Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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)
Esempio n. 4
0
    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