Пример #1
0
    def __main_thread(self, server, targets):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)

        if ':' in server:
            server, port = server.split(':', 1)
        else:
            port = 53

        try:
            port = int(port)
        except:
            port = 53

        sock.connect((server, port))

        for target in targets:
            dnsqr = MetaPacket.new('dnsqr')
            dnsqr.set_field('dnsqr.qname', target)

            mpkt = MetaPacket.new('dns')
            mpkt.set_fields('dns', {
                'id' : randint(0, 2L**16-1),
                'qd' : dnsqr})

            sock.send(mpkt.get_raw())
Пример #2
0
    def send_redirect(self, sip, dip):
        key = sip + ':' + dip

        delay = self.connections.get(key, None)

        if delay and (time.time() - delay) <= self.delay:
            return

        self.connections[key] = time.time()

        pkt = MetaPacket.new('ip') / MetaPacket.new('icmp')

        pkt.set_field('ip.src', self.gateway)
        pkt.set_field('ip.dst', dip)

        pkt.set_field('icmp.type', 5)  # Redirect
        pkt.set_field('icmp.code', 0)  # Redirect for network
        pkt.set_field('icmp.gw', self.source)

        self.packets += 1
        self.session.context.si_l3(pkt)

        self.session.output_page.user_msg(
            _('%s to %s matches - redirect to %s') % (sip, dip, self.source),
            STATUS_INFO, AUDIT_NAME)

        self.summary = AUDIT_MSG % (_('%d redirects sent') % self.packets)
        self.percentage = (self.percentage + 536870911) % \
                          gobject.G_MAXINT
Пример #3
0
    def send_redirect(self, sip, dip):
        key = sip + ':' + dip

        delay = self.connections.get(key, None)

        if delay and (time.time() - delay) <= self.delay:
            return

        self.connections[key] = time.time()

        pkt = MetaPacket.new('ip') / MetaPacket.new('icmp')

        pkt.set_field('ip.src', self.gateway)
        pkt.set_field('ip.dst', dip)

        pkt.set_field('icmp.type', 5) # Redirect
        pkt.set_field('icmp.code', 0) # Redirect for network
        pkt.set_field('icmp.gw', self.source)

        self.packets += 1
        self.session.context.si_l3(pkt)

        self.session.output_page.user_msg(
            _('%s to %s matches - redirect to %s') % (sip, dip, self.source),
            STATUS_INFO, AUDIT_NAME)

        self.summary = AUDIT_MSG % (_('%d redirects sent') % self.packets)
        self.percentage = (self.percentage + 536870911) % \
                          gobject.G_MAXINT
Пример #4
0
    def __thread_main(self):
        try:
            log.debug('Entered in __thread_main')

            packets = 0
            probes = self.probes

            while probes != 0 and self.internal:
                pkt = MetaPacket.new('ip') / MetaPacket.new('tcp')

                if self.sip is True:
                    sip = random_ip()
                elif self.sip != '0.0.0.0':
                    sip = self.sip

                if self.sport is True:
                    sport = randint(1, 65535)
                else:
                    sport = self.sport

                pkt.set_fields('ip', {'dst': self.dip, 'src': sip})

                pkt.set_fields(
                    'tcp', {
                        'sport': sport,
                        'dport': self.dport,
                        'flags': TH_SYN,
                        'seq': randint(0, 2L**32 - 1)
                    })

                self.context.si_l3(pkt)
                sleep(self.delay)

                probes -= 1
                packets += 1

                if self.probes > 0:
                    self.summary = AUDIT_MSG % _('%d of %d sent' \
                                   % (packets, self.probes))
                    self.percentage = (packets / float(self.probes)) * 100.0
                else:
                    self.summary = AUDIT_MSG % _('%d sent' % packets)
                    self.percentage = (self.percentage + 536870911) % \
                                      gobject.G_MAXINT

            if self.internal:
                self.summary = AUDIT_MSG % _('Finished with %d sent' % packets)
                self.internal = False
            else:
                self.summary = AUDIT_MSG % _('stopped')

            self.percentage = 100.0
            self.state = self.NOT_RUNNING

        except Exception, err:
            log.error(generate_traceback())
