-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscanner.py
More file actions
148 lines (106 loc) · 4.08 KB
/
scanner.py
File metadata and controls
148 lines (106 loc) · 4.08 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
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
# -*- coding: utf-8 -*-
import socket
import os
import struct
from ctypes import *
import threading
import time
from netaddr import IPNetwork,IPAddress
# ip addres of listened host
host = '192.168.91.134'
# the subnet of the target
subnet = "192.168.91.0/24"
# magic message to check icmp response
magic_message = "PYTHONRULES!"
# send udp data gram to subnet
def udp_sender(subnet, magic_message):
time.sleep(5)
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# SOCK_DGRAM: set to use udp
for ip in IPNetwork(subnet):
try:
sender.sendto(magic_message, ("%s" % ip,65212))
except:
pass
# ip header
class IP(Structure):
_fields_ = [
("ihl", c_uint8, 4),
("version", c_uint8, 4),
("tos", c_uint8),
("len", c_uint16),
("id", c_uint16),
("offset", c_uint16),
("ttl", c_uint8),
("protocol_num", c_uint8),
("sum", c_uint16),
("src", c_uint32),
("dst", c_uint32)
]
def __new__(self, socket_buffer=None):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer=None):
# mapping protocol constant value to name
self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}
# transfer to readable ip address
self.src_address = socket.inet_ntoa(struct.pack("<L", self.src))
self.dst_address = socket.inet_ntoa(struct.pack("<L", self.dst))
# transfer to readable protocol name
try:
self.protocol = self.protocol_map[self.protocol_num]
except:
self.protocol = str(self.protocol_num)
class ICMP(Structure):
_fields_ = [
("type", c_uint8),
("code", c_uint8),
("checksum", c_uint16),
("unused", c_uint16),
("next_hop_mtu", c_uint16)
]
def __new__(self, socket_buffer):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer):
pass
# handle like last example
if os.name == "nt":
socket_protocol = socket.IPPROTO_IP
else:
socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
# setting to add ip address of listened host to capture result
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# start to send packet
t = threading.Thread(target=udp_sender, args=(subnet, magic_message))
t.start()
try:
while True:
# read packets
raw_buffer = sniffer.recvfrom(65565)[0]
# create ip structure from first 20 bytes of buffer
ip_header = IP(raw_buffer[0:20])
# print detected host and protocol
print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)
# handle if icmp
if ip_header.protocol == "ICMP":
# calculate the position of icmp packet
offset = ip_header.ihl * 4
buf = raw_buffer[offset:offset + sizeof(ICMP)]
# create structure of icmp
icmp_header = ICMP(buf)
print "ICMP -> Type: %d Code: %d" % (icmp_header.type, icmp_header.code)
# check if code and type are 3
if icmp_header.code == 3 and icmp_header.type == 3:
# check if subnet of the target
if IPAddress(ip_header.src_address) in IPNetwork(subnet):
# check if magic message is included
if raw_buffer[len(raw_buffer)-len(magic_message):] == magic_message:
print "Host Up: %s" % ip_header.src_address
# handle Ctrl-C
except KeyboardInterrupt:
# disable promisecasmode if windows
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)