DnsCat traffic post-dissector

Well previously I blogged about actually parsing DnsCat traffic, this blog post will be about converting it into an actual Wireshark post-dissector. As with dissecting DnsCat traffic using LUA I’ve also never written a wireshark post-dissector up until now. This is how it will finally look like:


Things you should know(read: things that could/should be improved) about this post-dissector:

  • It assumes you are tunneling plain ascii (dnscat –listen –exec ‘/bin/sh’)
  • It will only decode incoming&outgoing packets if you use the wireshark development version
  • I think it would be more efficient if this would have been a chained-dissector
  • It’s only been tested locally (dnscat –dns 127.0.0.1)
  • It will happily parse every DNS packet it encounters

Just as the previous post, this one will contain the source code (pastebin) and the references at the end of the post. Now let’s get going with building our post-dissector.

Continue reading “DnsCat traffic post-dissector”

Lua based DnsCat traffic parser

For the ones who don’t know DnsCat it’s an awsome tool and even has metasploit shellcodes. Here’s a little quote from the website:

dnscat is designed in the spirit of netcat, allowing two hosts over the Internet to talk to each other. The major difference between dnscat and netcat, however, is that dnscat routes all traffic through the local (or a chosen) DNS server. This has several major advantages:

  • Bypasses pretty much all network firewalls
  • Bypasses many local firewalls
  • Doesn’t pass through the typical gateway/proxy and therefore is stealthy

Which brings us to my original quest of finding a nice protocol to experiment with Wireshark dissector prototyping using LUA. I decided to try and make a dissector for DnsCat traffic. This post won’t contain the dissector, instead it contains a stand alone LUA DnsCat traffic parser(main dissector logic). Reason for this is that I’m not entirely happy with the dissector as it is right now,  I want to try and improve some things on it before publishing it. To be able to run this parser you’ll need to install an additional LUA library though, since LUA doesn’t have native support for bitwise operators. You can get the library from the following website:

http://bitop.luajit.org/

The installation is pretty straightforward, if you are on ubuntu you could also just do the following:

sudo apt-get install liblua5.1-bitop0

Ones you have that in place you should be able to run the parser without any problems. You can get the parser from pastebin or at the end of this post. If you are really impatient you can throw together a quick dissector yourself and just reuse this code for the dissecting part. I’ve also included some references at the end of this post that I’ve used while developing the parser.

Continue reading “Lua based DnsCat traffic parser”

raw sockets, pcap files & wireshark quirks?

So this is one of those things that you don’t stumble upon until you are playing with it. When writing sniffers you can use libpcap or it’s win32 version winpcap. Now that doesn’t really do the job in all circumstances, since sometimes you don’t want to install an additional library. Lucky for us you can also sniff traffic by using raw sockets(I’m assuming win32, for the rest of the blog entry). Usually when sniffing with raw sockets you are looking for something specific in the stream of data and can just output it to a good old plain text file…however sometimes you’d just like to capture everything that comes through the network interface. That’s when it becomes interesting to save packets in the PCAP format, so I decided to write my own quick & dirty implementation.

Now here comes the fun part, when sniffing the packets you get everything above the Physical Layer. This means that the Ethernet header is lost and you directly receive the IP header. I did not realize this until I had written the packets into a PCAP file. When trying to open the file with Wireshark, it tries to interpret the first bytes as a Ethernet header which fails horribly. So I came up with two possible solutions:

  • Understand / Configure wireshark to start directly with the IP interpretation
    • Tried this for a while, then decided to go for the second option just for fun.
  • Add a fake Ethernet header to each packet.
    • As previously stated this was the final choice

Well it worked like a charm, Wireshark correctly interpreted the packets and dissected the rest of the contents just as I was used to with normal captures. If anyone knows how to correct the problem WITHOUT writing the fake Ethernet header, by just configuring wireshark correctly DO share.

Here is one last and small warning/readme, before I post the src, for those wanting to play with raw sockets…I’ve noticed some weird behavior myself when testing the sniffer on Win7.

http://www.nirsoft.net/utils/smsniff.html#problems

Under Windows 2000/XP (or greater), SmartSniff also allows you to capture TCP/IP packets without installing any capture driver, by using ‘Raw Sockets’ method. However, this capture method has some limitations and problems:

  • Outgoing UDP and ICMP packets are not captured.
  • On Windows XP SP1 outgoing packets are not captured at all – Thanks to Microsoft’s bug that appeared in SP1 update…
    This bug was fixed on SP2 update, but under Vista, Microsoft returned back the outgoing packets bug of XP/SP1.
  • On Windows Vista with SP1, only UDP packets are captured. TCP packets are not captured at all.
  • On Windows 7, it seems that ‘Raw Sockets’ method works properly again, at least for now…

