Finding Live Hosts on the Local Network Segment Using Metasploit

I’ve been learning ruby of late, and one way I’m doing that is by tearing into Metasploit. This has a few nice benefits for me:

* I get to see real code, written by smart people
* I get to learn metasploit a lot better
* I get to figure out how to write my own modules for metasploit

Since I’ve got a couple of arp flood/sweep scripts I’ve written in both perl and python, I figured that’d be a decent place to start.

It turns out that metasploit has a module already to do this (arp_sweep.rb), so I started out by taking a look at it. At first, I thought it didn’t do an active sweep, because it appeared to operate on a pcap file only. I tweeted a question to #metasploit about that, and was quickly informed by @hdmoore that the module does indeed work on the target network, I just needed to set the INTERFACE option.

At that point I realized I should probably stop relying on just the code, and start poking at things from within the console =)

First thing’s first, the arp_sweep module relies on pcaprub. Because I’m using Ubuntu 9.10 (Karmic Koala) vs. something like Backtrack, this module was not already configured. I found a great post over at darkoperator.com which explained, among other things, how to get this working. Here are the steps I took:

From inside my metasploit svn trunk directory (~/src/svn/metasploit/framework3/trunk in my case), I ran the following:

   $ cd external/pcaprub
   $ ruby extconf.rb && make
   $ sudo make install

Note that you need to have the libpcap-dev package in order for the compile of pcaprub to work.

Once I had that done, I returned to the main trunk directory, and ran msfconsole as root (that last bit is important, the arp sweep must be run as root in linux as far as I can tell, due to the fact that the module puts the interface into promiscuous mode to capture the ARP replies):

root:~/msf# ./msfconsole

                 o                       8         o   o
                 8                       8             8
