-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDPI_test.py
More file actions
67 lines (51 loc) · 2.48 KB
/
DPI_test.py
File metadata and controls
67 lines (51 loc) · 2.48 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
import os
from netfilterqueue import NetfilterQueue
from scapy.layers.inet import IP, TCP
from scapy.layers.tls.handshake import TLSClientHello
from scapy.layers.tls.record import TLS
from scapy.packet import Raw
from scapy.sendrecv import send
MSG_TYPE = 0
HANDSHAKE_TYPE = 5
HANDSHAKE = 0x16
CLIENT_HELLO = 0x01
SPLIT_AT = 2
tcp_streams = {}
def process_packet(packet):
scapy_packet = IP(packet.get_payload())
if scapy_packet.haslayer(TCP) and scapy_packet[TCP].payload:
tcp_payload = bytes(scapy_packet[TCP].payload)
stream_id = (scapy_packet[IP].src, scapy_packet[TCP].sport,
scapy_packet[IP].dst, scapy_packet[TCP].dport)
if tcp_payload[MSG_TYPE] == HANDSHAKE and tcp_payload[HANDSHAKE_TYPE] == CLIENT_HELLO:
tcp_streams[stream_id] = [tcp_payload, scapy_packet[IP].seq, scapy_packet[IP].ack]
packet.drop()
elif stream_id in tcp_streams:
tcp_streams[stream_id][0] += tcp_payload
if TLS(tcp_streams[stream_id][0]).haslayer(TLSClientHello):
scapy_packet_p1 = scapy_packet[IP] / scapy_packet[TCP]
scapy_packet_p2 = scapy_packet[IP] / scapy_packet[TCP]
del scapy_packet_p1[IP].len, scapy_packet_p1[IP].chksum, scapy_packet_p1[TCP].chksum, scapy_packet_p1[TCP].payload, scapy_packet_p1[TCP].seq, scapy_packet_p1[TCP].ack
del scapy_packet_p2[IP].len, scapy_packet_p2[IP].chksum, scapy_packet_p2[TCP].chksum, scapy_packet_p2[TCP].payload, scapy_packet_p2[TCP].seq, scapy_packet_p2[TCP].ack
scapy_packet_p1 /= Raw(tcp_streams[stream_id][0][:SPLIT_AT])
scapy_packet_p2 /= Raw(tcp_streams[stream_id][0][SPLIT_AT:])
scapy_packet_p1[TCP].seq = tcp_streams[stream_id][1]
scapy_packet_p2[TCP].seq = tcp_streams[stream_id][1] + SPLIT_AT
scapy_packet_p1[TCP].ack = tcp_streams[stream_id][2]
scapy_packet_p2[TCP].ack = tcp_streams[stream_id][2]
send(scapy_packet_p2, verbose=False)
send(scapy_packet_p1, verbose=False)
del tcp_streams[stream_id]
packet.drop()
else:
packet.accept()
else:
packet.accept()
os.system("iptables -I INPUT -p tcp ! --dport 443 -j NFQUEUE --queue-num 5")
nfqueue = NetfilterQueue()
nfqueue.bind(5, process_packet)
try:
nfqueue.run()
finally:
os.system("iptables -D INPUT -p tcp ! --dport 443 -j NFQUEUE --queue-num 5")
nfqueue.unbind()