def icmp(mpkt): if not checksum_check: return None if mpkt.get_field('ip.flags', 0) & 1: # Only a fragment return None payload = mpkt.cfields.get('reassembled_payload', None) if not payload: payload = mpkt.get_field('icmp') if not payload: return None cur_chksum = hex(unpack("!H", payload[2:4])[0]) icmpraw = payload[0:2] + '\x00\x00' + payload[4:] com_chksum = hex(checksum(icmpraw)) if com_chksum != cur_chksum: mpkt.set_cfield('good_checksum', com_chksum) manager.user_msg(_("Invalid ICMP packet from %s to %s : " \ "wrong checksum %s instead of %s") % \ (mpkt.get_field('ip.src'), \ mpkt.get_field('ip.dst'), \ cur_chksum, com_chksum), 5, 'decoder.icmp') return None
def udp(mpkt): mpkt.l4_len = UDP_LENGTH mpkt.l4_src, \ mpkt.l4_dst = mpkt.get_fields('udp', ('sport', 'dport')) load = mpkt.get_field('udp')[mpkt.l4_len:] if load: mpkt.data = load if checksum_check: udpraw = mpkt.get_field('udp') if udpraw: if mpkt.payload_len == len(udpraw): psdhdr = pack("!4s4sHH", inet_aton(mpkt.l3_src), inet_aton(mpkt.l3_dst), mpkt.l4_proto, mpkt.payload_len) chksum = checksum(psdhdr + udpraw[:6] + \ '\x00\x00' + udpraw[8:]) if mpkt.get_field('udp.chksum') != chksum: mpkt.set_cfield('good_checksum', hex(chksum)) manager.user_msg( _("Invalid UDP packet from %s to %s : " \ "wrong checksum %s instead of %s") % \ (mpkt.l3_src, mpkt.l3_dst, \ hex(mpkt.get_field('udp.chksum', 0)), \ hex(chksum)), \ 5, UDP_NAME) manager.run_decoder(APP_LAYER, PL_DEFAULT, mpkt) if mpkt.flags & MPKT_MODIFIED and \ mpkt.flags & MPKT_FORWARDABLE: mpkt.set_field('udp.chksum', None) return None
def ip(mpkt): mpkt.l3_src, \ mpkt.l3_dst, \ mpkt.l4_proto = mpkt.get_fields('ip', ('src', 'dst', 'proto')) # TODO: handle IPv6 ipraw = mpkt.get_field('ip') if not ipraw: return mpkt.l3_len = mpkt.get_field('ip.ihl') * 4 mpkt.payload_len = mpkt.get_field('ip.len') - mpkt.l3_len if mpkt.context: mpkt.context.check_forwarded(mpkt) if mpkt.flags & MPKT_FORWARDED: return None mpkt.context.set_forwardable(mpkt) iplen = min(20, len(ipraw)) if mpkt.get_field('ip.len') > len(ipraw): # Probably we are capturing with low snaplen # so the packets are not fully captured. Avoid # further calculation. return PROTO_LAYER, mpkt.l4_proto if checksum_check: ihl = max(20, mpkt.l3_len) pkt = ipraw[:10] + '\x00\x00' + ipraw[12:ihl] chksum = checksum(pkt) # Probably here it's better to set also a cfield # and to turn False the checksum_check default value if mpkt.get_field('ip.chksum') != chksum: mpkt.set_cfield('good_checksum', hex(chksum)) manager.user_msg(_("Invalid IP packet from %s to %s : " \ "wrong checksum %s instead of %s") % \ (mpkt.l3_src, mpkt.l3_dst, \ hex(mpkt.get_field('ip.chksum')), \ hex(chksum)), 5, 'decoder.ip') elif reassemble: ip_reassemble(mpkt) ident = IPIdent.create(mpkt) sess = SessionManager().get_session(ident) if not sess: sess = Session(ident) sess.data = IPStatus() SessionManager().put_session(sess) sess.prev = mpkt.session mpkt.session = sess status = sess.data status.last_id = mpkt.get_field('ip.id', 0) manager.run_decoder(PROTO_LAYER, mpkt.l4_proto, mpkt) if mpkt.flags & MPKT_DROPPED: status.id_adj -= 1 elif mpkt.flags & MPKT_MODIFIED or status.id_adj != 0: mpkt.set_field('ip.id', mpkt.get_field('ip.id', 0) + status.id_adj) mpkt.set_field('ip.len', mpkt.get_field('ip.len', 0) + mpkt.inj_delta) mpkt.set_field('ip.chksum', None)
def _process_tcp(self, mpkt): mpkt.l4_src, \ mpkt.l4_dst, \ mpkt.l4_ack, \ mpkt.l4_seq, \ mpkt.l4_flags = mpkt.get_fields('tcp', ('sport', 'dport', 'ack', \ 'seq', 'flags')) mpkt.l4_len = mpkt.get_field('tcp.dataofs', 5) * 4 if mpkt.l4_src is None: return None tcpraw = mpkt.get_field('tcp') if tcpraw: mpkt.data_len = mpkt.payload_len - mpkt.l4_len mpkt.data = tcpraw[mpkt.l4_len:] wrong = False if self.checksum_check and tcpraw: if mpkt.payload_len == len(tcpraw): ip_src = mpkt.l3_src ip_dst = mpkt.l3_dst psdhdr = pack("!4s4sHH", inet_aton(ip_src), inet_aton(ip_dst), mpkt.l4_proto, mpkt.payload_len) chksum = checksum(psdhdr + tcpraw[:16] + \ "\x00\x00" + tcpraw[18:]) if mpkt.get_field('tcp.chksum', 0) != chksum: wrong = True mpkt.set_cfield('good_checksum', hex(chksum)) self.manager.user_msg( _("Invalid TCP packet from %s to %s : " \ "wrong checksum %s instead of %s") % \ (ip_src, ip_dst, \ hex(mpkt.get_field('tcp.chksum', 0)), \ hex(chksum)), 5, 'decoder.tcp') if wrong: self.manager.run_decoder(APP_LAYER, PL_DEFAULT, mpkt) return None if self.reassembler: self.reassembler.process_tcp(mpkt) ident = TCPIdent.create(mpkt) sess = SessionManager().get_session(ident) if not sess: sess = Session(ident) sess.data = (TCPStatus(), TCPStatus()) SessionManager().put_session(sess) sess.prev = mpkt.session mpkt.session = sess if ident.l3_src == sess.ident.l3_src: status = sess.data[1] ostatus = sess.data[0] else: status = sess.data[0] ostatus = sess.data[1] status.last_seq = mpkt.l4_seq + mpkt.data_len if mpkt.l4_flags & TH_ACK: status.last_ack = mpkt.l4_ack if mpkt.l4_flags & TH_SYN: status.last_seq += 1 if mpkt.l4_flags & TH_RST: status.injectable |= INJ_FIN ostatus.injectable |= INJ_FIN if mpkt.flags & MPKT_FORWARDABLE: status.injectable |= INJ_FWD elif status.injectable & INJ_FWD: status.injectable ^= INJ_FWD self.manager.run_decoder(APP_LAYER, PL_DEFAULT, mpkt) if mpkt.l4_flags & TH_FIN: status.injectable |= INJ_FIN if mpkt.flags & MPKT_DROPPED and mpkt.flags & MPKT_FORWARDABLE: status.seq_adj += mpkt.inj_delta elif (mpkt.flags & MPKT_MODIFIED or \ status.seq_adj != 0 or ostatus != 0) and \ mpkt.flags & MPKT_FORWARDABLE: mpkt.set_field('tcp.seq', mpkt.l4_seq + status.seq_adj) mpkt.set_field('tcp.ack', mpkt.l4_ack - ostatus.seq_adj) status.seq_adj += mpkt.inj_delta mpkt.set_field('tcp.chksum', None) return None