public
Description: Threaded python script to sweep a network range to help determine valid network addresses.
Homepage:
Clone URL: git://github.com/linuxgeek247/Marco.git
Christopher (author)
Sat May 09 16:27:54 -0700 2009
Marco / marco.py
100644 98 lines (81 sloc) 2.846 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/python
 
# marco.py
# Sends arp requests to the entire network range searching for the first response.
# Creates a second thread to monitor for responses to allow the sending thread to just spew packets.
# The whole point is to find a valid IP when on a completely quiet network segment without DHCP
# or any other means to find a valid address.
# I couldn't seem to figure out how to get nmap to do an arp sweep on a network range that I didn't have
# an IP/interface associated with.
# Requires:
# ipaddr (http://code.google.com/p/ipaddr-py/) and of course scapy (http://www.secdev.org/projects/scapy/)
 
import ipaddr
import sys
import logging
import getopt
import time
 
from scapy import *
from threading import Thread
 
class ArpMonitorThread(Thread):
def __init__(self, map):
Thread.__init__(self)
self.map = map
self.found = []
 
def arp_callback(self, pkt):
if pkt[ARP].op == 2:
if pkt[ARP].psrc not in self.found:
print pkt[ARP].sprintf("%psrc% (%hwsrc%)")
self.found.append(pkt[ARP].psrc)
 
if self.map == False:
sys.exit(0)
 
def run(self):
sniff(filter='(arp) and (not ether dst host ff:ff:ff:ff:ff:ff)', store=0, prn=self.arp_callback)
 
def usage():
print "python marco.py [-i <iface>] [-n <network/range>] [-t <timeout>] [-s <saddr>] [-c <count>] [-m] [-h]"
print "\tiface: network interface to send and listen on. (default: lo)"
print "\tnetwork/range: network to scan in CIDR notation. (default: 127.0.0.1)"
print "\ttimeout: how long to wait for responses after sending. (default: 0)"
print "\tsaddr: source address to originate the arp packets from. (default: 127.0.0.1)"
print "\tcount: number of times to send the packets (default: 1)"
print "\t-m: Find all hosts on the network not just the first response (default: disabled)"
sys.exit(0)
 
# Defaults
network = '127.0.0.1'
saddr = '127.0.0.1'
iface = 'lo'
count = 1
map = False
timeout = 0
 
# Parse our arguments
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], 'i:n:t:s:c:hm', ['interface=', 'network=', 'timeout=', 'saddr=', 'count='])
except getopt.GetoptError, err:
usage()
 
for o, a in opts:
if o in ('-i', '--interface') :
iface = a
elif o in ('-n', '--network'):
network = a
elif o in ('-t', '--timeout'):
timeout = int(a)
elif o in ('-s', '--saddr'):
saddr = int(a)
elif o in ('-c', '--count'):
count = (int(a) if (int(a) > 0) else 1)
elif o == '-m':
map = True
else:
usage()
 
# Start the response monitor first
monitor = ArpMonitorThread(map)
monitor.start()
 
# Create our packet list
pkts = []
for ip in ipaddr.IPv4(network):
pkts.append(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(psrc=saddr, pdst=ip))
 
# Send our packets
for i in range(1, count):
sendp(pkts, verbose=0, iface=iface)
 
# Sleep to make sure we get everything
time.sleep(timeout)
 
# All packets have been sent
sys.exit(0)