def register_decoders(self): manager = AuditManager() manager.add_decoder(NET_LAYER, LL_TYPE_IP, self.ip_decoder) manager.add_injector(0, LL_TYPE_IP, ip_injector) manager.add_injector(0, STATELESS_IP_MAGIC, stateless_ip_injector)
def register_decoders(self): manager = AuditManager() manager.add_decoder(PROTO_LAYER, NL_TYPE_UDP, self.decoder) manager.add_injector(1, NL_TYPE_UDP, self.injector)
class TCPDecoder(Plugin, PassiveAudit): def start(self, reader): self.checksum_check = True self.reassembler = None self.manager = None def stop(self): manager = AuditManager() manager.remove_decoder(PROTO_LAYER, NL_TYPE_TCP, self._process_tcp) manager.remove_injector(1, NL_TYPE_TCP, self._inject_tcp) try: manager.remove_decoder_hook(PROTO_LAYER, NL_TYPE_ICMP, self.reassembler.process_icmp, 1) except: pass def register_decoders(self): self.manager = AuditManager() conf = self.manager.get_configuration('decoder.tcp') self.checksum_check = conf['checksum_check'] self.manager.add_decoder(PROTO_LAYER, NL_TYPE_TCP, self._process_tcp) self.manager.add_injector(1, NL_TYPE_TCP, self._inject_tcp) if conf['enable_reassemble']: self.reassembler = Reassembler(conf['reassemble_workarounds'], conf['reassemble_maxstreams']) self.manager.add_decoder_hook(PROTO_LAYER, NL_TYPE_ICMP, self.reassembler.process_icmp, 1) def _inject_tcp(self, context, mpkt, length): """ Function that manages injection of fragments in active TCP connection """ ident = TCPIdent.create(mpkt) sess = SessionManager().get_session(ident) if not sess: log.debug("No TCP session found.") return False, length 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] mpkt.set_fields('tcp', { 'sport' : mpkt.l4_src, 'dport' : mpkt.l4_dst, 'dataofs' : 5, 'chksum' : None, 'urgptr' : 0, 'flags' : TH_PSH, 'options' : {}}) if status.injectable & INJ_FIN or \ not status.injectable & INJ_FWD or \ not ostatus.injectable & INJ_FWD: log.debug("Session is not injectable.") return False, length mpkt.set_fields('tcp', { 'seq' : status.last_seq + status.seq_adj, 'ack' : status.last_ack - ostatus.seq_adj}) if status.last_ack != 0: mpkt.set_field('tcp.flags', mpkt.l4_flags | TH_ACK) mpkt.session = sess.prev length += 20 + mpkt.l2_len injector = AuditManager().get_injector(0, mpkt.session.ident.magic) is_ok, length = injector(context, mpkt, length) if not is_ok: return is_ok, length length = context.get_mtu() - length if length > mpkt.inject_len: length = mpkt.inject_len payload = mpkt.inject[:length] payload_pkt = MetaPacket.new('raw') payload_pkt.set_field('raw.load', payload) mpkt.add_to('tcp', payload_pkt) status.seq_adj += length mpkt.data_len = length return True, length 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