Skip to content

ret2csu 说明

复制本地路径 | 在线编辑

之所以叫 csu,本质是利用 __libc_csu_init 里现成的两段代码,构造出 ROP 链。

注意点:不需要知道 libc 地址

__libc_csu_init 不是在 libc 里面,而是编译进 你这个可执行文件 里的代码。也就是在 主程序 ELF 的 .text

所以 ret2csu 不需要知道 libc 基地址!

具体细节

用的 __libc_csu_init 这个函数,里面有两个片段可以用:

片段一:

pop rbx
pop rbp
pop r12
pop r13
pop r14
pop r15
ret

片段二:

mov rdx, r15
mov rsi, r14
mov edi, r13d
call [r12 + rbx*8]

可以看到第二片段里面有个 call 指令,里面用到的寄存器 r12rbx 我们可以在第一个片段中控制,所以两个片段会组合使用,达到 func(arg1, arg2, arg3) 的效果:

padding
csu_pop_addr      ← 片段 A
rbx = 0
rbp = 1
r12 = func_got
r13 = arg1
r14 = arg2
r15 = arg3
csu_call_addr     ← 片段 B
junk              ← 对齐 / 占位

常用方式

常见的做法有 write(1, puts@got, 8); 泄露 libc 地址,read(0, bss, 0x400); 达到写入内存目的。

通常有如下的组合:

ret2csu  write 泄露
ret2csu  read 写第二阶段
ret2libc  system

好处

  1. ELF 基本都有 __libc_csu_init
  2. 不依赖 libc
  3. 能一次性设置 3 个参数
  4. ASLR 开启也能用(只要程序不是 PIE)(回忆:ASLR 是 heap 之类的结构随机化,主程序不随机)

Comments