ooYoYo. .oPYo.  o8P .oPYo. .oPYo. .oPYo. 8 .oPYo. o8  o8P
8' 8  8 8oooo8   8  .oooo8 Yb..   8    8 8 8    8  8   8
8  8  8 8.       8  8    8   'Yb. 8    8 8 8    8  8   8
8  8  8 `Yooo'   8  `YooP8 `YooP' 8YooP' 8 `YooP'  8   8
..:..:..:.....:::..::.....::.....:8.....:..:.....::..::..:
::::::::::::::::::::::::::::::::::8:::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


       =[ metasploit v3.3.4-dev [core:3.3 api:1.0]
+ -- --=[ 528 exploits - 248 auxiliary
+ -- --=[ 196 payloads - 23 encoders - 8 nops
       =[ svn r8703 updated today (2010.03.03)

The next thing that happens when I load msfconsole is that a bunch of stuff I have set in my msfconsole.rc gets loaded. If you want more information on what that means, Mubix has a great introduction to metasploit rc files at his practical exploitation site. Here’s what it looks like:

resource (/root/.msf3/msfconsole.rc)> color false
resource (/root/.msf3/msfconsole.rc)> setg RHOSTS 10.0.1.0/24
RHOSTS => 10.0.1.0/24
resource (/root/.msf3/msfconsole.rc)> setg RHOST 10.0.1.75
RHOST => 10.0.1.75
resource (/root/.msf3/msfconsole.rc)> setg LHOST 10.0.1.51
LHOST => 10.0.1.51

The LHOST setting reflects the IP address of my testing host, the RHOST setting is a victim host I have on my network specifically to attack, and the RHOSTS is my lab network. The color false is there for a few reasons, one of them being that I like transparent term windows and color text sometimes doesn’t play well with that.

The next step is to load the arp_sweep module and check out what options it takes. The module is in the auxiliary tree within metasploit, and can be loaded like so:

msf > use auxiliary/scanner/discovery/arp_sweep
msf auxiliary(arp_sweep) > show options

Module options:

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   INTERFACE                   no        The name of the interface
   PCAPFILE                    no        The name of the PCAP capture file to process
   RHOSTS     10.0.1.0/24      yes       The target address range or CIDR identifier
   SHOST                       yes       Source IP Address
   SMAC                        yes       Source MAC Address
   THREADS    1                yes       The number of concurrent threads
   TIMEOUT    500              yes       The number of seconds to wait for new data

You can see here some of the effects of the resource file that was loaded earlier, the RHOSTS option is already set for me. I need to set a couple of other things though to make this work, like the source IP address and MAC, as well as the aforementioned INTERFACE setting:

msf auxiliary(arp_sweep) > set SHOST 10.0.1.51
SHOST => 10.0.1.51
msf auxiliary(arp_sweep) > set INTERFACE wlan0
INTERFACE => wlan0

To set the SMAC option, I need to find the MAC address of my network adapter. Because I’m using wireless for my testing, I need to grab that information from the wlan0 interface. Fortunately, ifconfig provides this information. Even more fortunately, metasploit allows system commands to be run from within the console, so I can get this quite easily. :

msf auxiliary(arp_sweep) > ifconfig wlan0
[*] exec: ifconfig wlan0

wlan0     Link encap:Ethernet  HWaddr 00:1b:77:df:e9:ae
          inet addr:10.0.1.51  Bcast:10.0.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21b:77ff:fedf:e9ae/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8229414 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12543574 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2582588276 (2.5 GB)  TX bytes:797473527 (797.4 MB)

Now that I have the MAC address (it’s presented in the HWaddr string above), I can set the last option:

msf auxiliary(arp_sweep) > set SMAC 00:1b:77:df:e9:ae
SMAC => 00:1b:77:df:e9:ae

One more thing to change; I like to increase the thread count to keep things moving quickly:

msf auxiliary(arp_sweep) > set THREADS 20
THREADS => 20

Now I run show options once more to make sure the changes I made look right:

msf auxiliary(arp_sweep) > show options

Module options:

   Name       Current Setting    Required  Description
   ----       ---------------    --------  -----------
   INTERFACE  wlan0              no        The name of the interface
   PCAPFILE                      no        The name of the PCAP capture file to process
   RHOSTS     10.0.1.0/24        yes       The target address range or CIDR identifier
   SHOST      10.0.1.51          yes       Source IP Address
   SMAC       00:1b:77:df:e9:ae  yes       Source MAC Address
   THREADS    20                 yes       The number of concurrent threads
   TIMEOUT    500                yes       The number of seconds to wait for new data

And then I can run the module:

msf auxiliary(arp_sweep) > run

[*] 10.0.1.1 appears to be up.
[*] 10.0.1.2 appears to be up.
[*] 10.0.1.5 appears to be up.
[*] 10.0.1.18 appears to be up.
[*] 10.0.1.49 appears to be up.
[*] 10.0.1.50 appears to be up.
[*] 10.0.1.75 appears to be up.
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed

Excellent! I got a nice list of live hosts on the local network segement using ARP.

I’ll talk about why this is useful (over something like tcp portscanning the local network) in a blog post soon.

[edit]
I should mention by the way: if you wanted to do this outside of metasploit, you could do something like the following:

$ for i in `seq 0 254`; do sudo arping -I wlan0 -c1 -f 10.0.1.$i; done |grep Unicast

The results aren’t nearly as pretty (nor are they as quickly gotten):

Unicast reply from 10.0.1.1 [00:0E:08:ED:A8:B1]  2.028ms
Unicast reply from 10.0.1.2 [00:15:62:FF:D6:06]  1.248ms
Unicast reply from 10.0.1.5 [00:20:00:38:20:6C]  2.548ms
Unicast reply from 10.0.1.18 [00:1D:73:A4:0A:AD]  1.182ms
Unicast reply from 10.0.1.49 [00:1F:3C:CD:50:1C]  1.652ms
Unicast reply from 10.0.1.50 [00:21:97:47:6C:80]  1.766ms
Unicast reply from 10.0.1.75 [00:02:55:42:08:0D]  1.203ms