Tuesday, November 23, 2010

IPv6 link-local host discovery concept

Recently I spoke about IPv6 security at the dc303 meeting.  I was trying to do a demo of the new metasploit module, but the local switch had IPv6 disabled.  Scott Hogg ended up using Scapy to send a spoofed router advertisement packet which would in turn force all hosts to do an IP auto discovery.  Think about how you can take this to the next level, and use it for host discovery in situations where hosts do not respond to ping's, and without having to brute force scan.


Process
The idea behind this is that your OS/kernel deals with IP auto configuration; it is done using ICMP packets, and are packets that (for the most part) bust be responded to and processed.  Un-like IPv4, you cant just drop all ICMP.  If your machine is on a network without IPv6 turned on, it will not obtain a global address.  ifconfig will look something like (mac addresses have been modified):



$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1a:a0:52:11:22  
          inet addr:192.168.1.7  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21a:a0ff:fe52:1122/64 Scope:Link

Notice, you only have 1 IPv6 address.  

In order for your OS to start doing an IP auto-config, it will have to be directed by a router on the local segment to obtain an IP address via IP auto-config; it must see a ICMPv6 router advertisement message . There are a few things that come to mind when thinking about how to craft this spoofed packet:

1. Have it look like it was sent from the legitimate router (use the router MAC) 
2. Have it look like it was sent from someone else on the network - making it look like someone else is doing your dirty work
3. Completely random information
4. Completely legitimate information

I am going to use Scapy to create the router advertisement.  The packet will look like this:

>>> a = IPv6()/ICMPv6ND_RA()/ICMPv6NDOptPrefixInfo(prefix='2001:db8:dead:beef::', prefixlen=64)/ICMPv6NDOptSrcLLAddr(lladdr="04:1E:DD:AA:BB:73")

Broken down:
IPv6()
This is the IPv6 header
ICMPv6ND_RA()
This says the packet is going to be an ICMPv6 Neighbor Discovery Router Advertisement
ICMPv6NDOptPrefixInfo(prefix='2001:db8:dead:beef::', prefixlen=64)
This is an ICMPv6 Option, of type Prefix Information.  The prefix/prefixlen says that during the auto-ip config process, each node will attempt to get a /64 with the prefix 2001:db8:50:50::
ICMPv6NDOptSrcLLAdd
Another ICMPv6 Option, of type Source Link Local Address, or what MAC address is the default route/router.


To put this on the wire, you simply run:

>>> send(a)
.
Sent 1 packets.




Note: I have been having a lot of difficulty on OSX doing this, not sure the exact issues


This will cause all of the devices on the link-local to start auto-config'ing another interface.  ifconfig should look something like:


$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1a:a0:52:11:22  
          inet addr:192.168.1.7  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: 2001:db8:dead:beef:21a:a0ff:fe52:1122/64 Scope:Global
          inet6 addr: fe80::21a:a0ff:fe52:1122/64 Scope:Link


Something interesting to notice is that on this host (Ubuntu) the IPv6 addresses have the same host portion of the IP address:
2001:0db8:dead:beef:21a:a0ff:fe52:1122
fe80:0000:0000:0000:21a:a0ff:fe52:1122


Note: New Windows randomize addresses, and periodically change them.


This concept can be used for a link-local host discovery even for hosts that are not responding to ICMPv6 PingRequest's.


1. Send out a Router Advertisement
2. Monitor for all Host Advertisements
3. Replace first half of seen IPv6 address with the first half of the link-local address
4. Send a ICMPv6 HostSolicitation to the link-local address for confirmation


metasploit module to follow.

Friday, November 19, 2010

IPv6 fuzzing with Peach

I started to write an IPv6 header fuzzer in Peach, and recently moved to writing it as a metasploit auxiliary module.  Its half done, but in case it can help anyone, here it is.

This is all done on OSX with Peach 2.3.6

1. Must have scapy installed. (ports has it for osx, aptitude on ubuntu)

2. Add pScapy.pyc to the Peach installation; in my case:
/opt/Peach-2.3.6/Peach/Publishers/pScapy.pyc

3. Modify the /opt/Peach-2.3.6/Peach/Publishers/__init__.py and include pScapy to the __all__ variable:

__all__ = ["file", "sql", "stdout",
        "tcp", "udp", "com", "process",
        "http", "icmp", "raw", "remote",
        "dll", "smtp", "wifi", "pScapy"]

Note: When writing this, I accidentally deleted pScapy.py, so if anyone knows how to, or can decompile the .pyc file, it would be of great help.

4. Modify the ipv6.xml to contain a valid destination MAC and IPv6 address

