# A2
**Deadline:** Monday, September 7, 2020, 11:59 pm PT
*This assignment should be in pairs*
## Getting Started
This assignment will involve using the Pomona VM `pom-itb-cs2.campus.pomona.edu`. Begin by connecting to the VM (note: you will need to be connected to the
Pomona VPN at that time), copying the starter files to a protected directory on
the VM (they are available for download on the course website or can be copied from `/data/a2.tar` on the VM.
Before you proceed any further, edit the port number at the top of the main
function to something unique. Next, compile the server using the command
```
make fs_nsp_nnx
```
and run the server
```
./fs_nsp_nnx
```
If you visit the Pomona VM from a web browser (at the port you specified) you
should be able to see that it is, in fact, a functional (if minimal) web
server.
## Structure of the Server and ```telnet``` Tutorial
In addition to supporting simple GET requests over HTTP, the server also
supports a number of commandline commands. To talk to the server, you can use
the telnet program from your local machine.
```
telnet pom-itb-cs2.campus.pomona.edu
```
Once we’re connected, we can start sending the server commands:
```
hello
Hello!
```
When we type in “hello”, the server replies back with “Hello!.” The complete
list of commands is documented below.
* ```hello``` replies back with Hello!
* ```goodbye``` terminates the connection
* ```echo ``` replies back with “Server is echoing: “ followed by
* ```setmsg ``` sets a global variable in the server named special_message
* ```getmsg```, gets the special message set with setmsg
* ```authenticate ``` authenticates the connection to with a
password when `````` matches the password hard-coded into the
server. Once the connection has been authenticated, it will reveal the
“secret message”, which is also hard-coded.
* ```getsecret``` gets the secret, assuming the connection has been
authenticated
* ```get ``` GETs a resource using the HTTP protocol.
Here’s an example
```
authenticate fishyfishy
You are now authenticated
getsecret
my secret message is here
echo Hi, my name is Eleanor!
Server is echoing: Hi, my name is Eleanor!
getmsg
Here is a special message
```
I expect you to be able to pick up and read through server.c on your own, and
this is specifically part of the project. A large part of security (and
software-engineering at large) is figuring out other people’s code. So work
through it, and when you get stuck, play around with telnet. When you get
confused, insert logmsg or printf statements, or (better yet) walk through it
in GDB.
## Problem 1: Crashing the Server
**Note:** Make sure you use the ./fs_nsp_nnx executable. This is
the one that is vulnerable.
Consider the handle_connection function inside of of the server executable.
The local variables for handle_connection will be laid out on the stack in
order. This function is insecure because fails to perform a bounds-check
before copying data: the variable string in handle_connection is a buffer of
size 100, but inputs of up to 1024 can be read into the larger (global) buffer
variable.
Your first job is to figure out an input that could be sent to the server that
would cause the return instruction pointer to be overwritten, so that–upon
returning from handle_connection, the program would go to a nonsense location
and the program would crash. (FYI: the reason why it would crash is that
control flow would wander into an unmapped or unauthorized page, generating a
segmentation fault.)
During a successful attack, the server should look something like this:
```
Got a connection on port 5000, handling now.
ffffdc70
Received some data!
echo
Segmentation fault (core dumped)
```
Once you figure it out, the next step is to script your attack. I’ve included
a simple script, client.py. Script your attack in the function crash_server.
Note that you will want to update the connection command at the beginning to
use the host `'pom-itb-cs2.campus.pomona.edu'` and whatever port you chose.
You will then be able to remotely attack the server from your local machine!
#####Hints:
1. As a reminder, the following GDB commands might be helpful:
```
info frame
info locals
print
print $rsp / etc.. (for registers)
x/20xb / x/20xb $rsp / etc..
```
2. Remember the stack grows down!
3. The following Python socket functions might be useful:
```
send
recv
```
For example, you could write s.send("echo hello") to send “echo hello” to the
server. Note that the Python API takes care of some of the ceremony of doing
things like writing the length.
4. send expects a byte string as argument. To turn a Python string into an
array of bytes, use the following: "echo ".encode().
5. If you want to represent a single byte, use b’\x23’, which represents the
single byte containing the hex value 0x23. If you wanted to write the string containing the bytes 0x23, 0x24, 0x57, and 0x42, in that order, you could write b’\x2e\x24\x57\x42’
6. You will probably want to want combine the string “echo “ with a sequence
of bytes. To do this, you can simply add them together (since Python’s add is
overloaded): “echo “.encode() + b’\x41’ * 23 generates the ASCII for “echo “
(note the space), followed by the letter ‘A’ (ASCII-encoded) 23 times.
## Problem 2: Owning Control Flow
Craft an exploit that will force the program to print out “Hello, world!\n”.
To do this, follow the same technique you did in Problem 1, but instead of
making %rip become some nonsense value, make it the address of the function
hello_world. That way, when the program returns from handle_connection, it
will then go to hello_world instead. Write your exploit inside of the Python
function hello_world.
It is totally okay if the server crashes after printing “Hello, world!”
When you get done, the server should do something like this:
```
Hello, world!
Illegal instruction (core dumped)
```
#####Hints:
1. Use GDB to manually figure out how to redirect control flow at first. This
helps you get a feel for where things should be in memory, and you can draw
them out on a whiteboard or on paper as you use GDB. It also helps you debug
your exploit as you develop it.
2. The gdb commands info frame, print, x, and set might be helpful.
3. Remember, you’re on a little-endian machine. So if I give you the number
0xDEADBEEFDEADBEEF, it will be represented as 0xEFBEADDEFEBEADDE.
## Problem 3: Executing Shellcode
Now you can control control-flow. Great. But say you want to run your own
code. To do this, you need to inject some assembly code into your program, and
then have %rip jump to the shellcode.
Your task in this part is to inject the shellcode into the program (via the
buffer overflow) and then jump to it. I have included a sample shellcode in
the file shellcode.c (its assembly is given, too). Write your shellcode injection in the Python function inject_execute_shellcode
#####Hints:
1. You’re going to want to place your shellcode somewhere inside the buffer,
and then smash the stack so that control flows back to wherever you placed
that shellcode. Therefore, you need to figure out the position of the string
variable.
2. You can use the shellcode I've provided in `shellcode.c`, you don't need to
write your own!
3. It's fine if your attack only works when your server is running in GDB.
## Feedback
In the interest of
improving future iterations of this course, please answer the following
questions and upload them in a file called ```feedback.txt```:
1. How long did you spend on this assignment?
2. Any comments or feedback? Things you found interesting? Things you found
challenging? Things you found boring?
### What to Submit
Submit your attack script client.py containing the three attack functions. Be
sure to include the constants requested in the comment at the top! You should
also submit a feedback file feedback.txt containing the answers to the
feedback questions.
Submissions that fail to follow the submission guidelines will make me sad.
Please follow the submission guidelines!