Skip to content

Instantly share code, notes, and snippets.

@Kazurin-775
Created September 10, 2023 05:48
Show Gist options
  • Select an option

  • Save Kazurin-775/b2ee2d023602a0f498ebf69d431c76bc to your computer and use it in GitHub Desktop.

Select an option

Save Kazurin-775/b2ee2d023602a0f498ebf69d431c76bc to your computer and use it in GitHub Desktop.
Kernel pwn exploit submitter, useful in CTF competitions, optimized for larger binaries and better terminal interactions
'''
A kernel pwn exploit submitter, optimized for larger binaries and better terminal interactions.
Best suitable when you have a large binary to send (>= 500 KiB), and other (non-chunked and
non-flow-controlled) senders result in truncated and corrupted binaries.
This normally runs at ~150 KiB/s for base64 encoded data, sufficient for use in CTF competitions.
Requires python-pwntools to be installed.
'''
from pwn import *
import base64
import os
import time
def send(io, data):
with log.progress('Uploading exploit') as prog:
begin = time.time()
for i in range(0, len(data), 1024):
chunk = data[i:min(i + 1024, len(data))]
prog.status(f'{i / len(data) * 100:2.2f}%')
io.sendline(chunk)
io.recvuntil(b'> ')
kib_s = len(data) / 1024 / (time.time() - begin)
prog.success(f'Done ({kib_s:.2f} KiB/s in base64)')
with open('exp', 'rb') as f:
data = f.read()
info('Exploit has %.2f KiB (%.2f KiB encoded)', len(data) / 1024, len(data) / 3 * 4 / 1024)
begin = time.time()
io = remote('host', port)
# Solve PoW
io.recvuntil(b': ')
chall = io.recvline(keepends=False)
info('Challenge = %s (%.2f s)', chall, time.time() - begin)
begin = time.time()
solver = process(['./solve', chall.decode()])
with log.progress('Solving PoW') as prog:
ans = solver.recvline(keepends=False)
solver.close()
info('Answer = %s (%.2f s)', ans, time.time() - begin)
io.sendline(ans)
# Wait for target to boot up
begin = time.time()
with log.progress('Waiting for target OS to boot up') as prog:
io.recvuntil(b'/ $')
prog.success(f'Done ({time.time() - begin:.2f} s)')
# Send exploit
begin = time.time()
# Disable terminal echo to reduce unnecessary network flow
io.sendline(b'stty -echo')
# Store exploit to /tmp/e
io.sendline(b'base64 -d > /tmp/e <<.EOF.')
# Send exploit in chunks
send(io, base64.b64encode(data))
io.sendline(b'.EOF.')
io.sendline(b'chmod 777 /tmp/e; echo Done; stty echo')
info('Sent exploit (%.2f s)', time.time() - begin)
begin = time.time()
io.recvuntil(b'Done')
info('Target is ready (%.2f s)', time.time() - begin)
info('Taking back control of the terminal')
term.term_mode = False
#os.system('reset')
info('Have fun!')
#context.log_level = 'debug'
io.interactive(prompt='')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment