Go to file
2020-12-12 12:20:21 +00:00
docs add cw overview (inc. mark scheme) 2020-12-02 16:48:26 +00:00
out Fix gitignore with vscode live share 2020-11-25 18:55:20 +00:00
ROPgadget add ropper 2020-12-02 12:13:45 +00:00
test-binaries readme stuff 2020-12-11 11:53:47 +00:00
.gitignore readme stuff 2020-12-11 11:53:47 +00:00
.vsjs.json Fix gitignore with vscode live share 2020-11-25 18:55:20 +00:00
autoRop.py readme stuff 2020-12-11 11:53:47 +00:00
exec_args.json pass exec args 2020-12-09 19:33:27 +00:00
init.sh readme stuff 2020-12-11 11:53:47 +00:00
README.md Update README.md 2020-12-12 12:20:21 +00:00
rop_exec_bash.json readme stuff 2020-12-11 11:53:47 +00:00
rop_exec_default.json Find offset by hand without core dump 2020-12-05 17:26:35 +00:00
rop_exec.json add executable with null byte in data address 2020-11-28 20:35:39 +00:00
ropinstall.sh ARBITRARY PROGRAM BUT BAD (NO ARGS) 2020-11-26 17:55:08 +00:00
Vagrantfile ARBITRARY PROGRAM BUT BAD (NO ARGS) 2020-11-26 17:55:08 +00:00

AutoROP

   _                ___       _.--.  ___        _____          ______ _____          ______ ______ 
\`.|\..----...-'`   `-._.-'_.-'`    / _ \      / ____|   /\   |____  / ____|   /\   |  ____|  ____|
/  ' `         ,       __.--'      | | | |_  _| |       /  \      / / |       /  \  | |__  | |__   
)/' _/     \   `-_,   /            | | | \ \/ / |      / /\ \    / /| |      / /\ \ |  __| |  __|
`-'" `"\_  ,_.-;_.-\_ ',           | |_| |>  <| |____ / ____ \  / / | |____ / ____ \| |    | |____ 
    _.-'_./   {_.'   ; /            \___//_/\_\\_____/_/    \_\/_/   \_____/_/    \_\_|    |______|
   {_.-``-'         {_/
                                                                
            __                                                                           __
           |            _______ _     _ _______  _____   ______  _____   _____             |
           |            |_____| |     |    |    |     | |_____/ |     | |_____]            |
           |            |     | |_____|    |    |_____| |    \_ |_____| |                  |
           |__                                                                           __|

Set up Vagrant

The project uses vagrant to ensure consistent results across machines.

vagrant up
vagrant ssh
cd cw

Our test environment uses:

  • Vagrant with the Libvirt provider
  • Ubuntu 18.04, provided by the image generic/ubuntu1804
  • Python 3.9.0
  • A modified version of ROPGadget

autoRop.py

Our ROP exploit is in the Python script autoRop.py. The script supports automatic gadget discovery and ROP chain exploitation of 32-bit x86 Linux ELF binaries. Broadly, the script works by:

  1. Generating a padding discovery ROP payload from the target program which executes /bin/echo "[ Successful ROP! ]".
  2. Modifying the padding length on the discovery payload until the exploit is successful.
  3. Generating the target ROP payload in exec_args.json with the discovered padding in step 2.
  4. Running the program with the target payload.

ROP exploit on test binaries

All binaries are located in the test-binaries directory. Each of them uses a different method for supplying the ROP exploit. Below are instructions for each type. You will see for each attack that it is successful when it prints [ Successful ROP! ].

vuln-32 - Binary using file input

This is the original vulnerable program from the lab. It takes its payload from a file, the path to which is passed as an argument.

python autoRop.py --input_method file --run test-binaries/vuln-32

null-data-addr - Binary using file input

This is the original vulnerable program from the lab, compiled with the flag -Tdata 0x080f0000. This sets the base .data address to 0x080f0000, resulting in null bytes in the data address. We can confirm the data address has been set accordingly with:

$ readelf --sections test-binaries/null-data-addr 2> /dev/null | grep -e "\.data "
>  [ 2] .data             PROGBITS        080f0000 091000 000f20 00  WA  0   0 32

AutoROP handles this and places its data at a

python autoRop.py --input_method file --run test-binaries/null-data-addr

elf-linux-x86/elf-linux-x86-NDH-chall - Binaries using a positional argument

These binaries are largely similar. They both take the payload as their first argument.

python autoRop.py --input_method arg --run test-binaries/elf-Linux-x86

python autoRop.py --input_method arg --run test-binaries/elf-Linux-x86-NDH-chall

crashmail - Binary using an optional argument

This was a real world vulnerable version of the program crashmail. When the SETTINGS option is used, the next argument has a buffer overflow vulnerability. Thus, we run this binary with the first argument as SETTINGS and the next argument as the payload. This can be configured by changing the exec_args file from the default exec_args.json

[ "$PAYLOAD$" ]

to test-binaries/crashmail_exec_args.json

[ "SETTINGS", "$PAYLOAD$" ]

like so:

python autoRop.py --input_method arg --exec_args test-binaries/crashmail_exec_args.json --run test-binaries/crashmail

This may take a little while due to the fairly large required offset.

Changing the execve target

AutoROP allows you to change what you execute with execve - enabling the execution of any executable with any arguments. It also allows to automatically run the ROP chain where the ROP payload will generate an interactive program, using the argument --interactive. Without --interactive, the program simply dumps the output of the ROP to stdout.

We demonstrate this by making AutoROP generate an interactive shell payload. To do this, we use the file rop_exec_bash.json:

["/bin/bash", "-p"]

This array represents the execve arguments - the signature will be execve("/bin/bash", ["/bin/bash", "-p"]).

The -p flag is used to enable privileged mode. In this mode, bash will acknowledge the effective user id, allowing exploitation of the setuid bit. This means that if the target binary has the setuid bit sit, we will be able to get a root shell. We demonstrate this by setting the setuid bit on vuln-32-setuid. This binary is stored in the home directory due to issues surrounding setting the owner and setuid bit on files in the Vagrant shared directory.

Now we run AutoROP on this binary, and get an interactive root shell:

python autoRop.py --input_method file --rop_exec_file rop_exec_bash.json --run --interactive ~/vuln-32-setuid

We can verify this by typing

whoami

and we get root!