pwn的writeup
三道题全是堆TvT
slient_note
有关unsorted bin
的切割。
这里他只有两个指针,一个指向大堆,一个指向小堆,free
之后指针没有置空。利用切割的特性可以让两个堆有overlap
,而且题目十分友好没有开PIE
TvT,那么就可以来一发unlink
。
先free
大的,再分配小的,就可以让大堆溢出到小堆构造unlink
。
把free@got
的内容写成puts@plt
就可以泄露libc
基址。但是这一道题没有给libc
文件,我当时没做出来,所以还没有去钻研怎么搞。但是其他两道题给了,根据CTF的尿性,应该可以用另外两道题的TvT。
但是这里需要注意的一个地方是记得在top chunk
之前做分割!!!
exp
1 |
|
login
有关爆破的一个题。
这题也是UAF,free
之后指针没有置空。注册一个密码长度0x18
的用户,删除之后再注册一个密码长度0x18
的用户,就可以实现用户堆和密码堆之间互写。
用户堆的第一项是密码堆的地址,第二项是一个函数地址,在login
成功的时候会调用这个函数,并且用第一项作为参数传入。现在这个两个地址都是可写的。难点在怎么把地址弄出来。
这个地方需要密码堆的内容和你输入的内容相等才能够调用,一开始一直想不出来,但是感谢一位同学提供的思路。
比如这里我们要爆破free
的地址,但我们不必往第一项里写free@got
,可以先写free@got + 5
,由于地址的最低位是\x00\x00
,所以我们只需要输入\x7f
就可以调用第二项的函数。那么接下来输入+4+3……,就可以一位一位爆破出来。
exp
1 |
|
boring_heap
这个题一开始的漏洞我觉得就是没有,完美的一个程序(微笑.jpg),问了大佬才知道的。
计算机用补码存储数据,也就是说负数比正数多一个,那么我们在
abs
这个最大的负数的时候是没有对应的正数的,所以返回的仍旧是这个负数。
题目这个地方abs
之后会取余他的size
,只有0x30
得出来不是0,根据C语言取余的特性会返回一个绝对值小于0x30
的负数,也就是-0x20
。
先分配5个堆,#0
用来当做溢出点,#4
用来分隔 top chunk
。
edit
#1
可以将#1
的size改成0xd1
,这样在free
#1
的时候这个堆就会被放到unsorted bin
里面。既可以泄露地址也可以overlap。
overlap之后就可以进行fastbin attack
。
main_arena
中使用malloc_state
这个数据结构来管理整个分配区。struct malloc_state { /* Serialize access. */ mutex_t mutex; //4bytes /* Flags (formerly in max_fast). */ int flags; //4bytes #if THREAD_STATS /* Statistics for locking. Only used if THREAD_STATS is defined. */ long stat_lock_direct, stat_lock_loop, stat_lock_wait; #endif //每个指针占的字节都是8 /* Fastbins */ mfastbinptr fastbinsY[NFASTBINS]; //NFASTBINS等于10 /* Base of the topmost chunk -- not otherwise kept in a bin */ mchunkptr top; /* The remainder from the most recent split of a small request */ mchunkptr last_remainder; /* Normal bins packed as described above */ mchunkptr bins[NBINS * 2 - 2]; // NBINS 等于128 /* Bitmap of bins */ unsigned int binmap[BINMAPSIZE]; /* Linked list */ struct malloc_state *next; #ifdef PER_THREAD /* Linked list for free arenas. */ struct malloc_state *next_free; #endif /* Memory allocated from the system in this arena. */ INTERNAL_SIZE_T system_mem; INTERNAL_SIZE_T max_system_mem; };
__malloc_hook
:
这个是一个函数指针,在每次malloc调用的时候就会先检查这个指针是否为空,为空则跳过,不为空则执行他。在初始化地址分配的时候,里面存储的是malloc_hook_ini()
,在这个函数里面将__malloc_hook
置为NULL。
具体利用方式
bins里面都是双向链表。在最开始的时候,unsorted bin里面存放的是top chunk的地址。
但是一般如果要让堆分配到__malloc_hook
去的话,附近合适的size就是__malloc_hook - 0x23
处的 0x7f
,而这题规定死了他的size大小,所以不能让fastbins
直接分配到__malloc_hook
。
这个题很厉害的地方就在于,可以让fastbins
的某个指针内容直接为size大小,然后让堆分配到fastbins
上面去,然后覆盖malloc_state
里面的top
指针到__malloc_hook
附近。
主要的利用姿势见exp。
1 |
|
疑惑
这里在计算libc的基址的时候,中间为啥要加一个0xc0
我也不知道,动调的时候加了发现了。