Пример #5
0
    def __thread_main(self):
        try:
            log.debug('Entered in __thread_main')

            packets = 0
            probes = self.probes

            while probes != 0 and self.internal:
                pkt = MetaPacket.new('ip') / MetaPacket.new('tcp')

                if self.sip is True:
                    sip = random_ip()
                elif self.sip != '0.0.0.0':
                    sip = self.sip

                if self.sport is True:
                    sport = randint(1, 65535)
                else:
                    sport = self.sport

                pkt.set_fields('ip', {
                    'dst' : self.dip,
                    'src' : sip})

                pkt.set_fields('tcp', {
                    'sport' : sport,
                    'dport' : self.dport,
                    'flags' : TH_SYN,
                    'seq' : randint(0, 2L**32-1)})

                self.context.si_l3(pkt)
                sleep(self.delay)

                probes -= 1
                packets += 1

                if self.probes > 0:
                    self.summary = AUDIT_MSG % _('%d of %d sent' \
                                   % (packets, self.probes))
                    self.percentage = (packets / float(self.probes)) * 100.0
                else:
                    self.summary = AUDIT_MSG % _('%d sent' % packets)
                    self.percentage = (self.percentage + 536870911) % \
                                      gobject.G_MAXINT

            if self.internal:
                self.summary = AUDIT_MSG % _('Finished with %d sent' % packets)
                self.internal = False
            else:
                self.summary = AUDIT_MSG % _('stopped')

            self.percentage = 100.0
            self.state = self.NOT_RUNNING

        except Exception, err:
            log.error(generate_traceback())
Пример #6
0
def send_tcpkill(ctx, src, dst, sport, dport, seq):
    mpkt = MetaPacket.new('ip') / MetaPacket.new('tcp')

    mpkt.set_fields('ip', {'src': src, 'dst': dst})

    mpkt.set_fields('tcp', {
        'sport': sport,
        'dport': dport,
        'seq': seq,
        'ack': 0,
        'flags': TH_RST
    })

    ctx.si_l3(mpkt)
Пример #7
0
    def send_dhcp(self, sip, dip, dmac, bootpkt):
        mpkt = MetaPacket.new('eth') / \
               MetaPacket.new('ip')  / \
               MetaPacket.new('udp') / bootpkt

        mpkt.set_field('eth.dst', dmac)
        mpkt.set_field('ip.src', sip)
        mpkt.set_field('ip.dst', dip)
        mpkt.set_field('udp.sport', 67)
        mpkt.set_field('udp.dport', 68)

        self.percentage = (self.percentage + 536870911) % \
                          gobject.G_MAXINT

        self.session.context.si_l2(mpkt)
Пример #8
0
def send_tcpkill(ctx, src, dst, sport, dport, seq):
    mpkt = MetaPacket.new('ip') / MetaPacket.new('tcp')

    mpkt.set_fields('ip', {
        'src' : src,
        'dst' : dst})

    mpkt.set_fields('tcp', {
        'sport' : sport,
        'dport' : dport,
        'seq' : seq,
        'ack' : 0,
        'flags' : TH_RST})

    ctx.si_l3(mpkt)
Пример #9
0
    def __on_discover(self, mpkt):
        values = self.get_values(mpkt)

        spoof = MetaPacket.new_from_layer(mpkt, 'bootp')
        spoof.set_field('bootp.op', BOOTP_REPLY)

        try:
            client_ip = self.pool_iter.next()
        except StopIteration:
            log.debug('No available IP address')
            return

        spoof.set_field('bootp.yiaddr', client_ip)
        spoof.set_field('bootp.siaddr', self.session.context.get_ip1())

        options = self.setup_options(values).items()
        options.append(('message-type', 'offer'))
        options.append('end')

        spoof.set_field('dhcp.options', options)

        self.send_dhcp(
            self.session.context.get_ip1(),
            mpkt.l3_src != '0.0.0.0' and mpkt.l3_src or '255.255.255.255',
            mpkt.l2_src, spoof)
Пример #10
0
    def __ping_thread(self):
        # TODO: maybe will be better to use IPy or something
        #       like that to handle also IPv6

        ip = unpack('!I', inet_aton(self.ip))[0]
        nm = unpack('!I', inet_aton(self.netmask))[0]
        last = unpack('!I', '\xff\xff\xff\xff')[0]

        start = ip & nm
        end = (last ^ nm) | ip

        sent = 0
        totals = float(end - start)

        # NB: With this method we ping also broadcast and reserved
        # addresses

        pkt = MetaPacket.new('eth') / MetaPacket.new('arp')
        pkt.set_field('eth.src', self.sess.context.get_mac1())
        pkt.set_field('eth.dst', 'ff:ff:ff:ff:ff:ff')
        pkt.set_field('arp.hwsrc', self.sess.context.get_mac1())
        pkt.set_field('arp.hwdst', '00:00:00:00:00:00')
        pkt.set_field('arp.psrc', self.sess.context.get_ip1())

        while self.internal and start <= end:
            pkt.set_field('arp.pdst', inet_ntoa(pack('!I', start)))
            self.sess.context.si_l2(pkt)
            time.sleep(0.01)
            self.percentage = (sent / totals) * 100.0
            start += 1
            sent += 1

        if not self.internal:
            self.summary = AUDIT_MSG % _('stopped')
            self.sess.output_page.user_msg(
                _('Scanning for hosts on iface %s with IP: %s and Netmask: %s stopped') \
                % (self.iface, self.ip, self.netmask), STATUS_WARNING, AUDIT_NAME)
        else:
            self.summary = AUDIT_MSG % _('finished')
            self.sess.output_page.user_msg(
                _('Scanning for hosts on iface %s with IP: %s and Netmask: %s finished') \
                % (self.iface, self.ip, self.netmask), STATUS_INFO, AUDIT_NAME)

        self.internal = False
        self.state = self.NOT_RUNNING
        self.percentage = 100.0
