# A1
**Deadline:** Wednesday, September 19, 2018, 11:55 pm
*This assignment may be completed individually or in pairs*
## Structure of the Server and ```telnet``` Tutorial
This assignment will have you launch a series of attacks against a small
server, which can serve–among other things–HTML and image files. The starter
files for this assignment are available here. The server
is implemented in the file server.c.
Note: If you are having trouble configuring your system, you might want
to use this VM to complete this
assignment. You can run this disk image with
VirtualBox (also available on the lab
machines).
Settings: 64-bit Ubuntu, 4GB+ memory. Username: 181S Student
Password: 181S-Security.
This server is woefully incomplete: it only implements a very tiny part of the
HTTP–the exchange-format used between web-browsers and servers. And yet this
server still implements enough of HTTP to be able to display static content.
Note that the word “server” is used all over the place in tech. For this
assignment, a “server” means an application that can exchange data with a user
on the other end of a communication channel (frequently called a “port”).
Begin by building the server:
```
make fs
```
This command builds the version of the server with all of the fancy modern
protection mechanisms enabled, so it won’t be susceptible to (as many of) the
attacks we’ll launch in this assignment.
To run the server, type the following:
```
./fs
```
The server should now be running on port 5000. This means that it’s listening
for connections. To talk to the server, you can use the telnet program:
```
telnet localhost 5000
```
The first command-line argument is the server to connect to. This could be a
remote host, like www.cs.pomona.edu, but in this case it’s going to be a
special host named localhost, which is an alias for the IP address 127.0.0.1.
This is like talking to a remote machine, across the internet, except you’re
talking to a server running your local machine.
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.
This server also supports a form of HTTP, which is a standard format
(protocol) used to exchange data between your web browser and the server
itself. Think of the web browser as doing this same stuff that you’re typing
into telnet in a specific way, except that it’s doing it using a program. To
see this, open a web browser (inside of the VM, using the user interface) and
point the address address bar at localhost:5000. Like navigating to
www.cs.pomona.edu, the server sends the necessary commands to our server
application to retrieve the page. You should be able to see the server
application generating some logs as it does this, so you can see which files
get requested.
Here’s the complete list of commands:
* ```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 secret
You are now authenticated
getsecret
hello my message is here
echo Hi, my name is Charles!
Server is echoing: Hi, my name is Charles!
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 the debugger.
## Problem 1: Crashing the Server
**Note:** From now on, make sure you use the ./fs_nsp_nnx executable. This is
the one that is vulnerable. ./fs has full protection mechanisms turned on.
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.
#####Hints:
1. If you need a review of C, assembly, or gdb, try doing the optional review exercises before starting the assignments.
2. The following GDB commands might be helpful:
```
info frame
info locals
print
print $rsp / etc.. (for registers)
x/20xb / x/20xb $rsp / etc..
```
3. Remember the stack grows down!
4. 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.
5. send expects a byte string as argument. To turn a Python string into an
array of bytes, use the following: "echo ".encode().
6. 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.
## Problem 4: Leaking the Secret
The server implements some code to check that the user types in a proper
authenticate command before allowing the secret message to be retrieved. E.g.,
if I simply telnet into the server and then type in getsecret I get the
message: “You are not authenticated right now, first use the authenticate
command.”
Your job in this part is to figure out how to get the server to give me the
secret message without typing in the password. Write your solution in the
function leak_secret.
#####Hints:
1. This part requires injecting some of your own shellcode that writes a
nonzero value to the address of is_authenticated.
## Feedback
This is the first time this course has been offered. 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?
### Collaboration Policy
You may work individually or in pairs. If you choose to work in pairs, you
should submit only one solution. You may discuss ideas with other students at
a high-level, but under no circumstances should you be looking at code written
by anyone other than you or your partner. Any ideas that originated
with another person should be cited.
### What to Submit
Submit your attack script client.py containing the four 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 may be subject to a 10% deduction.