西湖论剑 ezhttp
花了一下午做这题,被没有符号表的libc折磨的死去活来,不知道为啥我电脑ubuntu18的libcTM升级到1.3的没法tcache double free了,赛后自己编译了一个带dbg符号的,再ld_preload就可以了。
这题是道套了层类似http收发形式的堆体,逆这个收发花费了大部分的时间,这个就没什么好说的了,只要写下后面的利用手段吧:
add函数:
1 | v2 = strlen(&src); |
看到它是用strlen获取content的长度,之后malloc再strncpy,strlen会被’\x00’截断,在后面构造时给我带来了不少的麻烦。
dele函数有uaf:
1
2
3free(heaplist[2 * idx]);
heaplist[2 * idx + 1] = 0LL; // UAF
quit((__int64)"HTTP/1.1 200 OK", (__int64)"Delete success!");
edit还是正常的,哦对结尾加个’\n’:
1
2
3
4
5
6
7
8for ( i = 0; src[i] != '\n'; ++i )
;
if ( v4 < 0 || v4 > 15 || !heaplist[2 * v4] || i > (__int64)heaplist[2 * v4 + 1] )
{
quit((__int64)"HTTP/1.1 404 Not Found", (__int64)"No!You can't");
exit(0);
}
memcpy(heaplist[2 * v4], src, i);
由于没有show,add函数给了我们堆地址因此自然想到double free打tcache的结构体,之后dele0x100的堆进入unsortedbin写入main_arena地址,double free同时改main_arena后2字节来打stdout,但由于add时的’\x00’限制,要改写地址为stdout上面的地址,并填充’a’但0xfbad18不能改,其他都填’a’,开始以为不行,但仍能成功泄露,有点nb,之后由于有seccomp所以改free_hook为setcontext+53,并在0x100的堆里写payload,之后dele。利用setcontext+53来构造寄存器(rdi=0,rsi=heap+0xa0,rdx=0x200),rsp改到heap+0xa8,之后返回时去执行read读入后续的shellcode到栈里面rsp位置然后ret到shellcode来orw。
1 | pwndbg> telescope 0x555556d1f320 |
exp:
1 | from pwn import * |
libc使用的时glibc all in one里面的,download时候也一起把dbg符号一起下载了,之后编译一下就能用了。