5. Run:
# python peach.py ipv6.xml



Tuesday, November 16, 2010

IPv6 security at dc303

I will be speaking about IPv6 security at the next dc303 meeting.  All presentations, and tools will be posted here just prior to the start of the meeting.

Meeting location, and general dc303 information can be found here:
http://dc303.org/

Slides can be found here: dc303.ipv6.pptx

Friday, November 12, 2010

Meteasploit's new HTTP fuzzer

In a blog post, I noticed metasploit has a new HTTP fuzzer:

http://www.corelan.be:8800/index.php/2010/11/12/metasploit-module-http-form-field-fuzzer/

One thing that really stood out on that post was:
While this type of fuzzing/audits most likely won’t reveal bugs in the most common webserver platforms themselves (Apache, IIS, etc), I am convinced that there are a lot of other web server components out there that may not properly validate input from form fields or header fields.
So, I thought to myself, what embedded system do I have.... My router, and low and behold(after a little bit to figure out the timing):


msf auxiliary(http_form_field) > set url /cgi-bin/XXXX
url => http://192.168.1.1/cgi-bin/XXXX
msf auxiliary(http_form_field) > set rhost 192.168.1.1
rhost => 192.168.1.1
msf auxiliary(http_form_field) > set vhost 192.168.1.1
vhost => 192.168.1.1
msf auxiliary(http_form_field) > set rport 80
rport => 80
msf auxiliary(http_form_field) > set delay .1
delay => .1
msf auxiliary(http_form_field) > run


[*] [+] Grabbing webpage /cgi-bin/XXXX from 192.168.1.1
[*] [+] Code : 200
[*] [+] Enumerating form data
[*]     Number of forms : 1
[*]     - Enumerating form #1
[*]       Field : username, type text
[*]       Field : password, type password
[*]       Field : , type submit
[*]       Field : , type reset
[*]       Nr of fields in form 'noname_1' : 2
[*]     Forms : 
[*]      - Name : noname_1, ID : noname_1, Action : /cgi-bin/XXXX, Method : post
[*] [+] Fuzzing fields in form NONAME_1
[*]     - Fuzzing field username
[*] [+] Done fuzzing fields in form NONAME_1
[*] [+] Fuzzing header fields
[*]     - Fuzzing header 'method' (1/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header method | fuzzdata length : 2000
[*]     - Fuzzing header 'User-Agent' (2/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header User-Agent | fuzzdata length : 2000
[*]     - Fuzzing header 'Content-Type' (3/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header Content-Type | fuzzdata length : 2000
[*]     - Fuzzing header 'Content-Length' (4/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header Content-Length | fuzzdata length : 2000
[*]     - Fuzzing header 'Accept-Encoding' (5/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header Accept-Encoding | fuzzdata length : 2000
[*]     - Fuzzing header 'Referer' (6/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header Referer | fuzzdata length : 2000
[*]     - Fuzzing header 'Keep-Alive' (7/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header Keep-Alive | fuzzdata length : 2000
[*]     - Fuzzing header 'Accept' (8/12)
[-]       [-] No response - 1 / 2 - fuzzdata length : 1000
[-]       [-] No response - 2 / 2 - fuzzdata length : 2000
[*]       *!* No response : header Accept | fuzzdata length : 2000
^C[-] Auxiliary interrupted by the console user
[*] Auxiliary module execution completed


First try... Web server is not responding.

Backtrack Persistent USB

I finally purchased a USB stick to carry on me at all times.  Specifically for when friends need computer help, I have my tools on me, as well as I plan on doing some contract social engineering/pen-testing work.

I was able to install a Backtrack 4 R1 on it using a persistent state basically following this tutorial:

http://www.infosecramblings.com/backtrack/backtrack-4-usbpersistent-changesnessus/

I had a hard time getting grub installed via command line on an Ubuntu box.  When booting from the USB after doing a grub-install, it would simply boot to the grub shell. To get around that, I had to use a Windows 7 VM and UNetbootin to make the first partition bootable.  Even with all of that, I cant get the menu to default boot into the persistent state option. I have changed the grub menu text, and it still boots into option 0.  I think its due to first installing grub via command line, then without re-formatting using UNetbootin.

Other additions/changes I made:

Update the system:
# apt-get update
# apt-get upgrade
# apt-get clean

Enabled networking using this command:
# update-rc.d networking default

Update metasploit:
# cd /opt/metasploit/msf3
# svn update

Things to do:
Install firesheep - Yes, it could be helpful
Install watobo - New web app pen testing application
Script to reverse shell home
Script in fat32 partition for universal reverse shell home
Add Windows debugging tools to fat32 partition - Always come in handy