Wednesday, April 27, 2016

The PCAP Contest - Covert channel detection

NOTE: this was originally a Linkedin post, but at the bottom of this blog post are one line solutions that came in after the original post.

In April 2016 SANS released a PCAP riddle. The winner was:


Patrick Mooney, US Department of State, holder of various GIAC certifications, and exploring new potential employment options for Fall 2016. Read on to find out why you really want to hire this guy.

I am the chair of SANS Boston 2016 and asked my friend, Judy Novak, to help create a PCAP with a riddle. We talked about the options and settled for a covert channel.

When the first email went out 4/20/16  to 101k addresses in our cybersecurity focused database, we mentioned the riddle and I also posted about it on Linkedin, Facebook, Twitter, No solutions. 4/25/16, I mentioned it to the GIAC Advisory Board and in less than an hour, I received this message.

Bad checksums:

tcpdump -r Boston2016.pcap -Annvvts 0 | grep bad | awk ' { print $7 } ' | cut -c3-10 | xxd -r -p
Save the date, SANS Boston starts August 1, 2016. Another notable event occurred August 1, but in 1981. The rock music video channel MTV made its debut. The first person to decode this and show up and send the message to stephen@sans.edu will receive a prize. Best of luck to you, Judy Novak.

Bad checksums is where we embedded the secret message. Some programs and security monitoring tool do not check checksums so you can embed a message.
The command line, which is quite an elegant solution, spit out the message. We asked Patrick what his analysis process was and this is what he said.

Sure thing. I first looked at the packet capture in Wireshark to get a quick sense of what Wireshark thought the protocols in use were. Seeing that they were a series of DNS questions and answers the first thing that came to mind was some sort of covert channel or tunneling variant. The messages themselves on the surface all look valid and fairly simple so if there was a covert channel in there it would be in transaction IDs, sequence numbers or counters, or some other part of the protocol that can be manipulated by the sender.

My initial look at the packets was in Windows so I moved the file over to a linux VM and took a more raw look at the PCAP in tcpdump. The first thing that jumped out at me was the bad UDP checksums on the sent DNS requests, something that certainly qualifies as a field that can be manipulated but still results in otherwise valid looking packets. The inserted checksums were also suspiciously within the ASCII printable character range ... not as random looking as one would expect a real checksum to be. So I made a quick and dirty commandline to pull out the bad checksums from the tcpdump display I had started with, isolate the spoofed checksums, and then use xxd to convert the checksums to ASCII.

Jon Mark Allen also solved the problem and this is his methodology:

Thanks for pointing out the puzzle!
I'm afraid my process was fairly boring, and not the most elegant. But
it didn't take very long to complete. :-)

I opened the pcap in Wireshark and saw that the only packets were DNS
queries and responses. So I expanded the raw data column at the bottom
and started scrolling, looking for changes in the hex or ASCII sections.
The word patterns began to stick out to me, so I created a display
filter and used tshark to output only the UDP checksum fields on query
packets.

The raw output was 147 lines like this:
0x00007420
I'm sure scapy would have been more elegant, but my bash pipe experience
is still faster for me - especially on smaller tasks like this. So I
piped the output to cut and tr to create a raw string of hex, and then
used the python one-liner to convert to text.
tshark -r Boston2016.pcap -T text -Tfields -e udp.checksum -2 -R \
"dns.flags == 0x0100" | cut -c 7- | tr -d "\n" | \
python -c "import sys; import binascii;
print binascii.unhexlify(sys.stdin.read());"

That command yielded the following text:
Save the date, SANS Boston starts August 1, 2016. Another notable event
occurred August 1, but in 1981. The rock music video channel MTV made
its debut. The first person to decode this and show up and send the
message to stephen@sans.edu will receive a prize. Best of luck to you,
Judy Novak.

Ugly as all-get-out, but effective. :-)


And I was only going to highlight two analysts, but I am a softy, here is the 3rd:


Analyst: Jordan Wigley
File: Boston2016.pcap
Notes:
Noted that the DNS requests appeared to be valid, and resolved IP stayed consistent for a given domain.

Compared packets for a given domain, to look for any subtle differences.
Discovered that the UDP Checksum field on each DNS request seemed to be changing to unusual values on each request.

Filtered on just the requests in Wireshark using udp.dstport == 53
Noticed that if you looked at the DNS requests in order of occurrence, that the ASCII value of the UDP Checksum bytes appeared to be part of some data exfiltration or other message.

