-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathft.py
179 lines (143 loc) · 5.7 KB
/
ft.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
from socket import IPPROTO_TCP
import socket
import pynetfilter_conntrack
from pynetfilter_conntrack import *
from struct import *
class Filter(object):
"""docstring for Filter"""
def __init__(self):
pass
@staticmethod
def dump_table():
try:
ct = pynetfilter_conntrack.Conntrack()
table,count = ct.dump_table(socket.AF_INET)
return table
except Exception, e:
raise e
@staticmethod
def filter(ip, port, table):
try:
for entry in table:
if ((entry.orig_l4proto == IPPROTO_TCP) and ((entry.tcp_state == TCP_CONNTRACK_ESTABLISHED) or (entry.tcp_state == TCP_CONNTRACK_LAST_ACK)\
or (entry.tcp_state == TCP_CONNTRACK_CLOSE_WAIT) or (entry.tcp_state == TCP_CONNTRACK_FIN_WAIT) or (entry.tcp_state == TCP_CONNTRACK_TIME_WAIT) \
or (entry.tcp_state == TCP_CONNTRACK_CLOSE))\
and (ip == str(entry.orig_ipv4_src)) and (port == entry.orig_port_src)):
#print "Established connection, Closing or Time Wait"
return True # This connection is a "normal connction and should be passed to the application"
elif (entry.orig_l4proto == IPPROTO_TCP):
print "Not an Established connection"
return False
except Exception, e:
raise e
@staticmethod
def newconn(ip, port, table):
try:
for entry in table:
if ((entry.orig_l4proto == IPPROTO_TCP) and (entry.tcp_state == TCP_CONNTRACK_ESTABLISHED) and (ip == str(entry.orig_ipv4_src)) and (port == entry.orig_port_src)):
#print entry.tcp_state
print "Syn packet With established connection"
return False
elif ((entry.orig_l4proto == IPPROTO_TCP) and (entry.tcp_state == TCP_CONNTRACK_SYN_RECV) and (ip == str(entry.orig_ipv4_src)) and (port == entry.orig_port_src) ):
print "New Connection"
return True
except Exception, e:
raise e
@staticmethod
def checksum(msg):
s = 0
# loop taking 2 characters at a time
for i in range(0, len(msg), 2):
w = ord(msg[i]) + (ord(msg[i+1]) << 8 )
s = s + w
s = (s>>16) + (s & 0xffff);
s = s + (s >> 16);
#complement and mask to 4 byte short
s = ~s & 0xffff
return s
@staticmethod
def parser(buff, port=8080):
ip_header = buff[0:20]
iph = unpack('!BBHHHBBH4s4s', ip_header)
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph[5]
protocol = iph[6]
s_addr = socket.inet_ntoa(iph[8])
d_addr = socket.inet_ntoa(iph[9])
tcp_header = buff[iph_length:iph_length+20]
#now unpack them :)
tcph = unpack('!HHLLBBHHH' , tcp_header)
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
flags = tcph[5]
h_size = iph_length + tcph_length * 4
data_size = len(buff) - h_size
if (dest_port == port) and (protocol == 6) : # Is the destination port that of the server and is the Protocol TCP (6)
return [s_addr, source_port, sequence, acknowledgement, flags, d_addr]
else:
return False
@staticmethod
def repack(buff, dest):
print "Repacking....."
bufflength = len(buff)
ip_header = buff[0:20]
iph = unpack('!BBHHHBBH4s4s', ip_header)
# Variables to make it repackable
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph[5]
protocol = iph[6]
# Tcp stuff We Need this
tcp_header = buff[iph_length:iph_length+20]
print "I am about to unpack the TCP header"
#now unpack them :)
tcph = unpack('!HHLLBBHHH' , tcp_header)
print "That worked", tcph
source_port = tcph[0]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
flags = tcph[5]
h_size = iph_length + tcph_length * 4
data_size = len(buff) - h_size
data = buff[h_size:]
print "Ip Header:", iph
print "Dest", dest
d_addr = socket.inet_aton(dest)
print "Packing new Ip header"
newiph = pack('!BBHHHBBH4s4s', iph[0], iph[1], iph[2], iph[3], iph[4], iph[5], iph[6],iph[7],iph[8],d_addr)
print "Packed"
try:
packet = newiph + tcp_header + data
except Exception, e:
print e
print "Calculating new checksum"
try:
check = Filter.checksum(packet)
print "Calculated Checksum"
except Exception, e:
print "Calculation did not work"
print e
print "New TCP headers"
tcp_doff = 5
tcp_offset_res = (tcp_doff << 4) + 0
try:
newtcp_header = pack('!HHLLBBH', tcph[0], tcph[1], tcph[2],tcph[3],tcp_offset_res,tcph[5],tcph[6]) + pack('H', check) + pack('!H', tcph[8])
print "Done"
except Exception, e:
print "Tcp header creation failed"
print e
packet = newiph + newtcp_header + data
print "Passing to parser to double check the Header"
print Filter.parser(packet)
return packet