house of pig plus
[TOC] 参考博客 当题目中限制了system函数的调用,可以使用此方法进行orw,但是这个方法的前提还是有hook可打
特别之处
- IO_str_overflow中一个特别之处 mov rdx,QWORD PTR [rdi+0x28]这条汇编指令,此时的rdi恰好指向我们伪造的IO_FILE_plus的头部,使得可以进行rdx的设置,进而可以使用setcontent函数进行srop
0x7ffff7e6eb20 <__GI__IO_str_overflow>: repz nop edx
0x7ffff7e6eb24 <__GI__IO_str_overflow+4>: push r15
0x7ffff7e6eb26 <__GI__IO_str_overflow+6>: push r14
0x7ffff7e6eb28 <__GI__IO_str_overflow+8>: push r13
0x7ffff7e6eb2a <__GI__IO_str_overflow+10>: push r12
0x7ffff7e6eb2c <__GI__IO_str_overflow+12>: push rbp
0x7ffff7e6eb2d <__GI__IO_str_overflow+13>: mov ebp,esi
0x7ffff7e6eb2f <__GI__IO_str_overflow+15>: push rbx
0x7ffff7e6eb30 <__GI__IO_str_overflow+16>: sub rsp,0x28
0x7ffff7e6eb34 <__GI__IO_str_overflow+20>: mov eax,DWORD PTR [rdi]
0x7ffff7e6eb36 <__GI__IO_str_overflow+22>: test al,0x8
0x7ffff7e6eb38 <__GI__IO_str_overflow+24>: jne 0x7ffff7e6eca0 <__GI__IO_str_overflow+384>
0x7ffff7e6eb3e <__GI__IO_str_overflow+30>: mov edx,eax
0x7ffff7e6eb40 <__GI__IO_str_overflow+32>: mov rbx,rdi
0x7ffff7e6eb43 <__GI__IO_str_overflow+35>: and edx,0xc00
0x7ffff7e6eb49 <__GI__IO_str_overflow+41>: cmp edx,0x400
0x7ffff7e6eb4f <__GI__IO_str_overflow+47>: je 0x7ffff7e6ec80 <__GI__IO_str_overflow+352>
0x7ffff7e6eb55 <__GI__IO_str_overflow+53>: mov rdx,QWORD PTR [rdi+0x28] <----
0x7ffff7e6eb59 <__GI__IO_str_overflow+57>: mov r14,QWORD PTR [rbx+0x38]
0x7ffff7e6eb5d <__GI__IO_str_overflow+61>: mov r12,QWORD PTR [rbx+0x40]
0x7ffff7e6eb61 <__GI__IO_str_overflow+65>: xor ecx,ecx
0x7ffff7e6eb63 <__GI__IO_str_overflow+67>: mov rsi,rdx
0x7ffff7e6eb66 <__GI__IO_str_overflow+70>: sub r12,r14
0x7ffff7e6eb69 <__GI__IO_str_overflow+73>: cmp ebp,0xffffffff
0x7ffff7e6eb6c <__GI__IO_str_overflow+76>: sete cl
0x7ffff7e6eb6f <__GI__IO_str_overflow+79>: sub rsi,QWORD PTR [rbx+0x20]
0x7ffff7e6eb73 <__GI__IO_str_overflow+83>: add rcx,r12
0x7ffff7e6eb76 <__GI__IO_str_overflow+86>: cmp rcx,rsi
0x7ffff7e6eb79 <__GI__IO_str_overflow+89>: ja 0x7ffff7e6ec4a <__GI__IO_str_overflow+298>
0x7ffff7e6eb7f <__GI__IO_str_overflow+95>: test al,0x1
0x7ffff7e6eb81 <__GI__IO_str_overflow+97>: jne 0x7ffff7e6ecc0 <__GI__IO_str_overflow+416>
0x7ffff7e6eb87 <__GI__IO_str_overflow+103>: lea r15,[r12+r12*1+0x64]
具体做法
- 使用largebin attrack劫持stderr->_chain字段为一个堆地址ck0
- 使用largebin attrack劫持global_max_fast或者tls中管理tcache的部分为堆地址ck1,这是为了malloc从tcache中取得malloc_hook,以及随便取一个chunk触发malloc hook
- edit(ck1)使得0xa0 对应的tcache中为malloc_hook,0xb0对应的chunk为任意一个堆地址
- mov rdx,QWORD PTR [rdi+0x28],rdi=FAKE FILE头部(注意FAKE FILE前0x10无法管理,但是不影响)。edit(ck0)设置FAKE FILE+0x28的值为fake frame的底部;合理地设置fp->_IO_write_ptr,fp->_IO_write_base,fp->_IO_buf_base=一个堆地址(该堆地址的内容应该是setcontent+61),fp->_IO_buf_end;chain=ck2;vtable=IO_str_overflow;这样IO_str_overflow时malloc hook被设置为setcontent+61,rdx=fake frame底部,同时遍历下一个FILE ck2
- edit(ck2)使得其执行IO_str_overflow时可以malloc出一个0xb0的chunk
- edit(ck3)为一个orw
- 执行exit(0),第一个IO_str_overflow可以让malloc hook被设置为setcontent+61,rdx=fake frame底部,第二个IO_str_overflow调用了malloc函数执行srop,让rsp=ck3的mem,rip=ret,srop结束后执行orw