Going through each packet to pull out those bytes revealed the following message:
Save the date, SANS Boston 2016 starts August 1, 2016. Another notable event occurred August 1, but in 1981. The rock music video channel MTV made its debut. The first person to decode this and show up and send the message to stephen@sans.edu will receive a prize. Best of luck to you, Judy Novak..



UPDATE 4/27/16 Now people are sending in one line solutions - amazing, also a cautionary word to the tshark folks, stabilize your parsing.

Luis Rocha
The solution is already known but a one liner is also cool. Great work Judy!

$tshark -nnr Boston2016.pcap -Y "dns.flags == 0x0100"  -T fields -e
udp.checksum | sed 's/^..//'  | tr -d '\n' | xxd -r -p

Mark Stingley, (referring to the solution above, using TShark 1.8.2.)
Typo in the example. Should be:

tshark -nnr Boston2016.pcap -R "dns.flags == 0x0100"  -T fields -e
udp.checksum | sed 's/^..//'  | tr -d '\n' | xxd -r -p

Luis Rocha 
I think it depends on the tshark version.
On my version of tshark using -R as display filter I get the following 
warning:
"-R without -2 is deprecated. For single-pass filtering use -Y"

$tshark -v
TShark 1.10.2 (SVN Rev 51934 from /trunk-1.10)

Evan H. Dygert
My version of tshark (1.12.4) is slightly different as it outputs the 
checksum in decimal, not hex. I ended up doing the following:

tshark -n -r Boston2016.pcap -Y 'dns.flags.response == 0' -T fields -e 
udp.checksum | while read -r; do printf '%x' $REPLY; done | xxd -r -p

Matt Bennet posted an approach to look at hex frequency:
tshark -n -r Boston2016.pcap -Y 'dns.flags.response == 0' -T fields -e udp.checksum | sed 's/0x0000//' | fold -w2 | sort | uniq -c | sort -nr

Austin Taylor
#python3
from scapy.all import *
pcap = rdpcap('/Users/austin.taylor/Downloads/Boston2016.pcap')
b''.join([binascii.unhexlify(hex(pcap[i]['UDP'].chksum)[2:].encode('utf-8')) for i in range(0, len(pcap)) if pcap[i]['IP'].dst=='192.168.1.1'])


Still more solutions :)

Julio Auto
>>> a=rdpcap('Boston2016.pcap')
>>> blab=''
>>> for c in a[::2]:
...   blab=blab+(hex(c[UDP].chksum)[2:])
... 
>>> blab
'536176652074686520646174652c2053414e5320426f73746f6e207374617274732041756775737420312c20323031362e20416e6f74686572206e6f7461626c65206576656e74206f636375727265642041756775737420312c2062757420696e20313938312e202054686520726f636b206d7573696320766964656f206368616e6e656c204d5456206d616465206974732064656275742e2054686520666972737420706572736f6e20746f206465636f6465207468697320616e642073686f7720757020616e642073656e6420746865206d65737361676520746f207374657068656e4073616e732e6564752077696c6c20726563656976652061207072697a652e2042657374206f66206c75636b20746f20796f752c204a756479204e6f76616b2e'
>>> blab.decode('hex')
'Save the date, SANS Boston starts August 1, 2016. Another notable event occurred August 1, but in 1981.  The rock music video channel MTV made its debut. The first person to decode this and show up and send the message to stephen@sans.edu will receive a prize. Best of luck to you, Judy Novak.'

Sean Johnstone
=====
SANS BOSTON CHALLENGE LAB NOTES
=====

Many DNS requests. Rapid. 294 requests/replies in 0.34s
SRC_IP: 192.168.11.23
DST_IP: 192.168.1.1
DNS responses appear correct -- Does not appear to be an attempt to return falsified results.
Does not appear that the purpose of challenge is to spot malicious techniques. Hidden data likely.
Transaction IDs do not appear to translate to anything HEX > ASCII -- 25979d11f4eb into %— ôë
Checksum validation is disabled ****
Data is hidden in sending checksum: HEX > ASCII 536176652074 -- Save t
DNS responses do not hold any message. Output akin to Transaction IDs.

MESSAGE IS HEX > ASCII WITHIN SENDING CHECKSUM

Need to automate, to hell with approx. 150 requests.

Unsure how to exract specific fields within a packet using TCPDUMP, solution will be death-by-grep translated.

sean@sean-VirtualBox:~$ sudo tcpdump -r Boston20161.pcap src 192.168.11.23
01:33:32.291613 IP 192.168.11.23.22830 > 192.168.1.1.domain: 9623+ A? tools.ietf.org. (32)
- Need expanded output

