Changeset 5516
- Timestamp:
- 02/08/10 14:59:20 (6 months ago)
- Location:
- pm/trunk/audits/passive
- Files:
-
- 2 modified
-
ip/sources/main.py (modified) (5 diffs)
-
tcp/sources/main.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
pm/trunk/audits/passive/ip/sources/main.py
r5495 r5516 46 46 """ 47 47 48 from timeimport time48 import time 49 49 50 50 from umit.pm.core.i18n import _ … … 52 52 from umit.pm.gui.plugins.engine import Plugin 53 53 from umit.pm.manager.auditmanager import AuditManager, PassiveAudit 54 from umit.pm.manager.sessionmanager import * 54 55 from umit.pm.core.netconst import PROTO_LAYER, NET_LAYER, LL_TYPE_IP, INJ_FORWARD 55 56 from umit.pm.core.auditutils import checksum … … 67 68 reas_dict = {} 68 69 70 def ip_reassemble(mpkt): 71 # Here we have to check for fragmentation 72 # by creating a dict to holds id of ip packets 73 # and set mpkt.lock() on it if mpkg is MF 74 # until the resegmentation is done. 75 # If it's a fragment we have to return None 76 # to break the chain. 77 78 # TODO: check ip.flags standard name in UMPA 79 ts = time.time() 80 mf = mpkt.get_field('ip.flags', 0) & 1 81 frag_off = mpkt.get_field('ip.frag', 0) * 8 82 83 if not mf and frag_off == 0: 84 return False 85 86 ipid = mpkt.get_field('ip.id') 87 88 if ipid in reas_dict: 89 plist = reas_dict[ipid] 90 91 if len(plist) >= max_frags: 92 del reas_dict[ipid] 93 manager.user_msg(_('Dropping out the sequence with ID: ' 94 '%s due reassemble_max_fragments') % 95 ipid, 7, 'decoder.ip') 96 97 return False 98 99 ret = 0 100 idx = 0 101 inserted = False 102 103 while idx < len(plist): 104 ts2, frag_off2, mpkt2 = plist[idx] 105 106 if frag_off2 == frag_off: 107 plist[idx] = (ts, frag_off, mpkt.copy()) 108 break 109 elif frag_off2 < frag_off: 110 ret += frag_off2 111 idx += 1 112 continue 113 114 inserted = True 115 plist.insert(idx, (ts, frag_off, mpkt.copy())) 116 break 117 118 if not inserted: 119 plist.append((ts, frag_off, mpkt.copy())) 120 121 # Now let's get the last packet and see if MF = 0 122 # EVASION! 123 if plist[-1][-1].get_field('ip.flags') & 1 == 0: 124 125 if idx == len(plist) -1: 126 ret = frag_off - ret 127 else: 128 while idx < len(plist) - 1: 129 ts2, frag_off2, mpkt2 = plist[idx] 130 ret += frag_off2 131 idx += 1 132 133 ret = plist[-1][1] - ret 134 135 if ret == 0: 136 log.debug('Reassembling sequence with ID: %s' % \ 137 ipid) 138 139 reas_payload = '' 140 141 for ts2, frag_off2, mpkt2 in plist: 142 try: 143 ihl = mpkt2.l3_len 144 reas_payload += mpkt2.get_field('ip')[ihl:] 145 except: 146 pass 147 148 # Ok check that we have a complete payload 149 ihl = mpkt.l3_len 150 p_len = frag_off + mpkt.get_field('ip.len') - ihl 151 152 if len(reas_payload) != p_len: 153 mpkt.set_cfield('reassembled_payload', None) 154 manager.user_msg(_('Reassemble of IP packet ' \ 155 'from %s to %s failed') % \ 156 (mpkt.l3_src, mpkt.l3_dst), \ 157 4, 'decoder.ip') 158 159 # Nice drop out everythin! 160 del reas_dict[ipid] 161 162 mpkt.set_cfield('reassembled_payload', reas_payload) 163 return True 164 else: 165 if len(reas_dict) >= max_len: 166 # Ok just drop the list with the minor ts (the oldest) 167 min_k = min([(v, k) for k, v in reas_dict.items()])[1] 168 del reas_dict[min_k] 169 170 # Debug 171 manager.user_msg(_('Dropping out the oldest sequence ' 172 'with ID: %s') % min_k, 173 7, 'decoder.ip') 174 175 log.debug('First packet of the sequence with ID: %s' % ipid) 176 reas_dict[ipid] = [(ts, frag_off, mpkt)] 177 178 return False 179 69 180 def ip(mpkt): 181 mpkt.l3_src, \ 182 mpkt.l3_dst, \ 183 mpkt.l4_proto = mpkt.get_fields('ip', ('src', 'dst', 'proto')) 184 185 # TODO: handle IPv6 186 70 187 ipraw = mpkt.get_field('ip') 71 188 72 189 if not ipraw: 73 190 return 191 192 mpkt.l3_len = mpkt.get_field('ip.ihl') * 4 193 mpkt.payload_len = mpkt.get_field('ip.len') - mpkt.l3_len 194 195 if mpkt.context: 196 mpkt.context.check_forwarded(mpkt) 197 198 if mpkt.flags & MPKT_FORWARDED: 199 return None 200 201 mpkt.context.set_forwardable(mpkt) 74 202 75 203 iplen = min(20, len(ipraw)) … … 79 207 # so the packets are not fully captured. Avoid 80 208 # further calculation. 81 return PROTO_LAYER, mpkt. get_field('ip.proto')209 return PROTO_LAYER, mpkt.l4_proto 82 210 83 211 if checksum_check: 84 ihl = max(20, mpkt. get_field('ip.ihl') * 4)212 ihl = max(20, mpkt.l3_len) 85 213 pkt = ipraw[:10] + '\x00\x00' + ipraw[12:ihl] 86 214 … … 93 221 manager.user_msg(_("Invalid IP packet from %s to %s : " \ 94 222 "wrong checksum %s instead of %s") % \ 95 (mpkt.get_field('ip.src'), \ 96 mpkt.get_field('ip.dst'), \ 223 (mpkt.l3_src, mpkt.l3_dst, \ 97 224 hex(mpkt.get_field('ip.chksum')), \ 98 225 hex(chksum)), 99 226 5, 'decoder.ip') 227 100 228 elif reassemble: 101 # Here we have to check for fragmentation 102 # by creating a dict to holds id of ip packets 103 # and set mpkt.lock() on it if mpkg is MF 104 # until the resegmentation is done. 105 # If it's a fragment we have to return None 106 # to break the chain. 107 108 # TODO: check ip.flags standard name in UMPA 109 ts = time() 110 mf = mpkt.get_field('ip.flags', 0) & 1 111 frag_off = mpkt.get_field('ip.frag', 0) * 8 112 113 if not mf and frag_off == 0: 114 return PROTO_LAYER, mpkt.get_field('ip.proto') 115 116 ipid = mpkt.get_field('ip.id') 117 118 if ipid in reas_dict: 119 plist = reas_dict[ipid] 120 121 if len(plist) >= max_frags: 122 del reas_dict[ipid] 123 manager.user_msg(_('Dropping out the sequence with ID: ' 124 '%s due reassemble_max_fragments') % 125 ipid, 7, 'decoder.ip') 126 127 return PROTO_LAYER, mpkt.get_field('ip.proto') 128 129 ret = 0 130 idx = 0 131 inserted = False 132 133 while idx < len(plist): 134 ts2, frag_off2, mpkt2 = plist[idx] 135 136 if frag_off2 == frag_off: 137 plist[idx] = (ts, frag_off, mpkt.copy()) 138 break 139 elif frag_off2 < frag_off: 140 ret += frag_off2 141 idx += 1 142 continue 143 144 inserted = True 145 plist.insert(idx, (ts, frag_off, mpkt.copy())) 146 break 147 148 if not inserted: 149 plist.append((ts, frag_off, mpkt.copy())) 150 151 # Now let's get the last packet and see if MF = 0 152 # EVASION! 153 if plist[-1][-1].get_field('ip.flags') & 1 == 0: 154 155 if idx == len(plist) -1: 156 ret = frag_off - ret 157 else: 158 while idx < len(plist) - 1: 159 ts2, frag_off2, mpkt2 = plist[idx] 160 ret += frag_off2 161 idx += 1 162 163 ret = plist[-1][1] - ret 164 165 if ret == 0: 166 log.debug('Reassembling sequence with ID: %s' % \ 167 ipid) 168 169 reas_payload = '' 170 171 for ts2, frag_off2, mpkt2 in plist: 172 try: 173 ihl = mpkt2.get_field('ip.ihl') * 4 174 reas_payload += mpkt2.get_field('ip')[ihl:] 175 except: 176 pass 177 178 # Ok check that we have a complete payload 179 ihl = mpkt.get_field('ip.ihl') * 4 180 p_len = frag_off + mpkt.get_field('ip.len') - ihl 181 182 if len(reas_payload) != p_len: 183 mpkt.set_cfield('reassembled_payload', None) 184 manager.user_msg(_('Reassemble of IP packet ' \ 185 'from %s to %s failed') % \ 186 (mpkt.get_field('ip.src'), 187 mpkt.get_field('ip.dst')), 188 4, 'decoder.ip') 189 190 # Nice drop out everythin! 191 del reas_dict[ipid] 192 193 mpkt.set_cfield('reassembled_payload', reas_payload) 194 else: 195 if len(reas_dict) >= max_len: 196 # Ok just drop the list with the minor ts (the oldest) 197 min_k = min([(v, k) for k, v in reas_dict.items()])[1] 198 del reas_dict[min_k] 199 200 # Debug 201 manager.user_msg(_('Dropping out the oldest sequence ' 202 'with ID: %s') % min_k, 203 7, 'decoder.ip') 204 205 log.debug('First packet of the sequence with ID: %s' % ipid) 206 reas_dict[ipid] = [(ts, frag_off, mpkt)] 207 208 return PROTO_LAYER, mpkt.get_field('ip.proto') 229 ip_reassemble(mpkt) 230 231 ident = IPIdent.create(mpkt) 232 sess = SessionManager().get_session(ident) 233 234 if not sess: 235 sess = Session(ident) 236 sess.data = IPStatus() 237 SessionManager().put_session(sess) 238 239 sess.prev = mpkt.session 240 mpkt.session = sess 241 242 status = sess.data 243 status.last_id = mpkt.get_field('ip.id', 0) 244 245 manager.run_decoder(PROTO_LAYER, mpkt.l4_proto, mpkt) 246 247 if mpkt.flags & MPKT_DROPPED: 248 status.id_adj -= 1 249 elif mpkt.flags & MPKT_MODIFIED or status.id_adj != 0: 250 mpkt.set_field('ip.id', mpkt.get_field('ip.id', 0) + status.id_adj) 251 mpkt.set_field('ip.len', mpkt.get_field('ip.len', 0) + mpkt.inj_delta) 252 mpkt.set_field('ip.chksum', None) 209 253 210 254 return ip 211 255 212 def ip_injector(context, mpkt): 213 pkt = MetaPacket.new('ip') 214 215 if mpkt.cfields.get('inj::payload', None): 216 pkt.set_field('ip.src', mpkt.get_field('ip.src')) 217 pkt.set_field('ip.dst', mpkt.get_field('ip.dst')) 218 219 # DEBUG: remove me after finished. Only used to track 220 # IP packets 221 pkt.set_field('ip.id', 666) 222 223 mpkt.set_cfield('inj::data', pkt) 224 else: 225 mpkt.reset_field('ip.chksum') 226 227 return INJ_FORWARD 256 def ip_injector(context, mpkt, length): 257 if length + 20 > context.get_mtu(): 258 return False, length 259 260 sess = mpkt.session 261 status = sess.data 262 263 mpkt.set_fields('ip', { 264 'ihl' : 5, 265 'version' : 4, 266 'tos' : 0, 267 'chksum' : None, 268 #'len' : None, 269 'flags' : 0, 270 'frag' : 0, 271 'ttl' : 125, 272 'proto' : mpkt.l4_proto, 273 'src' : mpkt.l3_src, 274 'dst' : mpkt.l3_dst, 275 'id' : status.last_id + status.id_adj + 1}) 276 277 if not SessionManager().get_session(sess.ident): 278 return False, length 279 280 length += 20 281 further_len = length 282 283 # TODO: support encapsulated packets 284 285 status.id_adj += 1 286 287 payload_len = context.get_mtu() - length 288 289 if payload_len > mpkt.inject_len: 290 payload_len = mpkt.inject_len 291 292 tlen = further_len + payload_len - mpkt.l2_len 293 mpkt.set_field('ip.len', tlen) 294 295 mpkt.set_data_len(payload_len) 296 297 return True, length 228 298 229 299 class IPDecoder(Plugin, PassiveAudit): -
pm/trunk/audits/passive/tcp/sources/main.py
r5506 r5516 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 2008 Adriano Monteiro Marques3 # Copyright (C) 2008, 2010 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 20 20 21 21 """ 22 TCP protocol d issector22 TCP protocol decoder 23 23 24 24 >>> from umit.pm.core.auditutils import audit_unittest … … 38 38 from umit.pm.core.atoms import defaultdict 39 39 from umit.pm.gui.plugins.engine import Plugin 40 from umit.pm.manager.sessionmanager import * 40 41 from umit.pm.manager.auditmanager import AuditManager, PassiveAudit 41 42 from umit.pm.core.netconst import * … … 241 242 if iplen < 20: 242 243 return 243 ipsrc, ipdst = inet_aton(mpkt. get_field('ip.src')), \244 inet_aton(mpkt. get_field('ip.dst'))244 ipsrc, ipdst = inet_aton(mpkt.l3_src), \ 245 inet_aton(mpkt.l3_dst) 245 246 246 247 # Proto or port unreach … … 286 287 return 287 288 288 ipsrc, ipdst = inet_aton(mpkt. get_field('ip.src')),\289 inet_aton(mpkt. get_field('ip.dst'))289 ipsrc, ipdst = inet_aton(mpkt.l3_src), \ 290 inet_aton(mpkt.l3_dst) 290 291 291 292 if ipsrc == '\x00\x00\x00\x00' and \ … … 681 682 @param mpkt a MetaPacket object 682 683 """ 683 ctup = (inet_aton(mpkt. get_field('ip.src')),684 inet_aton(mpkt. get_field('ip.dst')),685 mpkt. get_field('tcp.sport'), mpkt.get_field('tcp.dport'))684 ctup = (inet_aton(mpkt.l3_src), 685 inet_aton(mpkt.l3_dst), 686 mpkt.l4_src, mpkt.l4_dst) 686 687 687 688 hash_idx = ':'.join(ctup[0:2]) … … 743 744 # First look for client side streams 744 745 745 ctup = (inet_aton(mpkt. get_field('ip.src')),746 inet_aton(mpkt. get_field('ip.dst')),747 mpkt. get_field('tcp.sport'), mpkt.get_field('tcp.dport'))746 ctup = (inet_aton(mpkt.l3_src), 747 inet_aton(mpkt.l3_dst), 748 mpkt.l4_src, mpkt.l4_dst) 748 749 749 750 tcp_stream = self.find_tcp_stream(ctup) … … 879 880 def start(self, reader): 880 881 self.checksum_check = True 881 self.dissectors = True882 882 self.reassembler = None 883 883 self.manager = None … … 899 899 900 900 self.checksum_check = conf['checksum_check'] 901 self.dissectors = conf['enable_dissectors']902 901 903 902 self.manager.add_decoder(PROTO_LAYER, NL_TYPE_TCP, self._process_tcp) 903 self.manager.add_injector(1, NL_TYPE_TCP, self._inject_tcp) 904 904 905 905 if conf['enable_reassemble']: … … 908 908 self.manager.add_decoder_hook(PROTO_LAYER, NL_TYPE_ICMP, 909 909 self.reassembler.process_icmp, 1) 910 self.manager.add_injector(1, NL_TYPE_TCP, self._inject_tcp) 911 912 def _inject_tcp(self, context, mpkt): 910 911 def _inject_tcp(self, context, mpkt, length): 913 912 """ 914 913 Function that manages injection of fragments in active TCP connection 915 914 """ 916 915 917 ret = INJ_FORWARD 918 stream, orcv = mpkt.cfields.get('inj::data', (None, None)) 919 920 if not stream: 921 log.debug('Last packet of the chain. Exiting') 922 return INJ_FORWARD 923 924 rcv = (stream.client is orcv) and (stream.server) or (stream.client) 925 926 if not stream: 927 raise Exception('inj::data key not present') 928 929 if stream.state == CONN_UNDEFINED: 930 log.error('The data can\'t be injected in a UNDEFINED stream') 931 return INJ_ERROR 932 933 injector = AuditManager().get_injector(0, LL_TYPE_IP) 934 935 if injector(context, mpkt) == INJ_ERROR: 936 log.error('Error in underlayer injector') 937 return INJ_ERROR 938 939 payload = mpkt.cfields.get('inj::payload', None) 940 941 if not payload: 942 # Here we have only to adjust the sequence 943 # or check for dropped packet. If flags is dropped just increase 944 # the seq_adj and return True 945 946 if mpkt.get_field('tcp.seq') == rcv.seq + rcv.seq_adj: 947 log.debug('This is the injected packet skipping it') 948 949 ret = INJ_SKIP_PACKET 950 mpkt.unset_cfield('inj::data') 951 952 else: 953 cseq = mpkt.get_field('tcp.seq') 954 cack = mpkt.get_field('tcp.ack') 955 956 log.debug('Adjusting sequence for TCP packet') 957 log.debug('TCP sequence %d + %d = %d', cseq, rcv.seq_adj, 958 rcv.seq_adj + cseq) 959 log.debug('TCP ack %d - %d = %d', cack, orcv.seq_adj, 960 cack - orcv.seq_adj) 961 log.debug('Resetting TCP checksum') 962 963 mpkt.set_field('tcp.seq', cseq + rcv.seq_adj) 964 mpkt.set_field('tcp.ack', cack - orcv.seq_adj) 965 mpkt.reset_field('tcp.chksum') 966 mpkt.unset_cfield('inj::data') 967 916 ident = TCPIdent.create(mpkt) 917 sess = SessionManager().get_session(ident) 918 919 if not sess: 920 log.debug("No TCP session found.") 921 return False, length 922 923 if ident.l3_src == sess.ident.l3_src: 924 status = sess.data[1] 925 ostatus = sess.data[0] 968 926 else: 969 970 if rcv.seq_adj == 0 and orcv.seq_adj == 0: 971 972 ret = INJ_SKIP_PACKET 973 log.error('The packet seems to be OK as is. ' 974 'This is the first packet') 975 976 elif mpkt.get_field('tcp.seq') == rcv.seq + rcv.seq_adj: 977 978 ret = INJ_SKIP_PACKET 979 log.debug('No adjustments needed. SEQ & ACK are ok') 980 981 else: 982 cseq = mpkt.get_field('tcp.seq') 983 cack = mpkt.get_field('tcp.ack') 984 985 log.debug('Adjusting current TCP packet') 986 log.debug('TCP sequence %d + %d = %d', cseq, rcv.seq_adj, 987 rcv.seq_adj + cseq) 988 log.debug('TCP ack %d - %d = %d', cack, orcv.seq_adj, 989 cack - orcv.seq_adj) 990 log.debug('Resetting TCP checksum') 991 992 mpkt.set_field('tcp.seq', cseq + rcv.seq_adj) 993 mpkt.set_field('tcp.ack', cack - orcv.seq_adj) 994 mpkt.reset_field('tcp.chksum') 995 996 plen = len(payload) 997 pkt = mpkt.cfields.get('inj::data', None) 998 999 if not pkt: 1000 log.error('The underlayer injector returns None as mpkt') 1001 return INJ_ERROR 1002 1003 mtu = context.get_mtu() - pkt.get_size() 1004 1005 if plen > mtu: 1006 plen = mtu 1007 1008 prev_len = len(mpkt.get_field('tcp')) - \ 1009 mpkt.get_field('tcp.dataofs') * 4 1010 1011 nseq = mpkt.get_field('tcp.seq') + prev_len 1012 nack = mpkt.get_field('tcp.ack') 1013 1014 pkt = pkt / MetaPacket.new('tcp') / MetaPacket.new('raw') 1015 pkt.set_field('tcp.sport', mpkt.get_field('tcp.sport')) 1016 pkt.set_field('tcp.dport', mpkt.get_field('tcp.dport')) 1017 pkt.set_field('tcp.flags', TH_PSH) 1018 pkt.set_field('tcp.seq', nseq) 1019 pkt.set_field('tcp.ack', nack) 1020 1021 log.debug('Forging new TCP + Raw packet (appended to %s)' % pkt) 1022 log.debug('TCP seq: %d' % nseq) 1023 log.debug('TCP ack: %d' % nack) 1024 1025 if rcv.ack_seq != 0: 1026 pkt.set_field('tcp.flags', TH_PSH | TH_ACK) 1027 1028 pkt.set_field('raw.load', payload[:plen]) 1029 1030 remaining = payload[plen:] 1031 1032 # Adjusting seq_adj 1033 cur_len = len(mpkt.get_field('tcp')) - \ 1034 mpkt.get_field('tcp.dataofs') * 4 1035 1036 rcv.seq_adj += cur_len 1037 1038 log.debug('Current packet has a payload with length = %d. ' 1039 'seq_adj become: %d' % (cur_len, rcv.seq_adj)) 1040 1041 1042 if remaining: 1043 pkt.set_cfield('inj::data', (stream, orcv)) 1044 pkt.set_cfield('inj::payload', remaining) 1045 1046 mpkt.set_cfield('inj::data', pkt) 1047 mpkt.unset_cfield('inj::payload') 1048 1049 mpkt.unset_cfield('inj::flags') 1050 mpkt.unset_cfield('inj::l4proto') 1051 1052 return ret 927 status = sess.data[0] 928 ostatus = sess.data[1] 929 930 mpkt.set_fields('tcp', { 931 'sport' : mpkt.l4_src, 932 'dport' : mpkt.l4_dst, 933 'dataofs' : 5, 934 'chksum' : None, 935 'urgptr' : 0, 936 'flags' : TH_PSH, 937 'options' : {}}) 938 939 if status.injectable & INJ_FIN or \ 940 not status.injectable & INJ_FWD or \ 941 not ostatus.injectable & INJ_FWD: 942 log.debug("Session is not injectable.") 943 return False, length 944 945 mpkt.set_fields('tcp', { 946 'seq' : status.last_seq + status.seq_adj, 947 'ack' : status.last_ack - ostatus.seq_adj}) 948 949 if status.last_ack != 0: 950 mpkt.set_field('tcp.flags', mpkt.l4_flags | TH_ACK) 951 952 mpkt.session = sess.prev 953 length += 20 + mpkt.l2_len 954 955 injector = AuditManager().get_injector(0, mpkt.session.ident.magic) 956 is_ok, length = injector(context, mpkt, length) 957 958 if not is_ok: 959 return is_ok, length 960 961 length = context.get_mtu() - length 962 963 if length > mpkt.inject_len: 964 length = mpkt.inject_len 965 966 payload = mpkt.inject[:length] 967 payload_pkt = MetaPacket.new('raw') 968 payload_pkt.set_field('raw.load', payload) 969 mpkt.add_to('tcp', payload_pkt) 970 971 status.seq_adj += length 972 mpkt.data_len = length 973 974 return True, length 1053 975 1054 976 def _process_tcp(self, mpkt): 1055 if self.checksum_check: 1056 # TODO: Handle IPv6 here 1057 tcpraw = mpkt.get_field('tcp') 1058 1059 if tcpraw: 1060 ln = mpkt.get_field('ip.len') - 20 1061 1062 if ln == len(tcpraw): 1063 ip_src = mpkt.get_field('ip.src') 1064 ip_dst = mpkt.get_field('ip.dst') 1065 1066 psdhdr = pack("!4s4sHH", 1067 inet_aton(ip_src), 1068 inet_aton(ip_dst), 1069 mpkt.get_field('ip.proto'), 1070 ln) 1071 1072 chksum = checksum(psdhdr + tcpraw[:16] + \ 1073 "\x00\x00" + tcpraw[18:]) 1074 1075 if mpkt.get_field('tcp.chksum', 0) != chksum: 1076 mpkt.set_cfield('good_checksum', hex(chksum)) 1077 self.manager.user_msg( 1078 _("Invalid TCP packet from %s to %s : " \ 1079 "wrong checksum %s instead of %s") % \ 1080 (ip_src, ip_dst, \ 1081 hex(mpkt.get_field('tcp.chksum', 0)), \ 1082 hex(chksum)), 1083 5, 'decoder.tcp') 1084 elif self.reassembler: 1085 self.reassembler.process_tcp(mpkt) 1086 1087 if not self.dissectors: 1088 return None 1089 1090 ret = self.manager.run_decoder(APP_LAYER_TCP, 1091 mpkt.get_field('tcp.dport'), mpkt) 1092 1093 ret = max(ret, self.manager.run_decoder(APP_LAYER_TCP, 1094 mpkt.get_field('tcp.sport'), mpkt)) 977 mpkt.l4_src, \ 978 mpkt.l4_dst, \ 979 mpkt.l4_ack, \ 980 mpkt.l4_seq, \ 981 mpkt.l4_flags = mpkt.get_fields('tcp', ('sport', 'dport', 'ack', \ 982 'seq', 'flags')) 983 mpkt.l4_len = mpkt.get_field('tcp.dataofs', 5) * 4 984 985 tcpraw = mpkt.get_field('tcp') 986 987 if tcpraw: 988 mpkt.data_len = mpkt.payload_len - mpkt.l4_len 989 mpkt.data = tcpraw[mpkt.l4_len:] 990 991 if self.checksum_check and tcpraw: 992 ln = mpkt.get_field('ip.len') - 20 993 994 if ln == len(tcpraw): 995 ip_src = mpkt.l3_src 996 ip_dst = mpkt.l3_dst 997 998 psdhdr = pack("!4s4sHH", 999 inet_aton(ip_src), 1000 inet_aton(ip_dst), 1001 mpkt.l4_proto, 1002 ln) 1003 1004 chksum = checksum(psdhdr + tcpraw[:16] + \ 1005 "\x00\x00" + tcpraw[18:]) 1006 1007 if mpkt.get_field('tcp.chksum', 0) != chksum: 1008 mpkt.set_cfield('good_checksum', hex(chksum)) 1009 self.manager.user_msg( 1010 _("Invalid TCP packet from %s to %s : " \ 1011 "wrong checksum %s instead of %s") % \ 1012 (ip_src, ip_dst, \ 1013 hex(mpkt.get_field('tcp.chksum', 0)), \ 1014 hex(chksum)), 1015 5, 'decoder.tcp') 1016 elif self.reassembler: 1017 self.reassembler.process_tcp(mpkt) 1018 1019 ident = TCPIdent.create(mpkt) 1020 sess = SessionManager().get_session(ident) 1021 1022 if not sess: 1023 sess = Session(ident) 1024 sess.data = (TCPStatus(), TCPStatus()) 1025 SessionManager().put_session(sess) 1026 1027 sess.prev = mpkt.session 1028 mpkt.session = sess 1029 1030 if ident.l3_src == sess.ident.l3_src: 1031 status = sess.data[1] 1032 ostatus = sess.data[0] 1033 else: 1034 status = sess.data[0] 1035 ostatus = sess.data[1] 1036 1037 status.last_seq = mpkt.l4_seq + mpkt.data_len 1038 1039 if mpkt.l4_flags & TH_ACK: 1040 status.last_ack = mpkt.l4_ack 1041 1042 if mpkt.l4_flags & TH_SYN: 1043 status.last_seq += 1 1044 1045 if mpkt.l4_flags & TH_RST: 1046 status.injectable |= INJ_FIN 1047 ostatus.injectable |= INJ_FIN 1048 1049 if mpkt.flags & MPKT_FORWARDABLE: 1050 status.injectable |= INJ_FWD 1051 elif status.injectable & INJ_FWD: 1052 status.injectable ^= INJ_FWD 1053 1054 self.manager.run_decoder(APP_LAYER, PL_DEFAULT, mpkt) 1055 1056 if mpkt.l4_flags & TH_FIN: 1057 status.injectable |= INJ_FIN 1058 1059 if mpkt.flags & MPKT_DROPPED and mpkt.flags & MPKT_FORWARDABLE: 1060 status.seq_adj += mpkt.inj_delta 1061 elif (mpkt.flags & MPKT_MODIFIED or \ 1062 status.seq_adj != 0 or ostatus != 0) and \ 1063 mpkt.flags & MPKT_FORWARDABLE: 1064 1065 mpkt.set_field('tcp.seq', mpkt.l4_seq + status.seq_adj) 1066 mpkt.set_field('tcp.ack', mpkt.l4_ack - ostatus.seq_adj) 1067 1068 status.seq_adj += mpkt.inj_delta 1069 1070 mpkt.set_field('tcp.chksum', None) 1095 1071 1096 1072 return None … … 1105 1081 ('decoder.tcp', { 1106 1082 'checksum_check' : [True, 'Cheksum check for TCP segments'], 1107 'enable_dissectors' : [True, 'Enable TCP protocol dissectors'],1108 1083 'enable_reassemble' : [True, 'Enable userland python implementation of ' 1109 1084 'TCP/IP stack to tracks TCP streams connection. '
