Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def friendly_tcp_flags(flags):
'''
returns a string containing a user-friendly representation of the tcp flags
'''
# create mapping of flags to string repr's
d = {dpkt.tcp.TH_FIN:'FIN', dpkt.tcp.TH_SYN:'SYN', dpkt.tcp.TH_RST:'RST', dpkt.tcp.TH_PUSH:'PUSH', dpkt.tcp.TH_ACK:'ACK', dpkt.tcp.TH_URG:'URG', dpkt.tcp.TH_ECE:'ECE', dpkt.tcp.TH_CWR:'CWR'}
#make a list of the flags that are activated
active_flags = filter(lambda t: t[0] & flags, d.iteritems())
#join all their string representations with '|'
return '|'.join(t[1] for t in active_flags)
def _check_packet(self, packet):
"""
check tcp seq duplicates
NOTE: TX/RX duplicate happens on loopback interfaces
:param packet:
:return: None
"""
src, dst = self._parse_packet_src_dst(packet)
tcp = get_ip_packet(packet.load).data
if tcp.flags & dpkt.tcp.TH_RST:
if (src, dst) in self._last_tcp_seq:
del self._last_tcp_seq[(src, dst)]
else:
if not tcp.data: raise BadPacket("no payload")
if (src, dst) in self._last_tcp_seq:
last_seq = self._last_tcp_seq[(src, dst)]
if tcp.seq <= last_seq:
# this exception eliminates dups
raise BadPacket("This sequence(%d<=%d) seen before" % (tcp.seq, last_seq))
self._last_tcp_seq[(src, dst)] = tcp.seq
# if we are ignoring handshakes, we will track all connections,
# even if we did not see the initialization handshake.
if not conn:
conn = self.track(addr, ts=ts, state='init', **kwargs)
# align the sequence numbers when we first see a connection
if conn.nextoffset['cs'] is None and addr == conn.addr:
conn.nextoffset['cs'] = tcp.seq + 1
elif conn.nextoffset['sc'] is None and addr != conn.addr:
conn.nextoffset['sc'] = tcp.seq + 1
self.track(addr, str(tcp.data), ts,
state='established', offset=tcp.seq, **kwargs)
else:
# otherwise, only track connections if we see a TCP handshake
if (tcp.flags == dpkt.tcp.TH_SYN
or tcp.flags == dpkt.tcp.TH_SYN | dpkt.tcp.TH_CWR | dpkt.tcp.TH_ECE):
# SYN
if conn:
# if a connection already exists for the addr,
# close the old one to start fresh
self.close(conn, ts)
conn = self.track(addr, ts=ts, state='init', **kwargs)
if conn:
conn.nextoffset['cs'] = tcp.seq + 1
elif (tcp.flags == dpkt.tcp.TH_SYN | dpkt.tcp.TH_ACK
or tcp.flags == dpkt.tcp.TH_SYN | dpkt.tcp.TH_ACK | dpkt.tcp.TH_ECE):
# SYN ACK
if conn and tcp.ack == conn.nextoffset['cs']:
conn.nextoffset['sc'] = tcp.seq + 1
conn.state = 'established'
if conn and conn.state == 'established':
self.track(addr, str(tcp.data), ts,
def checkV6Reply(hdr, pkt):
eth, ip, tcp = parseTCP(pkt)
if tcp.flags & dpkt.tcp.TH_ACK:
if not tcp.flags & dpkt.tcp.TH_RST:
if not tcp.flags & dpkt.tcp.TH_SYN:
if not tcp.flags & dpkt.tcp.TH_FIN:
assembleServerHello(hdr, pkt)
ip_length = ip.len # 4
ip_src = socket.inet_ntoa(ip.src) # 5
ip_dst = socket.inet_ntoa(ip.dst) # 6
try:
proto = ip.data # Loading the content of the 'ip' into a variable 'protocol' that can be for example ICMP, TCP, and UDP.
except:
continue
if isinstance(proto, str):
continue
sport = proto.sport # 7
dport = proto.dport # 8
if ip.p == 6:
try:
tcp_flag += ("F" if (int(proto.flags & dpkt.tcp.TH_FIN) != 0) else ".") # 27
tcp_flag += ("S" if (int(proto.flags & dpkt.tcp.TH_SYN) != 0) else ".") # 26
tcp_flag += ("R" if (int(proto.flags & dpkt.tcp.TH_RST) != 0) else ".") # 25
tcp_flag += ("P" if (int(proto.flags & dpkt.tcp.TH_PUSH) != 0) else ".") # 24
tcp_flag += ("A" if (int(proto.flags & dpkt.tcp.TH_ACK) != 0) else ".") # 23
tcp_flag += ("U" if (int(proto.flags & dpkt.tcp.TH_URG) != 0) else ".") # 22
tcp_flag += ("E" if (int(proto.flags & dpkt.tcp.TH_ECE) != 0) else ".") # 21
tcp_flag += ("C" if (int(proto.flags & dpkt.tcp.TH_CWR) != 0) else ".") # 20
except:
print
"EXCEPTION TCP FLAG" if debug else next
if (proto.dport == 80) or (proto.dport == 443):
if proto.data == '':
http_request_method = ''
else:
try:
"""Daemon function used to intercept responses from the hijacked session"""
pcap_filter = 'src host %s and src port %s and dst host %s and dst port %s and tcp' % (str_dst_ip, str_dst_port, str_src_ip, str_src_port)
sock = socket(PF_PACKET, SOCK_RAW)
sock.bind((self.dev, dpkt.ethernet.ETH_TYPE_ARP))
packets = pcap.pcap(self.dev)
packets.setfilter(pcap_filter)
eth = None
for _, pkt in packets:
eth = dpkt.ethernet.Ethernet(pkt)
ip_packet = eth.data
tcp = ip_packet.data
if tcp.seq == ack:
seq = tcp.ack
if len(tcp.data) > 0:
ack += len(tcp.data)
tcp_layer = dpkt.tcp.TCP(
sport=src_port,
dport=dst_port,
seq=seq,
ack=ack)
# build ip layer
ip_layer = dpkt.ip.IP(
src=src_ip,
dst=dst_ip,
data=tcp_layer)
# build ethernet layer
eth_layer = dpkt.ethernet.Ethernet(
dst=eth.dst,
src=eth.src,
type=eth.type,
data=ip_layer)
dst_conn["seq"] = pkt.seq
src_conn["ack"] = pkt.seq + 1
dst_conn["window_scale"] = 0
# For relative sequence nums
dst_conn["seq_start"] = pkt.seq
src_conn["ack_start"] = pkt.seq
# min_payload can be overriden by write()'ing None
src_conn["min_segment_size"] = 1
src_conn["max_segment_size"] = self.DEFAULT_MSS
src_conn["payload_sizes"] = collections.Counter()
if dpkt.tcp.TCP_OPT_MSS in tcp_opts_dict:
mss_request = struct.unpack('!H', tcp_opts_dict[dpkt.tcp.TCP_OPT_MSS])
src_conn["max_segment_size"] = max(1, min(mss_request, self.MAX_MSS))
dst_conn["syn_options"][dpkt.tcp.TCP_OPT_MSS] = struct.pack("!H", src_conn["max_segment_size"])
if dpkt.tcp.TCP_OPT_WSCALE in tcp_opts_dict:
wscale = struct.unpack('!B', tcp_opts_dict[dpkt.tcp.TCP_OPT_WSCALE])
src_conn["window_scale"] = wscale
dst_conn["syn_options"][dpkt.tcp.TCP_OPT_WSCALE] = tcp_opts_dict[dpkt.tcp.TCP_OPT_WSCALE]
# A | D_sender | D_receiver | B
# ------------------------------------------------------------
# Connection setup: A sends a SYN packet
# SYN-SENT | | SYN-SENT | ; -> SYN ->
# SYN-SENT | SYN-RECV | ESTABLISHED | SYN-RECV ; SYNACK <-
# ESTABLISHED | SYN-RECV | ESTABLISHED | SYN-RECV ; <- SYNACK
print "packet %d is IPv6 but not TCP. Next header field is %d" % (packet_cntr, ip.nxt )
continue
else :
print "packet %d is neither IPv4 nor IPv6" % packet_cntr
continue # Not going to deal with anything other than IP
# At this point, we have a TCP packet, which is independent of IPv4 or IPv6 (except we need the source and destination addresses). Form a
# connection ID so we know where to store this packet.
connection_id = (ip.src, tcp.sport, ip.dst, tcp.dport)
fin_flag = ( tcp.flags & dpkt.tcp.TH_FIN ) != 0
syn_flag = ( tcp.flags & dpkt.tcp.TH_SYN ) != 0
rst_flag = ( tcp.flags & dpkt.tcp.TH_RST ) != 0
psh_flag = ( tcp.flags & dpkt.tcp.TH_PUSH) != 0
ack_flag = ( tcp.flags & dpkt.tcp.TH_ACK ) != 0
urg_flag = ( tcp.flags & dpkt.tcp.TH_URG ) != 0
ece_flag = ( tcp.flags & dpkt.tcp.TH_ECE ) != 0
cwr_flag = ( tcp.flags & dpkt.tcp.TH_CWR ) != 0
# The flags string is really for debugging
flags = (
( "C" if cwr_flag else " " ) +
( "E" if ece_flag else " " ) +
( "U" if urg_flag else " " ) +
( "A" if ack_flag else " " ) +
( "P" if psh_flag else " " ) +
( "R" if rst_flag else " " ) +
( "S" if syn_flag else " " ) +
( "F" if fin_flag else " " ) )
if syn_flag and not ack_flag :
# Each TCP connection is forming. The new connection is stored as an object in a dictionary
# whose key is the tuple (source_ip_address, source_tcp_port, destination_ip_address, destination_tcp_port)
# The connection is stored in a dictionary. The key is the connection_id, value of each key is an object with fields for the
# current connection state and the total of all the bytes that have been sent
# Note that there are two connections, one from the client to the server and one from the server to the client. This becomes
def detect_handshake(packets):
'''
Checks whether the passed list of tcp.Packet's represents a valid TCP
handshake. Returns True or False.
'''
#from dpkt.tcp import * # get TH_* constants
if len(packets) < 3:
return False
if len(packets) > 3:
log.error('too many packets for detect_handshake')
return False
syn, synack, ack = packets
fwd_seq = None
rev_seq = None
if syn.tcp.flags & dpkt.tcp.TH_SYN and not syn.tcp.flags & dpkt.tcp.TH_ACK:
# have syn
fwd_seq = syn.seq # start_seq is the seq field of the segment
if (synack.flags & dpkt.tcp.TH_SYN and
synack.flags & dpkt.tcp.TH_ACK and
synack.ack == fwd_seq + 1):
# have synack
rev_seq = synack.seq
if (ack.flags & dpkt.tcp.TH_ACK and
ack.ack == rev_seq + 1 and
ack.seq == fwd_seq + 1):
# have ack
return True
return False