-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathIP-sampler.py
executable file
·138 lines (119 loc) · 4.55 KB
/
IP-sampler.py
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#! /usr/bin/env python2
import os
import re
import sys
import argparse
import random
import signal
from math import ceil
from libnmap.process import NmapProcess
from libnmap.parser import NmapParser, NmapParserException
from multiprocessing import Lock, Process, Queue, Pool
def parse_args():
#Create the arguments
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--hostlist", help="Enter the hosts list file")
parser.add_argument("-p", "--percent", default=5, type=float, help="Enter the percent of IPs per netblock to sample")
parser.add_argument("-w", "--workers", default=10, type=int, help="Enter the number of paralell workers")
parser.add_argument("--portscan", action="store_true", help="Instead of doing an ICMP ping sweep, check for at least one of the top 5 ports to respond with SYN/ACK")
parser.add_argument("--arpscan", action="store_true", help="Instead of doing an ICMP ping sweep, perform an ARP ping sweep")
return parser.parse_args()
def main(args):
'''
Set up async workers then print final results
'''
procs = []
lock = Lock()
q = Queue()
percent = args.percent / float(100)
if args.portscan:
pingtype = 'portscan'
elif args.arpscan:
pingtype = 'arpscan'
else:
pingtype = None
# Catch CTRL-C
def signal_handler(signal, frame):
# Stop further processes from spawning
q.put('STOP')
print '[-] Killing process'
for p in procs:
p.terminate()
if os.path.isfile('ghostdriver.log'):
os.remove('ghostdriver.log')
q.close()
signal.signal(signal.SIGINT, signal_handler)
if not args.hostlist:
sys.exit('[-] Enter a hostlist file using the -l flag')
hosts_list = open(args.hostlist, 'r').readlines()
# Create list of netblocks
for l in hosts_list:
l = l.strip()
q.put(l)
#q.put(None)
# Can't use Pool because pool makes process daemonic which can't produce children
# NmapProcess is a child of the worker process
procs = []
for w in xrange(args.workers):
p = Process(target=worker, args=(q, lock, percent, pingtype))
#p.daemon = True
p.start()
procs.append(p)
q.put('STOP')
for p in procs:
p.join()
if os.path.isfile('SampleIPs.txt'):
print '[+] Check SampleIPs.txt for a random {0}% sample of total online hosts'.format(str(percent * 100))
else:
print '[-] No online hosts found'
def worker(q, lock, percent, pingtype):
'''
Create Nmap processes to ping sweep each subnet then add a percentage
of the hosts that are up to the master sample list
'''
for netblock in iter(q.get, 'STOP'):
if pingtype == 'portscan':
nmap_args = '--top-ports 5 --max-rtt-timeout 150ms --max-retries 3'
elif pingtype == 'arpscan':
nmap_args = '-T4 -sn --max-rtt-timeout 150ms --max-retries 3'
else:
nmap_args = '-T4 -PE -sn --max-rtt-timeout 150ms --max-retries 3'
print '[*] nmap {0} {1}'.format(nmap_args, netblock)
nmap_proc = NmapProcess(targets=netblock, options=nmap_args)
rc = nmap_proc.run()
xml = nmap_proc.stdout
try:
report = NmapParser.parse(xml)
except NmapParserException as e:
print 'Exception raised while parsing scan: {0}'.format(e.msg)
continue
subnet_hosts_up = []
for host in report.hosts:
if host.is_up():
ip = host.address
hostname = None
if len(host.hostnames) != 0:
hostname = host.hostnames[0]
if pingtype == 'portscan':
for s in host.services:
if re.search('open|filtered', s.state):
subnet_hosts_up.append(ip)
break
else:
subnet_hosts_up.append(ip)
num_hosts = float(len(subnet_hosts_up))
random_sample_num = int(ceil(num_hosts * percent))
sample = []
for i in xrange(random_sample_num):
s = random.choice(subnet_hosts_up)
sample.append(s)
if len(sample) > 0:
print '[+] Random {0}% of live hosts in subnet {1}:'.format(percent*100, netblock)
for ip in sample:
print ' ', ip
if len(sample) > 0:
with lock:
with open('SampleIPs.txt', 'a+') as f:
for ip in sample:
f.write(ip+'\n')
main(parse_args())