-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhostscan.py
148 lines (96 loc) · 4.08 KB
/
hostscan.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
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python3
# /undead_warlock
# GPL3.0-or-foward
from mac_vendor_lookup import MacLookup
import scapy.all as scapy
import subprocess
import platform
import optparse
import re
def arguments(): # optparse arguments
singlerun = "singlerun"
address = "address"
log = "log"
parser = optparse.OptionParser()
parser.add_option("-a", "--address", dest= address, help= "Target's IPV4 Address. Use CIDR for full network scan.")
parser.add_option("-s", "--singlerun", dest= singlerun, action= "store_true", default= False, help= "True: One-time Scan | False: Real-time Scan")
parser.add_option("-l", "--log", dest= log, default= False, help= "If used, input a filename to be created with logs")
(inputs, args) = parser.parse_args()
if not inputs.address:
parser.error("\n[X] PLEASE INPUT AN IPV4 ADDRESS")
return (inputs.singlerun, inputs.address, inputs.log)
def checkAddress(ipaddress): # validating user's input
def printQuit():
print()
print("[X] Invalid IP Address")
quit()
return 0
def regexAddress(ipaddress, NOT_CIDR= None):
if NOT_CIDR:
address_numbers = re.findall(r"(([0-9]{1,3})[\.]?)", ipaddress)
else:
address_numbers = re.findall(r"(([0-9]{1,3})[\.\/])", ipaddress)
numbers = [int(value[1]) for value in address_numbers]
return numbers
numbers = regexAddress(ipaddress)
if len(numbers) == 3:
numbers = regexAddress(ipaddress, True)
if len(numbers) != 4: # Checking if ipaddress has 4 octets
printQuit()
for number in numbers: # Checking if a octet value is higher than 255.
if number > 255:
printQuit()
return 1
def arpRequest(Address):
arp_request = scapy.ARP(pdst= Address) # ARP Request for one/multiple IPs.
ethernet_request = scapy.Ether(dst= "ff:ff:ff:ff:ff:ff") # Ethernet request for Broadcast's MAC.
arp_ether_request = ethernet_request/arp_request # ARP Request through MAC's Broadcast Address.
return arp_ether_request
def menu():
print("\nIPv4\t\tMAC Address\t\thwlen\tplen\tMAC Vendor")
print("--"*38)
return 0
def clearTerminal():
OS = platform.system()
if OS == "Windows":
subprocess.call("cls", shell=True)
else:
subprocess.call("clear", shell=True)
def printOutput(singlerun, arp_ether_request, log):
clearTerminal()
menu()
already_printed = list()
if log:
already_logged = list()
loop = 1
while loop:
answered_request = scapy.srp(arp_ether_request, timeout= 1, verbose= False)[0]
for element in answered_request:
if [element[1].psrc, element[1].hwsrc] in already_printed:
continue
already_printed.append([element[1].psrc, element[1].hwsrc])
try :
MacVendor = MacLookup().lookup(element[1].hwsrc)
except:
MacVendor = "Unknown"
print(f"{element[1].psrc}\t{element[1].hwsrc}\t{element[1].hwlen}\t{element[1].plen} \t{MacVendor}" )
if log:
if [element[1].psrc, element[1].hwsrc, MacVendor] not in already_logged:
with open(log, "a") as logfile:
logfile.write("%s,%s,%s \n" %(element[1].psrc, element[1].hwsrc, MacVendor))
already_logged.append([element[1].psrc, element[1].hwsrc, MacVendor])
loop += 1
if singlerun:
loop = 0
if loop == 15:
clearTerminal()
menu()
already_printed = list()
loop = 1
return 1
def main():
singlerun, address, log = arguments()
checkAddress(address)
arp_ether_request = arpRequest(address)
printOutput(singlerun, arp_ether_request, log)
main()