The header file:


/*

DiabloHorn, fun with pcap and raw sockets

*/

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <time.h>

typedef struct pcap_hdr_s {
 unsigned int magic_number;   /* magic number */
 unsigned short version_major;  /* major version number */
 unsigned short version_minor;  /* minor version number */
 int  thiszone;       /* GMT to local correction */
 unsigned int sigfigs;        /* accuracy of timestamps */
 unsigned int snaplen;        /* max length of captured packets, in octets */
 unsigned int network;        /* data link type */
} pcap_hdr;

typedef struct pcaprec_hdr_s {
 unsigned int ts_sec;         /* timestamp seconds */
 unsigned int ts_usec;        /* timestamp microseconds */
 unsigned int incl_len;       /* number of octets of packet saved in file */
 unsigned int orig_len;       /* actual length of packet */
} pcaprec_hdr;

HANDLE openpcap(LPCWSTR);
void writepcaprec(HANDLE,void *,int);
void closepcap(HANDLE);

The C file


/*

 DiabloHorn, fun with pcap and raw sockets

 */
#include "pcap.h"

/*
 Opens a pcap file for appending, file is set to +S +H.
 Writes the general header.
*/
HANDLE openpcap(LPCWSTR filename){
 HANDLE hFile = NULL;
 pcap_hdr *genHeader;
 DWORD numWritten;
 //create file with shared read access and set it's attrib to +S +H
 hFile = CreateFile(filename,FILE_APPEND_DATA,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM,NULL);
 if(hFile == INVALID_HANDLE_VALUE){
 return hFile;
 }else if(GetLastError() == ERROR_ALREADY_EXISTS){
 printf("Appending to existing pcap file\n");
 return hFile;
 }
 printf("Created empty pcap file\n");
 genHeader = (pcap_hdr *)malloc(sizeof(pcap_hdr));
 memset(genHeader,0,sizeof(pcap_hdr));
 genHeader->magic_number = 0xa1b2c3d4;
 genHeader->network = 1;//ethernet
 genHeader->sigfigs = 0;
 genHeader->snaplen = 65535;
 genHeader->thiszone = 0;
 genHeader->version_major = 2;
 genHeader->version_minor = 4;
 printf("Writing general pcap header\n");

 if(WriteFile(hFile,genHeader,sizeof(pcap_hdr),&numWritten,NULL) == 0){
 //need something more sexy here
 return INVALID_HANDLE_VALUE;
 }
 free(genHeader);
 return hFile;
}

/*
 Write the record of the pcap file
 Write record header (does not take into account the time stuff)
 Write fake eth header
 Write actual ip load data
 NOTE: supplied data must be max size 65521, due to specs in general header
 reason cause of fakeeth and me liking 65535 as a number :-)
*/
void writepcaprec(HANDLE hFile,void *data,int datalen){
 pcaprec_hdr *recHeader;
 DWORD numWritten;
 time_t seconds;
 //fake eth header
 byte fakeeth[14] = {0xde,0xde,0xde,0xde,0xde,0xad,0xbe,0xbe,0xbe,0xbe,0xbe,0xef,0x08,0x00};
 seconds = time(NULL);
 //write pcap record header stuff
 recHeader = (pcaprec_hdr *)malloc(sizeof(pcaprec_hdr));
 memset(recHeader,0,sizeof(pcaprec_hdr));
 recHeader->incl_len = datalen+sizeof(fakeeth);
 recHeader->orig_len = datalen+sizeof(fakeeth);
 recHeader->ts_sec = (unsigned int)seconds;
 recHeader->ts_usec = 0;
 printf("Writing record pcap header\n");
 WriteFile(hFile,recHeader,sizeof(pcaprec_hdr),&numWritten,NULL);
 free(recHeader);
 printf("Writing fake eth header\n");
 //write fake eth header, to fix wireshark
 WriteFile(hFile,fakeeth,sizeof(fakeeth),&numWritten,NULL);
 printf("Writing record data\n");
 //write pcap data stuff
 WriteFile(hFile,data,datalen,&numWritten,NULL);
}

/*
 Prolly hardly used but ohwell...
*/
void closepcap(HANDLE hFile){
 CloseHandle(hFile);
}