Blogs involving different aspects of the I.T. world

Using ICMP to deliver shellcode

While researching different methods of exfiltration, I came across a technique that utilized DNS. While writing up the proof of concept code, I noticed something interesting with the ping function I had implemented. What had caught my eye was the fact that you can supply a buffer that can hold 65,500 bytes. With a size limit that large, we can easily smuggle shellcode into our ICMP request and then inject it into a process on the listener’s end.

Starting off with the shellcode delivery, only a C# console application within Visual Studio is needed. Here, we must import our dependencies. The only one being needed is System.Net.NetworkInformation.

Importing System.Net.NetworkInformation

Next we need to create a public static void function and then call that from within Main().

Creating the function sendShellcode() and calling it from main().

Next, we create a local variable and use that to initialize an instance of the ping class, while also assigning a value to our timeout var.

Our next step will require us to move to a Kali VM instance. Within here we’re going to generate shellcode to open up a message box. we’re going to select a payload For Windows 64 bit. (payload/windows/x64/messagebox). after selecting the payload we can customize the title and the message body. After the customization, we need to generate our payload. To do this, type: generate -f csharp. We can copy the output and move it back to our Windows machine.

Crafting our shellcode
Pasting the shellcode and formatting it to fit one line.

Our last step is to assign our TTL, tell our request not to fragment, and then send the request. Our code should now look as such.
Args:
pingOptions(TTL, dontFragmentBool)
pingSender.Send(IP/Hostname, timeoutInt, shellcodeBuf, options)

Now that we can deliver the payload, we need to create a listener. Let’s move to our victim VM.

On the victim VM, we open another C# console application and import these four dependencies:
System
System.Net
System.Net.Sockets
System.Runtime.InteropServices

Next, we need to create two functions. One that will return shellcode from the ICMP request, as well as one that will inject it into a local process.

Imports + Skeleton functions

We need to start by creating a socket that will listen for raw data from IPv4 addresses using the ICMP protocol. This is done within the getShellcode function.

icmpListener

Next, we bind our local address to the socket with a port value of 0.

icmpListener.Bind

Next, we need to set the IOControl for the socket. To do this, we supply a control code (first arg) of ReceiveAll as well as two identical byte arrays containing {1, 0, 0, 0} as the value.

IOControl

Our next three lines are straight forward. First, we assign a buffer, allocating 4096 bytes. Then we create a remote endpoint that will listen for transmissions from any IP address from no specific port. Finally, we  initialize our shellcode byte array with the byte size of 4068.

My reasoning behind the shellcode size of 4068, is because when we receive the ICMP buffer, the user inputted data starts at the 28 byte. Hence, 4096 – 28 gives us 4068.

Buffer + remoteEndPoint + Shellcode allocation

To finish off this function, we start the listener, then copy the received buffer from the request into our shellcode array. After copying the buffer to our array, we can return the value.

Receive the bytes, copy the buffer into the array, then return the value

Our last step is to the pass our shellcode to our injection function. This process is the same method used within this article, and is explained in greater detail there. However, the key point here is that we are utilizing notepad as our injection point, so all we need to grab that process ID. Checking within task manager, we get the process ID of 5588, so let’s add this to our code

notepadPID

Following the instructions in my last article, our code should look like this.

ICMPListener

All that is left to do, is to run both applications. First, we start the listener, then we launch the injector. Going in that order, let’s check out our Notepad process.

Success!

Final source code can be found here: https://github.com/RomanRII/shellcode-through-ICMP

1 Comment

  1. zach115th

    I wonder if you can set this up more like a reverse she’ll. Have the listener and secondary payload be on the attacking computer. Then deliver that payload with an echo reply?

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2021 RomanRIIs Blogs

Theme by Anders NorenUp ↑