Skip to content

Commit 8e548c5

Browse files
authored
Merge branch 'DhanushNehru:master' into new_features
2 parents 6589c3a + fe8a562 commit 8e548c5

File tree

13 files changed

+820
-0
lines changed

13 files changed

+820
-0
lines changed

Black Hat Python/chapter_03/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,35 @@ Open another terminal pick a host to ping.
1010
ping google.com
1111
```
1212
Then you should see some garbled output
13+
14+
### sniffer_ip_header_decode.py
15+
16+
```bash
17+
sudo sniffer_ip_header_decode.py
18+
```
19+
Open another terminal pick a host to ping.
20+
```bash
21+
ping google.com
22+
```
23+
We would be able to see only the response and only for the ICMP protocol
24+
25+
### sniffer_with_icmp.py
26+
27+
```bash
28+
sudo python3 sniffer_with_icmp.py
29+
```
30+
Open another terminal pick a host to ping.
31+
```bash
32+
ping google.com
33+
```
34+
35+
The output actually indicates that the ping (ICMP Echo) responses are being correctly received and decoded
36+
37+
### scanner.py
38+
39+
This code scans a specified subnet for active hosts by sending UDP datagrams and listening for ICMP "port unreachable" responses to identify which hosts are up. It prints the IP addresses of responsive hosts within the given subnet
40+
```bash
41+
sudo python3 scanner.py 192.168.1.0
42+
43+
# subnet to target: 192.168.1.0/24
44+
```
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import ipaddress
2+
import os
3+
import socket
4+
import struct
5+
import sys
6+
import threading
7+
import time
8+
9+
# Function to get subnet input from user
10+
def get_subnet():
11+
while True:
12+
subnet = input("Enter the subnet to target (e.g., 192.168.1.0/24): ")
13+
try:
14+
# Validate the subnet input
15+
ipaddress.ip_network(subnet)
16+
return subnet
17+
except ValueError:
18+
print("Invalid subnet. Please try again.")
19+
20+
# Magic string we'll check ICMP responses for
21+
MESSAGE = 'PYTHONRULES!'
22+
23+
# Class to handle IP headers
24+
class IP:
25+
def __init__(self, buff=None):
26+
# Unpack the IP header fields from the buffer
27+
header = struct.unpack('<BBHHHBBH4s4s', buff)
28+
self.ver = header[0] >> 4
29+
self.ihl = header[0] & 0xF
30+
self.tos = header[1]
31+
self.len = header[2]
32+
self.id = header[3]
33+
self.offset = header[4]
34+
self.ttl = header[5]
35+
self.protocol_num = header[6]
36+
self.sum = header[7]
37+
self.src = header[8]
38+
self.dst = header[9]
39+
40+
# Convert binary IP addresses to human-readable format
41+
self.src_address = ipaddress.ip_address(self.src)
42+
self.dst_address = ipaddress.ip_address(self.dst)
43+
44+
# Map protocol constants to their names
45+
self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
46+
try:
47+
self.protocol = self.protocol_map[self.protocol_num]
48+
except KeyError:
49+
print('No protocol for %s' % self.protocol_num)
50+
self.protocol = str(self.protocol_num)
51+
52+
# Class to handle ICMP headers
53+
class ICMP:
54+
def __init__(self, buff):
55+
# Unpack the ICMP header fields from the buffer
56+
header = struct.unpack('<BBHHH', buff)
57+
self.type = header[0]
58+
self.code = header[1]
59+
self.sum = header[2]
60+
self.id = header[3]
61+
self.seq = header[4]
62+
63+
# Function to send UDP datagrams with our magic message
64+
def udp_sender(subnet):
65+
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sender:
66+
# Send datagrams to all hosts in the subnet
67+
for ip in ipaddress.ip_network(subnet).hosts():
68+
sender.sendto(bytes(MESSAGE, 'utf8'), (str(ip), 65212))
69+
70+
# Class to handle the scanning and sniffing process
71+
class Scanner:
72+
def __init__(self, host):
73+
self.host = host
74+
# Choose the correct protocol based on the OS
75+
if os.name == 'nt':
76+
socket_protocol = socket.IPPROTO_IP
77+
else:
78+
socket_protocol = socket.IPPROTO_ICMP
79+
80+
# Create a raw socket
81+
self.socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
82+
self.socket.bind((host, 0))
83+
self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
84+
85+
# Enable promiscuous mode on Windows
86+
if os.name == 'nt':
87+
self.socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
88+
89+
def sniff(self, subnet):
90+
# Set to keep track of hosts that are up
91+
hosts_up = set([f'{str(self.host)} *'])
92+
try:
93+
while True:
94+
# Read a packet
95+
raw_buffer = self.socket.recvfrom(65535)[0]
96+
97+
# Create an IP header from the first 20 bytes
98+
ip_header = IP(raw_buffer[0:20])
99+
100+
# If it's ICMP, we want it
101+
if ip_header.protocol == "ICMP":
102+
offset = ip_header.ihl * 4
103+
buf = raw_buffer[offset:offset + 8]
104+
icmp_header = ICMP(buf)
105+
106+
# Check for TYPE 3 and CODE 3
107+
if icmp_header.code == 3 and icmp_header.type == 3:
108+
# Ensure the response is in our target subnet
109+
if ipaddress.ip_address(ip_header.src_address) in ipaddress.IPv4Network(subnet):
110+
# Make sure it has our magic message
111+
if raw_buffer[len(raw_buffer) - len(MESSAGE):] == bytes(MESSAGE, 'utf8'):
112+
if str(ip_header.src_address) not in hosts_up:
113+
hosts_up.add(str(ip_header.src_address))
114+
print(f'Host Up: {ip_header.src_address}')
115+
except KeyboardInterrupt:
116+
# Disable promiscuous mode on Windows
117+
if os.name == 'nt':
118+
self.socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
119+
120+
print('\nUser interrupted.')
121+
if hosts_up:
122+
print(f'\n\nSummary: Hosts up on {subnet}')
123+
for host in sorted(hosts_up):
124+
print(f'{host}')
125+
print('')
126+
sys.exit()
127+
128+
if __name__ == '__main__':
129+
# Get the target subnet from the user
130+
SUBNET = get_subnet()
131+
132+
# Determine the host to bind to
133+
if len(sys.argv) == 2:
134+
host = sys.argv[1]
135+
else:
136+
hostname = socket.gethostname()
137+
host = socket.gethostbyname(hostname)
138+
139+
print("Using host:", host)
140+
141+
# Create a scanner instance
142+
s = Scanner(host)
143+
144+
# Start the UDP sender in a separate thread
145+
t = threading.Thread(target=udp_sender, args=(SUBNET,))
146+
t.start()
147+
148+
# Start sniffing
149+
s.sniff(SUBNET)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import ipaddress
2+
import os
3+
import socket
4+
import struct
5+
import sys
6+
7+
class IP:
8+
def __init__(self, buff=None):
9+
header = struct.unpack('<BBHHHBBH4s4s', buff)
10+
self.ver = header[0] >> 4
11+
self.ihl = header[0] & 0xF
12+
self.tos = header[1]
13+
self.len = header[2]
14+
self.id = header[3]
15+
self.offset = header[4]
16+
self.ttl = header[5]
17+
self.protocol_num = header[6]
18+
self.sum = header[7]
19+
self.src = header[8]
20+
self.dst = header[9]
21+
22+
# human readable IP addresses
23+
self.src_address = ipaddress.ip_address(self.src)
24+
self.dst_address = ipaddress.ip_address(self.dst)
25+
26+
# map protocol constants to their names
27+
self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
28+
try:
29+
self.protocol = self.protocol_map[self.protocol_num]
30+
except Exception as e:
31+
print('%s No protocol for %s' % (e, self.protocol_num))
32+
self.protocol = str(self.protocol_num)
33+
34+
def sniff(host):
35+
# should look familiar from previous example
36+
if os.name == 'nt':
37+
socket_protocol = socket.IPPROTO_IP
38+
else:
39+
socket_protocol = socket.IPPROTO_ICMP
40+
41+
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
42+
sniffer.bind((host, 0))
43+
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
44+
45+
if os.name == 'nt':
46+
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
47+
48+
try:
49+
while True:
50+
# read a packet
51+
raw_buffer = sniffer.recvfrom(65535)[0]
52+
53+
# create an IP header from the first 20 bytes
54+
ip_header = IP(raw_buffer[0:20])
55+
56+
# print the detected protocol and hosts
57+
print('Protocol: %s %s -> %s' % (ip_header.protocol, ip_header.src_address, ip_header.dst_address))
58+
59+
except KeyboardInterrupt:
60+
# if we're on Windows, turn off promiscuous mode
61+
if os.name == 'nt':
62+
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
63+
sys.exit()
64+
65+
if __name__ == '__main__':
66+
if len(sys.argv) == 2:
67+
host = sys.argv[1]
68+
else:
69+
hostname = socket.gethostname()
70+
host = socket.gethostbyname(hostname)
71+
print("Using host:", host)
72+
sniff(host)
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import ipaddress
2+
import os
3+
import socket
4+
import struct
5+
import sys
6+
7+
# Define a class to represent the IP header of a packet
8+
class IP:
9+
def __init__(self, buff=None):
10+
# Unpack the IP header fields from the buffer
11+
header = struct.unpack('<BBHHHBBH4s4s', buff)
12+
self.ver = header[0] >> 4
13+
self.ihl = header[0] & 0xF
14+
self.tos = header[1]
15+
self.len = header[2]
16+
self.id = header[3]
17+
self.offset = header[4]
18+
self.ttl = header[5]
19+
self.protocol_num = header[6]
20+
self.sum = header[7]
21+
self.src = header[8]
22+
self.dst = header[9]
23+
24+
# Convert source and destination IP addresses to human-readable format
25+
self.src_address = ipaddress.ip_address(self.src)
26+
self.dst_address = ipaddress.ip_address(self.dst)
27+
28+
# Map protocol numbers to protocol names
29+
self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
30+
try:
31+
self.protocol = self.protocol_map[self.protocol_num]
32+
except Exception as e:
33+
print('%s No protocol for %s' % (e, self.protocol_num))
34+
self.protocol = str(self.protocol_num)
35+
36+
# Define a class to represent the ICMP header of a packet
37+
class ICMP:
38+
def __init__(self, buff):
39+
# Unpack the ICMP header fields from the buffer
40+
header = struct.unpack('<BBHHH', buff)
41+
self.type = header[0]
42+
self.code = header[1]
43+
self.sum = header[2]
44+
self.id = header[3]
45+
self.seq = header[4]
46+
47+
# Function to sniff packets on a specified host
48+
def sniff(host):
49+
# Determine the appropriate socket protocol
50+
if os.name == 'nt':
51+
socket_protocol = socket.IPPROTO_IP
52+
else:
53+
socket_protocol = socket.IPPROTO_ICMP
54+
55+
# Create a raw socket and bind it to the host
56+
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
57+
sniffer.bind((host, 0))
58+
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
59+
60+
# If running on Windows, set the socket to promiscuous mode
61+
if os.name == 'nt':
62+
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
63+
64+
try:
65+
while True:
66+
# Read a packet
67+
raw_buffer = sniffer.recvfrom(65535)[0]
68+
69+
# Create an IP header from the first 20 bytes of the packet
70+
ip_header = IP(raw_buffer[0:20])
71+
72+
# If the packet is ICMP, process and print its details
73+
if ip_header.protocol == "ICMP":
74+
print('Protocol: %s %s -> %s' % (
75+
ip_header.protocol,
76+
ip_header.src_address,
77+
ip_header.dst_address))
78+
print(f'Version: {ip_header.ver}')
79+
print(f'Header Length: {ip_header.ihl} TTL: {ip_header.ttl}')
80+
81+
# Calculate the starting point of the ICMP packet
82+
offset = ip_header.ihl * 4
83+
buf = raw_buffer[offset:offset + 8]
84+
85+
# Create an ICMP header from the buffer
86+
icmp_header = ICMP(buf)
87+
print('ICMP -> Type: %s Code: %s\n' % (icmp_header.type, icmp_header.code))
88+
except KeyboardInterrupt:
89+
# If running on Windows, turn off promiscuous mode
90+
if os.name == 'nt':
91+
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
92+
sys.exit()
93+
94+
if __name__ == '__main__':
95+
# If a host is specified in command-line arguments, use it
96+
if len(sys.argv) == 2:
97+
host = sys.argv[1]
98+
else:
99+
# Otherwise, get the local machine's IP address
100+
hostname = socket.gethostname()
101+
host = socket.gethostbyname(hostname)
102+
print("Using host:", host)
103+
# Start sniffing packets on the specified host
104+
sniff(host)

Black Hat Python/chapter_04/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
### mail_sniffer.py
2+
3+
- Install scapy package
4+
```python
5+
sudo pip3 install scapy
6+
```
7+
- A simple sniffer
8+
```
9+
sudo python3 mail_sniffer.py
10+
```
11+
12+
### mail_sniffer_using_BPF_syntax.py
13+
- If you are on a network where you know you're already on their internal network and you want to compromise some mail server accounts then you could do that by sniffing the network by running the below command
14+
```
15+
sudo python3 mail_sniffer_using_BPF_syntax.py
16+
```
17+
18+
### arper.py
19+
```
20+
python3 arper_1.py <victim_ip> <gateway_ip> <interface>
21+
python3 arper_2.py <victim_ip> <gateway_ip> <interface>
22+
```

0 commit comments

Comments
 (0)