Wednesday, August 22, 2012

Google Summer of Code with Nmap recap

  This summer, I have worked with the Nmap Security Scanner as part of the Google Summer of Code. I will try to summarize in this post what was for me one of the best experiences ever.
  I applied for GSoC as a NSE Web scanning specialist, which at the time was what I felt most comfortable with, but when results were announced, the Nmap team switched me to work as a NSE network discovery specialist under the mentoring of the great and very helpful Henri Doreau in order to better distribute skills of selected students. I was positive with this change although I was more prepared for the web scanning role and this in fact, turned to be one of the best moves I have had.

I will try to sum up some of the work that I have done during the program:
  • There are many available tools for enumerating Joomla and Wordpress modules, but none are available for Drupal. First script that I have written was http-drupal-modules, a script for enumerating a target Drupal based website's modules. I was going to release a standalone Python tool to do the same task a couple of weeks prior, but ended up to prefer the Nmap Scripting Engine which have many advantages, one of them is the ability to put the tool at hands of much more people.
  • A couple of months ago, Nicolas GrĂ©goire published a blogpost about a cool trick to detect reverse proxies. http-traceroute, is based on the same concept of sending HTTP requests with incremental Max-Forwards HTTP header values. Tests on some Aleksa TOP 100 sites, show some interesting information.
  • One could say my amazing experience started when I began working on my first non http-* script. firewall-bypass is a script that checks for a neat vulnerability in netfilter's conntrack. Eric Leblond presented this vulnerability at CanSecWest11 and was kind enough to share a private PoC with me, a couple of weeks prior to releasing opensvp. I believe that working on this script made me learn a lot as it pushed me to delve into IPv6, advanced netfilter features, setting non-trivial test environments with Linux routing etc,.
  • Do you still rely on wafw00f to detect and fingerprint web application firewalls ? meet http-waf-fingerprint! Initially based on the same collection of fingerprints, that I have gone through one by one, killing false positives and imprecise signatures while adding new fingerprints that I have researched. Besides, Naxsi's developers were kind enough to show us how to detect Naxsi's presence by abusing its score based approach. The scripts also benefits from Nmap's http pipe-lining for extra performances. The script is written in a manner that permits to extend it easily. Harder, better, faster, stronger. ;)
  • I took a short trip into VoIP land, working on some SIP related scripts. First one was sip-methods, a simple script that enumerates a target SIP server's allowed methods, using an OPTIONS request.
  • Second SIP related script was sip-enum-users which as you may have guessed, enumerates SIP extensions. It allows a lot of flexibility (scanning numerical ranges with 0's padding, using file lists etc,.) and being integrated into NSE's brute library, it has all its bells and whistles for multi-threading, timeout settings and such.
  • Probably one of my favorites, sip-call-spoof is a script that as its name suggests, spoofs calls and shows what action was taken by the target (eg. hang up after X seconds). Ekiga's default ringtone was fun to trigger directly from Nmap for the first time and is still echoing in my ears due to the amount of times I heard it while writing/testing the script. During my work on SIP related scripts, I have had the chance to bring many features and bug fixes to Nmap's SIP library.
  • Next Protocol Negotiation is a TLS extension which is mainly used to detect if a target server supports Google's SPDY protocol but allows extending it to other protocols. tls-nextprotoneg is a script which crafts a tls client hello with NPN extension to enumerate a target server's supported protocols. NPN is still a draft, and there aren't many public servers out there that support SPDY, but it is always good to be ahead of the pack, isn't it ?
  • I have added OSPF support to Nmap's packetdecoders by integrating Patrik's OSPF library, to which, I have brought many fixes and changes.
  • In Windows Vista, Microsoft introduced the Link-Layer Topology Discovery protocol, a proprietary protocol that is used for Network mapping. There was already some work in Nmap done by Gorjan Petrovski in the form of lltd-discovery, which uses LLTD to discover hosts on the local network. I have brought fixes to lltd-discovery and added support to printing Hostnames (whic are transmitted as unicode). LLTD is a very interesting protocol for network discovery given the wealth of interesting information it provides (IPv4 address, hostname, MAC address and IPv6 address) and low cost (Sending one broadcat Ethernet Frame).
  • EIGRP is a Cisco proprietary Interior Gateway routing protocol. I have worked on broadcast-eigrp-discovery script that discovers EIGRP enabled routers and grabs routing information.
  • I implemented a small subset of the EIGRP protocol in the form of EIGRP library.
  • From a network discovery perspective, IGMP is an interesting protocol, a very interesting one, actually. broadcast-igmp-discovery is as script that a permits discovering hosts which have multicast groups memberships by sending an IGMP Membership Query message (version 1, 2 or 3) of the chosen version to the All Hosts multicast address (224.0.0.1) and listening for Membership Response messages. What makes this great is the sheer number of default configurations in many operating systems that have group memberships (SSDP's 239.255.255.{250,253} for Windows, mDNS's 224.0.0.251 for Avahi in Ubuntu to name a few) but also the ability to make dedicated guesses on the target operating system from the multicast groups it uses (some of which are for proprietary protocols). I will unarguably investigate this in details.
  • mrinfo is a multicast routing information utility that comes with both Cisco IOS and Windows. It works by sending a crafted DVMRP Ask Neighbors2 request to a target router and listening for the DVMRP Neighbors2 response that the target sends back. Based on the same concept, the mrinfo implementation I have written goes further in terms of network discovery by defaulting to sending the request to the 224.0.0.1 All Hosts multicast address and listening for the responses (while allowing single target querying like the classic mrinfo). This led me to identifying a small bug in Cisco IOS's DVMRP while tinkering with this... Not bad.
  • Nmap had a RPC grinding feature (that was activated 'til March 2011 by using -sR flag but was since part of -sV but still relied on the very old pos_scan scan engine) which allows to fingerprint a Sun RPC target port by sending null commands containing program numbers from Nmap's rpc list. I replaced it with a new NSE based implementation. To not repeat myself, refer to the lengthy description that I posted on nmap-dev. You have the chance to replace some code from 1998 that was written when you were 7/8 years old with modern, more maintainable code that also happens to bring extra performances to the table ? Life is beautiful.
  • Back to Windows land, Link-Local Multicast Name Resolution is a protocol that Microsoft introduced with Windows Vista which allows resolving hostnames on the local link without relying on a DNS Server. llmnr-resolve works by sending a query to 224.0.0.252/UDP5355 containing the specified hostname and listening for the responses that are sent to our local address/UDP5355. The thing is, you just don't know who may be responding. ;)
  • As much as IGMP multicast tracerouting provides a wealth of information to troubleshoot multicast routing as it used to to troubleshoot the path used for a multicast group from a source to a destination host while returning some info on the used protocol between different hops and any errors that may have occured, it is a bit complicated on a first sight. Although most resources I found were CCIE blogs that required a lot of prior knowledge on cisco networks, a good reference could be found here. There is already a mtrace utility in Cisco IOS, but the mtrace I have written for Nmap is most probably better as it lets us define through which first hop to send contrary to IOS as the RPF table of the local router is checked to determine the next hop, even for the router that is initiating the query. As network discovery is all about being cheap sending less traffic and getting more information, we default to a 224.0.0.2 All Routers first hop and 0.0.0.0 multicast group address for multiple traceroutes using a single packet.
  • Discovering Protocol-Independant Multicast enabled routers is not a daunting task. broadcast-pim-discovery just does that for you. It works by crafting a PIM Hello message and sending it to 224.0.0.13 while listening for PIM Hello messages from other routers.
  • A good amount of bug fixes and updates here and there. Some were trivial while others were a bit more complicated to debug but still not worthy of single mentioning as I don't want to make my longest blog post even longer. All changes made could be found by checking commits from my svn user "kroosec" to Nmap's repository.

  And that is it. Although I believe I could have done much more if I didn't have to split my time between working on Nmap and preparing my graduation which will be next September (thank you again David Allen for the GTD), this was without doubt a great experience overall. The GSoC pushed to learn so much in a short period, being a good generalist to be able to adapt to different tasks and rapidly grasp new concepts while also being a good specialist when it comes to going deep into some protocols. I am far much better at setting labs and writing and testing new PoC's. I gained valuable experience with Cisco IOS (that I barely knew prior to GSoC). Crawling long RFC pages and crafting/parsing packets of some obscure, proprietary protocol don't cast uncertainty in me anymore... but I release better why with hundreds of packet dissectors, Wireshark is a mine of vulnerabilities. ;)
I still know how much is there to learn and discover, though. After all, life is about continuous learning and the day you stop learning is the day you start to become obsolete.

What's next ?
  Being a Nmap developer isn't going to stop with the GSoC. Actually, I still have a lot of interesting work in mind, to accomplish. Daniel Miller and David Fifield did a great job and recently added support for xml output in NSE. Thus, we will be making changes in Nmap's scripts to allow this feature. I have in my drafts, many more ideas for useful scripts that I will have to detail more before adding them to Nmap's scripts ideas wiki page, if anyone else happens to be interested in working on some and end up writing them before me.

  As other projects go, Network Discovery is a field that I plan to study more, the amount of exotic protocols and intracities in different implementations out there is very exciting. I have in mind some other projects that I will be sharing soon, depending on time.
Finally, I wish Aleksander Nikolic and Piotr Olma who both worked on NSE as part of GSoC good luck. Smart guys with a brilliant future. I would also like to thank again my gsoc mentor Henri Doreau. Without his great tutoring, I wouldn't have done much. Special thanks to Djalal Harouni who pushed me to take part of GSoC and encouraged me many times when I was in doubt.

Wednesday, August 15, 2012

Bug in Cisco IOS's DVMRP


 mrinfo is a handy multicast troubleshooting tool that comes with Cisco IOS (and Windows). It works by sending a DVMRP Ask Neighbors2 message to a target router and listening for the response message that is sent back.  draft-ietf-idmr-dvmrp-v3-11 contains a good explanation of what is DVMRP.
 While working on a similar (yet better ;)) implementation for Nmap's NSE, I have come across an interesting bug in Cisco IOS's implementation of DVMRP. (Tested against 12.4 and 15.0).

To demonstrate this, let's try with a simple test environment in which we have two routers:
Router1: 172.16.0.4
Router2: 172.16.0.5
both routers are connected to the same LAN via FastEthernet0/0, and have PIM enabled (mode is not important, as this was tested with both DM and SM modes.)
 When we execute the command #mrinfo 172.16.0.5 on Router1, the expected outcome happens. Router1 sends a DVMRP Ask Neighbors2 message to Router2, and the latter replies with a DVMRP Neighbors2 message.


 We could have a better perspective on how the routers are interpreting the packets with IOS's debugger using #debug ip dvmrp command. ( #terminal monitor is needed when remotely connected to the routers.) The events (sending and receiving on both sides) are shown by the debugger.



The fun comes when we think (just a bit) outside of the box and issue the #mrinfo 224.0.0.1 command. 224.0.0.1 being all hosts multicast address, means that it will be seen by Router2. When I first tried this, I hoped that mrinfo will parse all the responses from the routers that replied, but I was expecting it to just pick the first response to arrive.

In a normal way, Router1 will send the Ask Neighbors2 message, Router2 will receive the message, and respond to it with a Neighbors2 message.


Interestingly though, Router2 will set the destination address of the packet as 224.0.0.1.


As expected, Router1 will ignore the packet that has 224.0.0.1 as the source address.


Leading to the error "% Timed out receiving response"
Sending to destinations such as 224.0.0.2 (All Routers) and 224.0.0.4 (DVMRP) multicast addresses would yield the same results. This works even with 255.255.255.255 :)


Trying with another tool such as mtrace (The one I committed to Nmap, not Cisco IOS', as it is not flexible enough to let us choose which address to send to), which sends an IGMP Traceroute Query message and listens for IGMP Traceroute Response messages, we see the normal behavior: The target routers using their interfaces' addresses as the source address.


My call ? Sloppy programming in which, instead of using the interface address, the destination address of the request message is used as the source address of the response. If we got the packet, it was necessarily meant for us, right ?
Oh, and mrinfo sends those packets to multicast addresses with a TTL of 255, contrary to what RFC 3171. Another sign, that we are not using the tool as it was intended to be used as. :)