date | challenge | tags | |
---|---|---|---|
2024-08-26 11:12 |
nolibc |
|
堆块结构:
+---------+
| size(32)|
|---------|
| fd |
|---------|
| data ...|
|---------|
| unused |
|---------|
| unused |
+---------+
可以很轻松地用加载文件的办法从 /proc/self/maps
获得地址信息,同时 load 和 save to file 的功能都存在可能的溢出,但是问题在于总的堆大小不超过 0x10000,文件操作前会先申请 0x7fff 的堆块,管理结构体也占用了 0x4010,看起来这个溢出没法用。估计要从其它地方找漏洞。
在 free 里面看到了一个非常可疑的逻辑:
if ( work_ptr )
{
v0 = 0x10000 - (work_ptr - BSS_START);
if ( v0 > *(_DWORD *)work_ptr )
*(_DWORD *)work_ptr = v0 - 16;
}
进一步研究进入这里的输入,同时实际堆空间是比设计中的小 0x10 的,如果把堆空间占满再删除前面的堆块就能进入上述释放后的整理分支:
最后发现根本没必要泄露和堆块伪造,直接写填满堆块,越界写系统调用号,最后释放得到超过 0x8000 的空间后调用 open 就可以实现 getshell: