House Of Einherjar
House Of Einherjar
2.23
一般就是有off by one可以覆盖previnuse位,释放时会触发下面的合并
/* consolidate backward */ |
wiki上的例子
|
from pwn import * |
在s1通过堆块的空间复用,在s2的prevsize写上0x220,并用off by one把previnuse位置零,
s2堆情况
s1-prevsize找到假堆块进行unlink操作,假堆块s0还需要绕过unlink里下面的检查
if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \ |
下面的图if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \绕过
下面的图if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))\绕过
free(s2)后就可以把s0 0x7ac010放入unsortedbin了
how2heap例子
来自hollk师傅博客的简化版,上一个例子如果把伪造堆伪造到栈上会因为堆块太大,导致申请不出来,办法就是和topchunk合并后申请
|
grxer@Ubuntu16 /m/h/s/h/glibc_2.31> ./a.out |
绕过unlink大小的检测只需要*(fake_chunk+size)=size就行了,所以可以用下面的方法,用下面的方法因为时0x100大小是unsortedbin就不用把largebin才会用到的fd_nextsize和bk_nextsize覆写了
size_t fake_chunk[6]; |
2.31
how2heap例子
|
主要就是和tcache poisoning配合来使用了 利用堆块b来覆写c的prevsize和previnuse为到fakechunk的a块,freec后触发合并并绕过unlink b堆块还在使用但是被包裹放入unsortedbin里
intptr_t* d = malloc(0x158);会把b申请到d里,后面free掉b链入tcache
后面再利用d来覆写b的下一个空闲堆块为目标地址
、
就可以申请出来了
2016 Seccon tinypad
libc 2.23
/m/h/s/c/p/h/2016_seccon_tinypad> checksec tinypad |
自定的read_until有off by one的漏洞
unsigned __int64 __fastcall read_until(char *a1, unsigned __int64 len, int terminate) |
delete时存在只是置零了大小,存在uaf
free(*(void **)&tinypad[16 * idx + 248]); |
思路就是uaf泄露libc和heapbase,然后利用off by one来造成堆块重叠 就是2.31how2heap的例子,利用edit功能把管理区tinypad+256链入fastbin链表,申请到tinypad+256的管理区,由于edit功能时用来当前区域所存数据大小来作为重新读入的大小所以不能打free malloc的hook,只能利用environ全局变量,来泄露栈地址来覆盖main的返回地址为ogg
from pwn import * |
写完之后去看了一眼wp,发现edit里会先把输入读到tinypad,可以直接用tinypad的区域来构造fakechunk,利用house of ejinherjar来申请到tinypad,这里要注意的是要在tinypad至少+0x20的位置去伪造fakechunk,因为后面申请的堆最大才0x100,太菜了刚开始没看出来呜呜