# A2 **Deadline:** Tuesday, January 30, 2024 at 11:59 pm *This assignment may be completed individually or in pairs* ## Getting Started This assignment will involve using the Pomona VM `itbdcv-lnx04p.campus.pomona.edu`. Note that this VM is only accessible internally, so you will either need to be connected to the "Pomona" WiFi network or you will need to be connected to the Pomona VM. Once you are connected to the VM, log in with your Pomona credentials (off-campus students will need to visit Pomona ITS to claim your account). You can then copy the starter files to a protected directory on the VM with the command `tar xvf /data/cs181s/a2.tar'. Before you proceed any further, edit the port number at the top of the main function to something unique in the range 1800-1899. You can use the course slack channel to coordinate port numbers if you think you have a collision. 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 itbdcv-lnx04p.campus.pomona.edu <port_num> ``` 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 <text>``` replies back with “Server is echoing: “ followed by * ```setmsg <msg>``` sets a global variable in the server named special_message * ```getmsg```, gets the special message set with setmsg * ```authenticate <tried_password>``` authenticates the connection to with a password when ```<tried_password>``` 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 <URI> <http-version>``` 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 <more stuff here> 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 <address-in-hex> print $rsp / etc.. (for registers) x/20xb <address> / 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. ## 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. If you are working with a partner, the two of you should submit one assignment together. Submissions that fail to follow the submission guidelines will make me sad. Please follow the submission guidelines!