Пример #11
0
    def send_icmp_echo(self, ctx, sip, dip, smac, dmac):
        mpkt = MetaPacket.new('eth') / \
             MetaPacket.new('ip') /    \
             MetaPacket.new('icmp') /  \
             MetaPacket.new('raw')

        mpkt.set_field('eth.dst', dmac)
        mpkt.set_field('eth.src', smac)
        mpkt.set_field('ip.src', sip)
        mpkt.set_field('ip.dst', dip)
        mpkt.set_field('raw.load', ping_payload)

        #log.info(mpkt.summary())
        #log.info('Sending ICMP echo (%s -> %s) [%s -> %s]' % (
        #    sip, dip, smac, dmac))

        ctx.si_l2(mpkt)
Пример #12
0
    def send_arp(self, ctx, type, sip, smac, dip, dmac):
        mpkt = MetaPacket.new('eth') / MetaPacket.new('arp')
        mpkt.set_field('eth.dst', dmac)

        if type == ARP_REQUEST:
            dmac = '00:00:00:00:00:00'

        mpkt.set_field('arp.op', type)
        mpkt.set_field('arp.hwsrc', smac)
        mpkt.set_field('arp.hwdst', dmac)
        mpkt.set_field('arp.psrc', sip)
        mpkt.set_field('arp.pdst', dip)

        #log.info(mpkt.summary())
        #log.info('Sending %s (%s -> %s) [%s -> %s]' % (
        #    type == ARP_REQUEST and 'who-has' or 'is-at',
        #    sip, dip, smac, dmac))

        ctx.si_l2(mpkt)
Пример #13
0
def inject_buffer(ctx, conn, index, buff):
    if conn.l4_proto == NL_TYPE_TCP:
        proto = 'tcp'
    elif conn.l4_proto == NL_TYPE_UDP:
        proto = 'udp'
    else:
        return False

    mpkt = MetaPacket.new('ip') / MetaPacket.new(proto)

    if index == 0:
        mpkt.l3_src = conn.l3_addr1
        mpkt.l3_dst = conn.l3_addr2

        mpkt.l4_src = conn.l4_addr1
        mpkt.l4_dst = conn.l4_addr2
    else:
        mpkt.l3_src = conn.l3_addr2
        mpkt.l3_dst = conn.l3_addr1

        mpkt.l4_src = conn.l4_addr2
        mpkt.l4_dst = conn.l4_addr1

    mpkt.l4_proto = conn.l4_proto

    mpkt.set_fields('ip', {
        'src' : mpkt.l3_src,
        'dst' : mpkt.l3_dst})
    mpkt.set_fields(proto, {
        'sport' : mpkt.l4_src,
        'dport' : mpkt.l4_dst})

    mpkt.inject = buff
    mpkt.inject_len = len(buff)

    index += 2
    conn.flags = CN_INJECTED
    conn.buffers.append((index, buff))

    ctx.inject_buffer(mpkt)

    return True
Пример #14
0
    def poison(self, sess, host, target, hwsrc, hwdst, packets, delay):
        pkt = MetaPacket.new('eth') / MetaPacket.new('arp')

        if hwdst:
            pkt.set_field('eth.dst', hwdst)
            pkt.set_field('arp.hwdst', hwdst)
        else:
            pkt.set_field('arp.hwdst', 'ff:ff:ff:ff:ff:ff')

        pkt.set_field('arp.op', 'is-at')
        pkt.set_field('arp.psrc', host)
        pkt.set_field('arp.pdst', target)

        if hwsrc:
            pkt.set_field('arp.hwsrc', hwsrc)

        self.status.info(_('Starting ARP cache poison against %s '
                           '(capturing packets directed to %s)') % (target, host))

        send = sess.context.s_l2(pkt, repeat=packets, delay=delay)