sean@sean-VirtualBox:~$ sudo tcpdump -c 5 -vv -XX -r Boston20161.pcap src 192.168.11.23
01:33:32.291613 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 60)
    192.168.11.23.22830 > 192.168.1.1.domain: [bad udp cksum 0x5361 -> 0x6a8d!] 9623+ A? tools.ietf.org. (32)
0x0000:  4ce6 7640 db2d b4b5 2fd8 dc89 0800 4500  L.v@.-../.....E.
0x0010:  003c 0001 0000 4011 ed47 c0a8 0b17 c0a8  .<....@..G......
0x0020:  0101 592e 0035 0028 5361 2597 0100 0001  ..Y..5.(Sa%.....
0x0030:  0000 0000 0000 0574 6f6f 6c73 0469 6574  .......tools.iet
0x0040:  6603 6f72 6700 0001 0001                 f.org.....
- Better, can grep on 'cksum 0x'

sean@sean-VirtualBox:~$ sudo tcpdump -c 5 -vv -XX -r Boston20161.pcap src 192.168.11.23 | grep -o -E 'cksum 0x[a-f0-9]{4}'
cksum 0x5361
- Need to trim off start of output

sean@sean-VirtualBox:~$ sudo tcpdump -vv -XX -r Boston20161.pcap src 192.168.11.23 | grep -o -E 'cksum 0x[a-f0-9]{4}' | grep -o -E '[a-f0-9]{4}$'
- BINGO, now to translate.


sudo tcpdump -vv -XX -r Boston20161.pcap src 192.168.11.23 | grep -o -E 'cksum 0x[a-f0-9]{4}' | grep -o -E '[a-f0-9]{4}$'| xxd -r -p

Save the date, SANS Boston starts August 1, 2016. Another notable event occurred August 1, but in 1981.  The rock music video channel MTV made its debut. The first person to decode this and show up and send the message to stephen@sans.edu will receive a prize. Best of luck to you, Judy Novak.


Monday, April 25, 2016

David Fletcher Boston 2016 PCAP Lab Notebook

NOTE: I was only going to post the analysis of the first two analysts to solve the PCAP puzzle, but this is such a great example of a lab notebook I felt I should.

The pcap file titled “Boston2016.pcap” was downloaded from the SANS website at URL https://www.sans.org/event-downloads/43267/Boston2016.pcap.

This pcap file was opened with Wireshark version 2.0.2. Upon opening the pcap file, the analyst navigated to Statistics > Protocol Hierarchy to investigate the composition of the traffic recorded in the pcap file. The Protocol Hierarchy window identified that the whole of the traffic was Domain Name System (DNS) traffic.


Investigating further, the analyst navigated to the Statistics > Conversations window which revealed that the packet capture contained 147 DNS queries and responses originating from host 192.168.11.23 destined for 192.168.1.1. These queries were for various addresses.






Investigating further, the analyst navigated to the Statistics > Conversations window which revealed that the packet capture contained 147 DNS queries and responses originating from host 192.168.11.23 destined for 192.168.1.1. These queries were for various addresses.

The analyst began inspecting the queries for anomalies. Several comparisons were made.  First, the largest and smallest packet sizes were inspected.  Then the request and response messages in each query.  Each appeared to be a valid query and response.
Next the analyst began inspecting just the DNS queries without the responses. Moving through the results, the analyst noticed that the checksum for the UDP packets seemed to contain a message.

The analyst then split the packet capture into two files. One file containing just the queries and one file containing just the responses.
The following display filter was used to display only the queries in the pcap file.


A new pcap file containing just the DNS queries was saved by using the File > Export Specified Packets menu item only the displayed packets selected.

To capture only the responses, the following display filter was used:

Using the same technique used with the queries, the analyst saved just the responses into a separate pcap file using the File > Export Specified Packets menu item.

In order to extract the bytes of interest, the analyst moved the resulting pcap files over to a Kali Linux computer to use the scapy tool to extract the values.
On the Kali Linux computer, the Boston2016_queries.pcap file was read into Scapy using the rdpcap function.  Then a for loop was used in conjunction with the format method to extract the hexadecimal bytes from the UDP checksum field of each packet.

root@Barrett:~# scapy
INFO: Can't import python gnuplot wrapper . Won't be able to plot.
WARNING: No route found for IPv6 destination :: (no default route?)
Welcome to Scapy (2.2.0)
>>> packets=rdpcap("/home/bugger/Desktop/Boston2016_queries.pcap")
>>> packets
<Boston2016_queries.pcap: TCP:0 UDP:147 ICMP:0 Other:0>
>>> packets[0]
<Ether  dst=4c:e6:76:40:db:2d src=b4:b5:2f:d8:dc:89 type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=60 id=1 flags= frag=0L ttl=64 proto=udp chksum=0xed47 src=192.168.11.23 dst=192.168.1.1 options=[] |<UDP  sport=22830 dport=domain len=40 chksum=0x5361 |<DNS  id=9623 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR  qname='tools.ietf.org.' qtype=A qclass=IN |> an=None ns=None ar=None |>>>>
>>> for packet in packets:
...    format(packet.payload[UDP].chksum,'04x')
...
'5361'
'7665'
'2074'
'6865'
'2064'
'6174'
'652c'
'2053'
'414e'
'5320'
'426f'
'7374'
'6f6e'
'2073'
'7461'
'7274'
<snipped output>

The resulting hexadecimal values were then copied into the vim editor.  The single quotes were removed and the values were collapsed into a single line by replacing newlines with a null value. The result was the hexadecimal string seen below:

536176652074686520646174652c2053414e5320426f73746f6e207374617274732041756775737420312c20323031362e20416e6f74686572206e6f7461626c65206576656e74206f636375727265642041756775737420312c2062757420696e20313938312e202054686520726f636b206d7573696320766964656f206368616e6e656c204d5456206d616465206974732064656275742e2054686520666972737420706572736f6e20746f206465636f6465207468697320616e642073686f7720757020616e642073656e6420746865206d65737361676520746f207374657068656e4073616e732e6564752077696c6c20726563656976652061207072697a652e2042657374206f66206c75636b20746f20796f752c204a756479204e6f76616b002e

This value was then supplied to an online hex to ASCII conversion site (http://www.rapidtables.com/convert/number/hex-to-ascii.htm)  to produce the following message:



The same process was applied to the checksums of the query responses, however, no discernible text was produced.  The result can be seen below.




The danger of reading email before drinking coffee

It was a great Monday morning. We cuddled our Rottweiler puppy. Kathy poured me a cup of coffee, I went over to the office to read my email. There was a well written note from someone that wanted to buy SANS, (for five to ten million - good luck with that). And yours truly, a person well known for beyond average paranoia, actually responded. I have had two cups of coffee now and deleted two emails, one to Press@SANS, the other to SCORE@SANS from Russia offering to buy SANS. Not sure what the scam is exactly, but sure it is a scam.

Here is the latest, notice the wording problem:

Hello

In my search for a business partner i got your contact in google search. My client is willing to invest $10 Million to $50 million but my client said he need a trusted partner who he can have a meeting at the point of releasing his funds. 

I told my client that you have a good profile with your company which i got details about you on my search on google lookup. Can we trust you. 

Can we make a plan for a long term business relationship.

Please reply. 

For and on Behalf of the Investor 395,
Shosse Kosmonavtov Perm, Russia
Tel: +44 703197576

Here are the headers:
To: score@sans.org 
Reply-To: lee@suhrr.com 
Received: from mail1b.den.sans.org (LHLO mail1b.den.sans.org) (10.2.2.42) by mail1b.den.sans.org with LMTP; Mon, 25 Apr 2016 20:39:13 +0100 (BST)
Received: from mail1b.den.sans.org (localhost [127.0.0.1]) by mail1b.den.sans.org (Postfix) with ESMTPS id 1DD468EE08F0 for <snorthcutt@sans.edu>; Mon, 25 Apr 2016 20:39:13 +0100 (BST)
Received: from localhost (localhost [127.0.0.1]) by mail1b.den.sans.org (Postfix) with ESMTP id 0F9F78EE08E9 for <snorthcutt@sans.edu>; Mon, 25 Apr 2016 20:39:13 +0100 (BST)
Received: from mail1b.den.sans.org ([127.0.0.1]) by localhost (mail1b.den.sans.org [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id wGdUDkluscQ3 for <snorthcutt@sans.edu>; Mon, 25 Apr 2016 20:39:12 +0100 (BST)
Received: from savfw21a.sans.org (savfw21a.den.sans.org [10.2.2.25]) by mail1b.den.sans.org (Postfix) with ESMTP id E3C718EE04D1 for <snorthcutt@zimbra.sans.org>; Mon, 25 Apr 2016 20:39:12 +0100 (BST)
Received: from smtp21a.den.sans.org (smtp21a.den.sans.org [10.2.2.12]) by savfw21a.sans.org with ESMTP id 4A5llAcy88XXWhLd for <snorthcutt@zimbra.sans.org>; Mon, 25 Apr 2016 19:39:12 +0000 (GMT)
Received: from suhrr.com (unknown [50.244.188.212]) by smtp21a.den.sans.org (Postfix) with ESMTP id 31198408A5 for <score@sans.org>; Mon, 25 Apr 2016 19:39:12 +0000 (UTC)
X-Asg-Debug-Id: 1461613152-04861a11f6fad20001-6JivnH
X-Barracuda-Bbl-Ip: 50.244.188.212
X-Barracuda-Rbl-Ip: 50.244.188.212
X-Quarantine-Id: <wGdUDkluscQ3>
X-Barracuda-Apparent-Source-Ip: 50.244.188.212
Return-Path: melvin@suhrr.com
Mime-Version: 1.0
X-Virus-Scanned: amavisd-new at mail1b.den.sans.org
X-Virus-Scanned: by bsmtpd at sans.org
X-Barracuda-Spam-Status: No, SCORE=0.60 using global scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=4.0 KILL_LEVEL=1000.0 tests=ADVANCE_FEE_1, BSF_SC0_MISMATCH_TO, BSF_SC5_MJ1963, HTML_MESSAGE, MIME_HTML_ONLY, RDNS_NONE
X-Barracuda-Rbl-Trusted-Forwarder: 10.2.2.12
Content-Transfer-Encoding: quoted-printable
Message-Id: <20160425153912.8DDD0BDB8E87662D@suhrr.com>
X-Barracuda-Spam-Score: 0.60
X-Barracuda-Url: https://spam.sans.org:443/cgi-mod/mark.cgi
X-Asg-Orig-Subj: RE: Great Investment Offer
X-Barracuda-Connect: smtp21a.den.sans.org[10.2.2.12]
X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.29050 Rule breakdown below pts rule name              description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO    Envelope rcpt doesn't match header 0.00 MIME_HTML_ONLY         BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE           BODY: HTML included in message 0.00 ADVANCE_FEE_1          Appears to be advance fee fraud (Nigerian 419) 0.10 RDNS_NONE              Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963         Custom Rule MJ1963
Content-Type: text/html; charset="iso-8859-1"
X-Barracuda-Start-Time: 1461613152
X-Barracuda-Brts-Status: 1
X-Barracuda-Envelope-From: melvin@suhrr.com

RE: Great Investment Offer

Wednesday, April 20, 2016

5 keys to success as an Information Security Professional

People ask me all the time, how do I "get in" in cybersecurity. I usually point them to this document:
Ways To Become An Effective Information Security Professional - From A GIAC Wannabe Perspective But what if you are already in the industry? I wrote a Linkedin post on 3 Tips to keep riding the cybersecurity wave that was fairly well received.  In this post, I would like to expand, and reorder, based on some of the comments from the post.

First, you have to stay up to date. Cybersecurity pays well because it is demanding. You are taking a class, that is good, but it is not enough. Build time into your schedule to hone your skills. A really practical way to stay sharp is to write a Python script every week. Please forgive the sharpen the saw cliche, but it matters.  As Russell Eubanks put it: "You could "Begin with the End in Mind" by positioning yourself to become a senior information security leader by focusing on achieving results through others. I bet we all have more lessons learned to share with others than we care to admit."

Second, it is imperative that you balance work and life. Exercise and eat right. If you are married, try to stay married. Make sure your kids and pastor, rabbi, mullah know your name.

Third, balance being a cybersecurity generalist and specialist. The advantage of a course and certification like SANS Security Essentials and following that up with the GSEC certification forces us to stay current on all the major topics of security. If you decide to be a mentor or community SANS instructor it will blow your mind how much material you have to master before teaching it. Being a specialist in some area or even two such as Penetration Testing and Mobile Forensics is a key to being a truly useful member of the team. Every member of a military special forces unit can do each job, but they are experts in a few areas. This is how SANS Cyber Guardian is structured.


Forth, stay cybersecurity organized. Keep one or more lab notebooks close at hand or use note taking software. Never write anything down on scrap paper. When you make a screen shot give it a meaningful label.
Python urllib2 urlopen to dump webpage source
Have the situational awareness to realize how much time and energy you spend looking for things you did not file properly or repeating searches that you did not save the results for. Don't thrash, complete the task at hand.

Fifth, remind yourself from time to time that you are getting older and eventually you will retire or get flushed out of the system. Take some time right now to think about what you are going to do with the second half of your life.