Monday, June 1, 2009

Pcap2Syslog for .NET or Stuck transferring PCAP over UDP

I was recently in a situation where I wanted to transfer some fairly large .pcap file (1GB) from the internal network as part of the engagement. I did have direct HTTP connectivity to the outside (proxied and monitored for illegal sites) so I tried HTTP uploads but for some reason my transfers were getting dropped after about 5 megs into the transfer. I had no control over the issue and frankly I did not want to go even deeper than I already was. I think I was in the "3rd" tier with all nice policies applied to users like me so we are not able to waste company's time surfing the internet :) Anyway, all I had was DNS outbound for resolution, crippled HTTP and a Syslog. Don;t ask me why Syslog was enabled to the internet. Probably for monitoring or data collection purposes for manged service provider or something like that.

I started thinking of chopping my pcap into smaller chunks and doing the upload. I knew exactly what I would do on *nix and had scripts made for similar purpose but I happened to be on Windows and did not readily know what tools I would use.

So DNS or Syslog?

I did not yet research tools to allow me to chop up some binary data (such as PCAP), package them in smaller chunks ( Base 64 or not ) and shove them over DNS tunnel. I am sure they do exist and most likely many smart folks out there can point me to the ones they prefer. To date, I was ok bypassing content filtering with XML/RPC streams over HTTP(S). Not this time though.

Syslog? Well, it is foreign to Windows to begin with... What are the chances of getting the right tools fast enough to parse PCAP and transform them into syslog messages. I gather there would be enough dependencies to deter me ( or detect my activities) from doing so. Yeah, Cygwin comes to mind..

OK, start thinking outside the box. I have VS2008 so I have access to .Net libraries. But what can parse PCAP and which library can generate syslog messages? Well Syslog is a simple protocol and message generation can be accomplished with plain Sockets, something like this.
Indeed, all you need is


using System.Net;
using System.Net.Sockets;

and in a nutshell:

1. Instantiate UDP transport

udp = new UdpClient(ipAddress, 514);

2. Build Syslog String according to the RFC:

string[] strParams = { priority.ToString()+": ", time.ToString("MMM dd HH:mm:ss "),
machine,
body };

3. Send the chunk out.

rawMsg = ascii.GetBytes(string.Concat(strParams));
udp.Send(rawMsg, rawMsg.Length);
udp.Close();


Answer to the first question came in the form of Sharppcap . It;s a standalone assembly which lives in

Tamir.IPLib.SharpPcap.dll.



using System;
using System.Text;
using System.IO;
using Tamir.IPLib;
using Tamir.IPLib.Packets;


Since It can read pcaps offline I can do the following:


//Get an offline file pcap device
device = SharpPcap.GetPcapOfflineDevice(capFile);
//Open the device for capturing
device.PcapOpen();


Then, of course, you can iterate through packets like so:


while ((packet = device.PcapGetNextPacket()) != null)
{

DateTime ptime = packet.PcapHeader.Date;
int plen = packet.PcapHeader.PacketLength;

// Prints the time and length of each received packet to debug
Console.Write("{0}/{1}/{2} - {3}:{4}:{5}",
ptime.Day, ptime.Month, ptime.Year, ptime.Hour, ptime.Minute, ptime.Second);
StringBuilder sbuilder = new StringBuilder();

// Append to Message builder
sbuilder.Append()

// Either Call Syslog routines from above here,
// or call Syslog classes from here.
}




If you want to send based on filters, only what you want out of the PCAP (say, communication map to and from the host over UDP), then in a while loop you can introduce more laborate processing.


if (packet is UDPPacket) {
DateTime time = packet.Timeval.Date;
int ulen = packet.PcapHeader.PacketLength;
UDPPacket udp = (UDPPacket)packet;
string srcIp = udp.SourceAddress;
string dstIp = udp.DestinationAddress;
int srcPort = udp.SourcePort;
int dstPort = udp.DestinationPort;
Console.WriteLine(" UDP {0}:{1} -> {2}:{3}", srcIp, srcPort, dstIp, dstPort);
sbuilder.Append(String.Format(" UDP {0}:{1} -> {2}:{3}",
srcIp, srcPort, dstIp, dstPort));


// Append to Message builder here if you want
sbuilder.Append()

// Either Call Syslog routines from above here,
// or call Syslog classes from here.

} }

I turned out better than I expected. I filtered what I needed for further analysis, and my partially "interesting" data was sent in short messages over Syslog outbound.

Next, I should really look at DNS covert channels. If anyone has suggestions on tools, please let me know.



0 comments: