Two binaries to practice Ghidra + gdb + etc

The binaries for this exercise are in: http://rarceresearch.fun/ccom4995/b92/

hyp3rs3rv3r

hyp3rs3rv3r is an exercise to practice static and dynamic RE techniques. It acts like a server program that receives commands via the network. But given the correct commands, the server is vulnerable to open a backdoor to the system.

In order to exploit the vulnerability in Ubuntu, you should use netcat-traditional. You can switch from netcat-openbsd to netcat-traditional using the steps described here.

Initial run

  1. Run ./hyp3rs3rv3r banner

  2. In another terminal window run sudo netstat -tulpn | grep LISTEN to find which address and port the hyp3rs3rv3r program is listening to.

  3. Connect using: nc address port

  4. Type anything into the terminal where nc is running.

Basic info and decoding a string argument

  1. Is this a 32 or 64 bit executable? How did you find out?

  2. Is it stripped? How did you find out?

  3. Run nm hyp3rs3rv3r to display a list of the symbols of hyp3rs3rv3r. Why does nm display nothing?

  4. Run nm -D hyp3rs3rv3r to display a list of the dynamic symbols of hyp3rs3rv3r. Some of the function names that you should get are: accept, accept, read, socket, and write. It looks as if this executable tries too establish a socket connection as a server. Ok, big deal, so it could allow communication with the program through a socket. The big red flag in the list of functions is system. Find out what that function does and what is the parameter it should receive.

  5. Try string hyp3rs3rv3r. Unfortunately, non of the deduced strings looks like something you could pass to system as a parameter (we are looking for strings that look like command line instructions in linux, e.g. ls -al)

  6. In Ghidra, locate the call to system. What did Ghidra call that function where system is called?

  7. Look at the decompilation for the function where system is called. Several words are given literal values, i.e. 0xada0e3ee, etc. Looking at the corresponding assembly you will notice that the values are given to consecutive address in the stack frame. Thus, the address of the first local variable can be used to traverse the bytes 0xee, 0xe3, 0xa0, 0xad, 0xec, 0xf6. (Looking at the decompilation) the address of the first local variable and a number are sent as parameters to a function (FUN_08048a4c). Decompile FUN_08048a4c and try to understand what is happening. (Hint: the first argument is treated as a char * and the second is the length of the string)

  8. Implement a python program that performs the action taken in FUN_08048a4c and print out the results. This will reveal the string that is really used as parameter to system . What is the string? What will system do when receiving that command?

In search of how invoke the backdoor

  1. Let's consider the function that calls system. Is this function called from anywhere else in the program? Explain how you found out.

  2. Since the function that calls system is not called from anywhere else we would need to somehow affect the program's execution to fool it into jumping to that function. We will do this by overflowing a buffer. Since hyp3rs3rv3r establishes a socket, we will run a client that connects to hyp3rs3rv3r and sends a string that overflows the buffers declared by hyperserver, hopefully redirecting the server to the function that executes the dangerous system call.

  3. The function read is called by hyperserver to receive data from a client. Using Ghidra find out where read is called. Then, in gdb, put breakpoints at these addresses to determine which of the reads is the one called when a string is sent from the client. What is the address of the call read that is actually executed when the client sends something to the server.

  4. Notice that read receives three parameters, one of which is the size (count) of the string copy from the filedescriptor into the buffer. If the value of count exceeds the size reserved for buf you would overloading buf.

    ssize_t read(int fd, void *buf, size_t count);
    
  5. Explain why the two calls to read in this program could not create an overflow.

  6. Whenever we copy a chunk of memory to another chunk we could be inadvertently creating an overflow. Another function that performs such a chore is memcpy. Find where it is called, and explain why in this case it could cause an overflow.

  7. The server says it understands two commands "LIST" and "GET". In order to call the function that calls the memcpy what command must be issued by the client? Explain.

  8. Craft a string to pass from the client to the server such that overflows the buffer in memcpy and returns to the function that contains the call to system.

    To pass a long string via the client you can do:

    echo -ne 'the loooooooooooooooong stringggggggg' ' | nc 127.0.0.1 4242
    

crypto_crackme

The crypto_crackme binary is an application that asks for a secret and uses it to decrypt a message. In order to solve this task, you have to retrieve the message.

Unfortunately, the virtual machine doesn't support the libssl1.0.0 version of SSL library. You will have to use either the base system or the Debian 32 virtual machine.

You can break password hashes (including SHA1) on CrackStation.