Пример #15
0
def inject_buffer(ctx, conn, index, buff):
    if conn.l4_proto == NL_TYPE_TCP:
        proto = 'tcp'
    elif conn.l4_proto == NL_TYPE_UDP:
        proto = 'udp'
    else:
        return False

    mpkt = MetaPacket.new('ip') / MetaPacket.new(proto)

    if index == 0:
        mpkt.l3_src = conn.l3_addr1
        mpkt.l3_dst = conn.l3_addr2

        mpkt.l4_src = conn.l4_addr1
        mpkt.l4_dst = conn.l4_addr2
    else:
        mpkt.l3_src = conn.l3_addr2
        mpkt.l3_dst = conn.l3_addr1

        mpkt.l4_src = conn.l4_addr2
        mpkt.l4_dst = conn.l4_addr1

    mpkt.l4_proto = conn.l4_proto

    mpkt.set_fields('ip', {'src': mpkt.l3_src, 'dst': mpkt.l3_dst})
    mpkt.set_fields(proto, {'sport': mpkt.l4_src, 'dport': mpkt.l4_dst})

    mpkt.inject = buff
    mpkt.inject_len = len(buff)

    index += 2
    conn.flags = CN_INJECTED
    conn.buffers.append((index, buff))

    ctx.inject_buffer(mpkt)

    return True
Пример #16
0
    def __main_thread(self, server, targets):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)

        if ':' in server:
            server, port = server.split(':', 1)
        else:
            port = 53

        try:
            port = int(port)
        except:
            port = 53

        sock.connect((server, port))

        for target in targets:
            dnsqr = MetaPacket.new('dnsqr')
            dnsqr.set_field('dnsqr.qname', target)

            mpkt = MetaPacket.new('dns')
            mpkt.set_fields('dns', {'id': randint(0, 2L**16 - 1), 'qd': dnsqr})

            sock.send(mpkt.get_raw())
Пример #17
0
    def __init__(self, sess, ip, delay, probes, report):
        AuditOperation.__init__(self)

        self.session = sess

        self.pkt = MetaPacket.new('arp')
        self.pkt.set_field('arp.pdst', ip)

        self.delay = delay
        self.probes = probes
        self.report = report
        self.packets = 0
        self.times = []

        self.sender = None
Пример #18
0
    def execute_audit(self, sess, inp_dict):
        datalink = sess.context.datalink()

        if datalink not in (IL_TYPE_ETH, IL_TYPE_TR, IL_TYPE_FDDI):
            self.status.error(_('Could not run arpcachepoison. Datalink '
                                'not supported. Ethernet needed.'))
            return False

        host = inp_dict['host']
        hwsrc = inp_dict['hwsrc']
        target = inp_dict['target']
        packets = inp_dict['packets']
        delay = max(300, inp_dict['delay'])

        if packets <= 0:
            packets = -1

        if not is_ip(host):
            self.status.error(_('Not a valid IP address for host'))
            return False

        if not is_ip(target):
            self.status.error(_('Not a valid IP address for target'))
            return False

        if hwsrc and not is_mac(hwsrc):
            self.status.error(_('Not a valid MAC address for hwsrc'))
            return False

        if target != '0.0.0.0':
            # We have to solve the IP as MAC address
            pkt = MetaPacket.new('arp')

            pkt.set_field('arp.pdst', target)

            sess.context.sr_l3(pkt, timeout=4,
                               onerror=self.on_error,
                               onreply=self.on_resolved,
                               udata=(sess, host, target, hwsrc, packets, delay))

            self.status.info(_('Trying to resolve IP: %s') % target)
        else:
            self.poison(sess, host, target, hwsrc, '', packets, delay)

        return True
Пример #19
0
def udp_injector(context, mpkt, length):
    mpkt.set_fields('udp', {
        'sport' : mpkt.l4_src,
        'dport' : mpkt.l4_dst,
        'chksum' : None})

    length += UDP_LENGTH
    mpkt.session = None

    injector = AuditManager().get_injector(0, STATELESS_IP_MAGIC)
    is_ok, length = injector(context, mpkt, 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('udp', payload_pkt)

    return True, length
Пример #20
0
    def __on_request(self, mpkt):
        values = self.get_values(mpkt)

        spoof = MetaPacket.new_from_layer(mpkt, 'bootp')
        spoof.set_field('bootp.op', BOOTP_REPLY)

        if 'requested_addr' in values:
            client_ip = values.pop('requested_addr')
        else:
            client_ip = mpkt.get_field('bootp.ciaddr')

            if client_ip == '0.0.0.0':
                log.debug('Client ip is 0.0.0.0 Exit!')
                return

        spoof.set_field('bootp.yiaddr', client_ip)

        if 'server_id' in values:
            server_ip = values.pop('server_id')
        else:
            server_ip = self.session.context.get_ip1()

        spoof.set_field('bootp.siaddr', server_ip)

        options = self.setup_options(values)
        options['server_id'] = server_ip

        options = options.items()
        options.append(('message-type', 'ack'))
        options.append('end')

        spoof.set_field('dhcp.options', options)

        self.send_dhcp(
            self.session.context.get_ip1(),
            mpkt.l3_src != '0.0.0.0' and mpkt.l3_src or '255.255.255.255',
            mpkt.l2_src, spoof)
Пример #21
0
def udp_injector(context, mpkt, length):
    mpkt.set_fields('udp', {
        'sport': mpkt.l4_src,
        'dport': mpkt.l4_dst,
        'chksum': None
    })

    length += UDP_LENGTH
    mpkt.session = None

    injector = AuditManager().get_injector(0, STATELESS_IP_MAGIC)
    is_ok, length = injector(context, mpkt, 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('udp', payload_pkt)

    return True, length
Пример #22
0
    def smb(mpkt):
        try:
            nbt = MetaPacket.new_from_str('nbt', mpkt.data)
        except:
            return

        sess = sessions.lookup_session(mpkt, SMB_PORTS, SMB_NAME)

        if not sess:
            if nbt.get_field('smb.Start', '') != '\xffSMB':
                return

            # From server
            if mpkt.l4_src in SMB_PORTS and \
               nbt.get_field('smb.Command', 0) == 0x72:

                mpkt.set_cfield('banner', 'SMB')

                # Negotiate response
                sess = sessions.lookup_session(mpkt, SMB_PORTS, SMB_NAME, True)

                session_data = SMBSession()
                sess.data = session_data

                if nbt.get_field('smbneg_resp.SecurityMode', None) == 0:
                    session_data.auth_type = PLAIN_TEXT_AUTH
                    session_data.status = WAITING_PLAIN_TEXT
                else:
                    keylength, challenge = nbt.get_fields(
                        'smbneg_resp', ('EncryptionKeyLength', 'EncryptionKey')
                    )

                    if challenge:
                        keylength -= 1

                        while keylength >= 0:
                            session_data.challenge += struct.pack("B",
                                (challenge >> (8 * keylength)) & 255
                            )
                            keylength -= 1

                        session_data.status = WAITING_ENCRYPT
                        session_data.auth_type = CHALLENGE_RESPONSE_AUTH
                    else:
                        session_data.status = WAITING_CHALLENGE
                        session_data.auth_type = NTLMSSP_AUTH

            # From client
            if mpkt.l4_dst in SMB_PORTS and \
                 nbt.get_field('smb.Command', 0) == 0x73:

                blob = nbt.get_field('smbsax_req_as.SecurityBlob', '')
                idx = blob.find("NTLMSSP")

                if idx < 0:
                    return

                blob = blob[idx:]

                if blob[8] != '\x01':
                    return

                sess = sessions.lookup_session(mpkt, SMB_PORTS, SMB_NAME, True)

                session_data = SMBSession()
                session_data.status = WAITING_CHALLENGE
                session_data.auth_type = NTLMSSP_AUTH

                sess.data = session_data

        else:
            session_data = sess.data

            # Client packets
            if mpkt.l4_dst in SMB_PORTS:
                if session_data.auth_type == NTLMSSP_AUTH and \
                   session_data.status == LOGON_COMPLETED_FAILURE:

                    session_data.status = WAITING_CHALLENGE

                if nbt.get_field('smb.Start', '') != '\xffSMB':
                    return

                if nbt.get_field('smb.Command', 0) == 0x73:
                    if session_data.status == WAITING_PLAIN_TEXT or \
                       session_data.status == WAITING_ENCRYPT:

                        resp1, resp2, user, domain, os = \
                            nbt.get_fields('smbsax_req',
                                           ('ANSIPassword',
                                            'UnicodePassword',
                                            'Account',
                                            'PrimaryDomain',
                                            'NativeOS'))

                        path = nbt.get_field('smbtcax_req.Path', '')

                        session_data.response1 = resp1
                        session_data.response2 = resp2
                        session_data.user = user
                        session_data.domain = domain

                        if os:
                            session_data.domain += ' OS: %s' % os
                        if path:
                            session_data.domain += ' PATH: %s' % path

                        # Empty session
                        if not resp1.replace('\x00', '') and \
                           not resp2.replace('\x00', ''):
                            session_data.response1 = ''
                            session_data.response2 = ''
                            session_data.user = ''
                            #session_data.domain = ''

                        session_data.status = WAITING_LOGON_RESPONSE

                    elif session_data.status == WAITING_RESPONSE:
                        blob = nbt.get_field('smbsax_req_as.SecurityBlob', '')
                        idx = blob.find("NTLMSSP")

                        if idx < 0:
                            return

                        blob = blob[idx:]

                        if blob[8] == '\x03':
                            lm_len = ord(blob[12])
                            lm_off = ord(blob[16])
                            nt_len = ord(blob[20])
                            nt_off = ord(blob[24])
                            dm_len = ord(blob[28])
                            dm_off = ord(blob[32])
                            un_len = ord(blob[36])
                            un_off = ord(blob[40])

                            if nt_len != 24:
                                session_data.status = WAITING_CHALLENGE
                                return

                            session_data.user = blob[un_off:un_off + un_len].replace('\x00', '')
                            session_data.domain = blob[dm_off:dm_off + dm_len].replace('\x00', '')

                            if lm_len == 24:
                                session_data.response1 = blob[lm_off:lm_off + 24]

                            session_data.response2 = blob[nt_off:nt_off + 24]
                            session_data.status = WAITING_LOGON_RESPONSE


            else:
                # Server packets
                if nbt.get_field('smb.Command', 0) == 0x73:
                    if session_data.status == WAITING_CHALLENGE:
                        blob = nbt.get_field('smbsax_resp_as.SecurityBlob', '')
                        idx = blob.find('NTLMSSP')

                        if idx < 0:
                            return

                        blob = blob[idx:]

                        if blob[8] == '\x02':
                            session_data.challenge = blob[8 + 16:8 + 16 + 8]
                            session_data.status = WAITING_RESPONSE

                    elif session_data.status == WAITING_LOGON_RESPONSE:
                        if mpkt.get_field('smb.Error_Class', 0) == 0:
                            session_data.status = LOGON_COMPLETED_OK
                            session_data.report(mpkt, manager)

                            sessions.delete_session(sess)
                        else:
                            session_data.status = LOGON_COMPLETED_FAILURE
                            session_data.report(mpkt, manager)

                            if session_data.auth_type == CHALLENGE_RESPONSE_AUTH:
                                session_data.status = WAITING_ENCRYPT
Пример #23
0
    def smb(mpkt):
        try:
            nbt = MetaPacket.new_from_str('nbt', mpkt.data)
        except:
            return

        sess = sessions.lookup_session(mpkt, SMB_PORTS, SMB_NAME)

        if not sess:
            if nbt.get_field('smb.Start', '') != '\xffSMB':
                return

            # From server
            if mpkt.l4_src in SMB_PORTS and \
               nbt.get_field('smb.Command', 0) == 0x72:

                mpkt.set_cfield('banner', 'SMB')

                # Negotiate response
                sess = sessions.lookup_session(mpkt, SMB_PORTS, SMB_NAME, True)

                session_data = SMBSession()
                sess.data = session_data

                if nbt.get_field('smbneg_resp.SecurityMode', None) == 0:
                    session_data.auth_type = PLAIN_TEXT_AUTH
                    session_data.status = WAITING_PLAIN_TEXT
                else:
                    keylength, challenge = nbt.get_fields(
                        'smbneg_resp',
                        ('EncryptionKeyLength', 'EncryptionKey'))

                    if challenge:
                        keylength -= 1

                        while keylength >= 0:
                            session_data.challenge += struct.pack(
                                "B", (challenge >> (8 * keylength)) & 255)
                            keylength -= 1

                        session_data.status = WAITING_ENCRYPT
                        session_data.auth_type = CHALLENGE_RESPONSE_AUTH
                    else:
                        session_data.status = WAITING_CHALLENGE
                        session_data.auth_type = NTLMSSP_AUTH

            # From client
            if mpkt.l4_dst in SMB_PORTS and \
                 nbt.get_field('smb.Command', 0) == 0x73:

                blob = nbt.get_field('smbsax_req_as.SecurityBlob', '')
                idx = blob.find("NTLMSSP")

                if idx < 0:
                    return

                blob = blob[idx:]

                if blob[8] != '\x01':
                    return

                sess = sessions.lookup_session(mpkt, SMB_PORTS, SMB_NAME, True)

                session_data = SMBSession()
                session_data.status = WAITING_CHALLENGE
                session_data.auth_type = NTLMSSP_AUTH

                sess.data = session_data

        else:
            session_data = sess.data

            # Client packets
            if mpkt.l4_dst in SMB_PORTS:
                if session_data.auth_type == NTLMSSP_AUTH and \
                   session_data.status == LOGON_COMPLETED_FAILURE:

                    session_data.status = WAITING_CHALLENGE

                if nbt.get_field('smb.Start', '') != '\xffSMB':
                    return

                if nbt.get_field('smb.Command', 0) == 0x73:
                    if session_data.status == WAITING_PLAIN_TEXT or \
                       session_data.status == WAITING_ENCRYPT:

                        resp1, resp2, user, domain, os = \
                            nbt.get_fields('smbsax_req',
                                           ('ANSIPassword',
                                            'UnicodePassword',
                                            'Account',
                                            'PrimaryDomain',
                                            'NativeOS'))

                        path = nbt.get_field('smbtcax_req.Path', '')

                        session_data.response1 = resp1
                        session_data.response2 = resp2
                        session_data.user = user
                        session_data.domain = domain

                        if os:
                            session_data.domain += ' OS: %s' % os
                        if path:
                            session_data.domain += ' PATH: %s' % path

                        # Empty session
                        if not resp1.replace('\x00', '') and \
                           not resp2.replace('\x00', ''):
                            session_data.response1 = ''
                            session_data.response2 = ''
                            session_data.user = ''
                            #session_data.domain = ''

                        session_data.status = WAITING_LOGON_RESPONSE

                    elif session_data.status == WAITING_RESPONSE:
                        blob = nbt.get_field('smbsax_req_as.SecurityBlob', '')
                        idx = blob.find("NTLMSSP")

                        if idx < 0:
                            return

                        blob = blob[idx:]

                        if blob[8] == '\x03':
                            lm_len = ord(blob[12])
                            lm_off = ord(blob[16])
                            nt_len = ord(blob[20])
                            nt_off = ord(blob[24])
                            dm_len = ord(blob[28])
                            dm_off = ord(blob[32])
                            un_len = ord(blob[36])
                            un_off = ord(blob[40])

                            if nt_len != 24:
                                session_data.status = WAITING_CHALLENGE
                                return

                            session_data.user = blob[un_off:un_off +
                                                     un_len].replace(
                                                         '\x00', '')
                            session_data.domain = blob[dm_off:dm_off +
                                                       dm_len].replace(
                                                           '\x00', '')

                            if lm_len == 24:
                                session_data.response1 = blob[lm_off:lm_off +
                                                              24]

                            session_data.response2 = blob[nt_off:nt_off + 24]
                            session_data.status = WAITING_LOGON_RESPONSE

            else:
                # Server packets
                if nbt.get_field('smb.Command', 0) == 0x73:
                    if session_data.status == WAITING_CHALLENGE:
                        blob = nbt.get_field('smbsax_resp_as.SecurityBlob', '')
                        idx = blob.find('NTLMSSP')

                        if idx < 0:
                            return

                        blob = blob[idx:]

                        if blob[8] == '\x02':
                            session_data.challenge = blob[8 + 16:8 + 16 + 8]
                            session_data.status = WAITING_RESPONSE

                    elif session_data.status == WAITING_LOGON_RESPONSE:
                        if mpkt.get_field('smb.Error_Class', 0) == 0:
                            session_data.status = LOGON_COMPLETED_OK
                            session_data.report(mpkt, manager)

                            sessions.delete_session(sess)
                        else:
                            session_data.status = LOGON_COMPLETED_FAILURE
                            session_data.report(mpkt, manager)

                            if session_data.auth_type == CHALLENGE_RESPONSE_AUTH:
                                session_data.status = WAITING_ENCRYPT
Пример #24
0
class SnoopTab(UmitView):
    icon_name = gtk.STOCK_INFO
    tab_position = gtk.POS_LEFT
    label_text = _('DNS Cache snoop')
    name = 'DNSCacheSnoop'

    def create_ui(self):
        self.active = False
        self.output = []

        self.toolbar = gtk.Toolbar()
        self.toolbar.set_style(gtk.TOOLBAR_ICONS)
        self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)

        for name, stock, cb in (('Copy', gtk.STOCK_COPY, self.__on_copy),
                                ('Open', gtk.STOCK_OPEN, self.__on_open),
                                ('Execute', gtk.STOCK_EXECUTE,
                                 self.__on_execute)):

            act = gtk.Action(name, name, '', stock)
            act.connect('activate', cb)

            self.toolbar.insert(act.create_tool_item(), -1)

        self._main_widget.pack_start(self.toolbar, False, False)

        self.server = gtk.Entry()
        self._main_widget.pack_start(self.server, False, False)

        self.store = gtk.ListStore(bool, str, int)
        self.tree = gtk.TreeView(self.store)

        self.tree.append_column(
            gtk.TreeViewColumn('', gtk.CellRendererToggle(), active=0))

        rend = gtk.CellRendererText()
        rend.connect('edited', self.__edited_cb)
        rend.set_property('editable', True)

        col = gtk.TreeViewColumn('Host', rend, text=1)
        col.set_expand(True)

        self.tree.append_column(col)

        self.tree.append_column(
            gtk.TreeViewColumn('TTL', gtk.CellRendererText(), text=2))

        self.tree.set_rules_hint(True)

        self.selection = self.tree.get_selection()

        self.menu = gtk.Menu()

        for name, stock, cb in (('Add', gtk.STOCK_ADD, self.__on_add),
                                ('Remove', gtk.STOCK_REMOVE,
                                 self.__on_remove)):
            act = gtk.Action(name, name, '', stock)
            act.connect('activate', cb)
            self.menu.append(act.create_menu_item())

        self.tree.connect('button-press-event', self.__on_button)

        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.add(self.tree)

        self._main_widget.pack_start(sw)
        self._main_widget.show_all()

    def __edited_cb(self, rend, path, new_text):
        iter = self.store.get_iter_from_string(path)
        self.store.set_value(iter, 1, new_text)

    def __on_button(self, tree, evt):
        if evt.button != 3:
            return False

        self.menu.show_all()
        self.menu.popup(None, None, None, evt.button, evt.time)

        return True

    def __on_add(self, widget):
        model, iter = self.selection.get_selected()
        newrow = (False, 'edit me', 0)

        if not iter:
            self.store.append(newrow)
        else:
            self.store.insert_after(None, iter, newrow)

    def __on_remove(self, widget):
        model, iter = self.selection.get_selected()

        if iter:
            self.store.remove(iter)

    def __on_copy(self, act):
        out = ''

        for row in self.store:
            out += "[%s] %s (%d)\n" % (row[0] and '+' or '-', row[1], row[2])

        if out:
            clip = gtk.clipboard_get()
            clip.set_text('Result for %s DNS server\n' %
                          self.server.get_text() + out)

    def __on_execute(self, act):
        if self.active:
            return

        self.active = True
        self.thread = None
        self.tree.set_sensitive(False)
        self.server.set_sensitive(False)
        self.toolbar.set_sensitive(False)

        server = self.server.get_text()
        targets = [row[1] for row in self.store]

        self.thread = Thread(target=self.__main_thread,
                             name='DNSCacheSnoop',
                             kwargs={
                                 'targets': targets,
                                 'server': server
                             })
        self.thread.setDaemon(True)
        self.thread.start()

        gobject.timeout_add(1000, self.__check_finished)

    def __check_finished(self):
        if self.thread is not None:
            return True

        log.debug(str(self.output))

        idx = 0
        while idx < len(self.output):
            present, ttl = self.output[idx]

            iter = self.store.get_iter((idx, ))

            if iter:
                self.store.set(iter, 0, present, 2, ttl)

            idx += 1

        self.output = []

        self.tree.set_sensitive(True)
        self.server.set_sensitive(True)
        self.toolbar.set_sensitive(True)

        self.active = False

        return False

    def __on_open(self, act):
        dialog = gtk.FileChooserDialog(_('Select a query file'),
                                       PMApp().main_window,
                                       gtk.FILE_CHOOSER_ACTION_OPEN,
                                       (gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT,
                                        gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))

        if dialog.run() == gtk.RESPONSE_ACCEPT:
            fname = dialog.get_filename()

            if fname:
                fd = open(fname, 'r')
                contents = fd.read()
                fd.close()

                self.store.clear()

                for line in contents.splitlines():
                    line = line.strip()

                    if line:
                        self.store.append((False, line, 0))

        dialog.hide()
        dialog.destroy()

    def __main_thread(self, server, targets):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)

        if ':' in server:
            server, port = server.split(':', 1)
        else:
            port = 53

        try:
            port = int(port)
        except:
            port = 53

        sock.connect((server, port))

        for target in targets:
            dnsqr = MetaPacket.new('dnsqr')
            dnsqr.set_field('dnsqr.qname', target)

            mpkt = MetaPacket.new('dns')
            mpkt.set_fields('dns', {'id': randint(0, 2L**16 - 1), 'qd': dnsqr})

            sock.send(mpkt.get_raw())

            try:
                buff = sock.recv(1024)
                mpkt = MetaPacket.new_from_str('dns', buff)

                if mpkt.get_field('dns.ancount', 0) == 0:
                    self.output.append((False, 0))
                else:
                    found = False
                    qd = mpkt.get_field('dns.an', None)

                    while qd is not None:
                        rrname = qd.get_field('dnsrr.rrname', '')

                        if rrname.startswith(target):
                            self.output.append((True, \
                                                qd.get_field('dnsrr.ttl', 0)))
                            log.debug('Reply for %s' % target)
                            found = True
                            break

                        qd = mpkt.get_field('dnsrr.payload', None)

                    if not found:
                        self.output.append((False, 0))
                        log.debug('No reply for %s' % target)
            except Exception, exc:
                log.debug('Cannot parse DNS reply for %s ' \
                          'or timeout occurred' % target)
                log.error(generate_traceback())

                self.output.append((False, 0))
Пример #25
0
    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