Exemple #1
0
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip,Net):
        ip = iter(ip).next()
    ip = inet_ntoa(inet_aton(ip))
    tmp = map(ord, inet_aton(ip))
    if (tmp[0] & 0xf0) == 0xe0: # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
    iff,a,gw = conf.route.route(ip)
    if ( (iff == LOOPBACK_NAME) or (ip == conf.route.get_if_bcast(iff)) ):
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface = iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemple #2
0
def arpleak(target, plen=255, hwlen=255, **kargs):
    """Exploit ARP leak flaws, like NetBSD-SA2017-002.

https://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2017-002.txt.asc

    """
    # We want explicit packets
    pkts_iface = {}
    for pkt in ARP(pdst=target):
        # We have to do some of Scapy's work since we mess with
        # important values
        iface = conf.route.route(pkt.pdst)[0]
        psrc = get_if_addr(iface)
        hwsrc = get_if_hwaddr(iface)
        pkt.plen = plen
        pkt.hwlen = hwlen
        if plen == 4:
            pkt.psrc = psrc
        else:
            pkt.psrc = inet_aton(psrc)[:plen]
            pkt.pdst = inet_aton(pkt.pdst)[:plen]
        if hwlen == 6:
            pkt.hwsrc = hwsrc
        else:
            pkt.hwsrc = mac2str(hwsrc)[:hwlen]
        pkts_iface.setdefault(iface, []).append(
            Ether(src=hwsrc, dst=ETHER_BROADCAST) / pkt
        )
    ans, unans = SndRcvList(), PacketList(name="Unanswered")
    for iface, pkts in viewitems(pkts_iface):
        ans_new, unans_new = srp(pkts, iface=iface, filter="arp", **kargs)
        ans += ans_new
        unans += unans_new
        ans.listname = "Results"
        unans.listname = "Unanswered"
    for _, rcv in ans:
        if ARP not in rcv:
            continue
        rcv = rcv[ARP]
        psrc = rcv.get_field('psrc').i2m(rcv, rcv.psrc)
        if plen > 4 and len(psrc) > 4:
            print("psrc")
            hexdump(psrc[4:])
            print()
        hwsrc = rcv.get_field('hwsrc').i2m(rcv, rcv.hwsrc)
        if hwlen > 6 and len(hwsrc) > 6:
            print("hwsrc")
            hexdump(hwsrc[6:])
            print()
    return ans, unans
Exemple #3
0
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip,Net):
        ip = iter(ip).next()
    tmp = map(ord, inet_aton(ip))
    if (tmp[0] & 0xf0) == 0xe0: # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
    iff,a,gw = conf.route.route(ip)
    if ( (iff == LOOPBACK_NAME) or (ip == conf.route.get_if_bcast(iff)) ):
        return "ff:ff:ff:ff:ff:ff"
    # Windows uses local IP instead of 0.0.0.0 to represent locally reachable addresses
    ifip = str(pcapdnet.dnet.intf().get(iff)['addr'])
    if gw != ifip.split('/')[0]:
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface = iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemple #4
0
def build_hmac_sha1(pkt, pw = '\0' * 20, ip4l=None, ip6l=None):
    if ip4l is None:
        ip4l = []
    if ip6l is None:
        ip6l = []
    if not pkt.haslayer(CARP):
        return None 

    p = pkt[CARP]
    h = hmac.new(pw, digestmod = hashlib.sha1)
    # XXX: this is a dirty hack. it needs to pack version and type into a single 8bit field
    h.update('\x21')
    # XXX: mac addy if different from special link layer. comes before vhid
    h.update(struct.pack('!B', p.vhid))

    sl = []
    for i in ip4l:
        # sort ips from smallest to largest
        sl.append(inet_aton(i))
    sl.sort()

    for i in sl:
        h.update(i)

    # XXX: do ip6l sorting

    return h.digest()
Exemple #5
0
 def i2m(self, pkt, x):
     if not x:
         return b""
     if isinstance(x, bytes):
         return x
     tmp_len = 2 + len(x) * 4
     s = b"\x01\x01" + struct.pack("!H", tmp_len) + b"\x00\x01"
     for o in x:
         s += inet_aton(o)
     return s
Exemple #6
0
    def i2m(self, pkt, x):
        x = inet_aton(x)
        tmp_len = self.length_from(pkt)

        if tmp_len <= 8:
            return x[:1]
        elif tmp_len <= 16:
            return x[:2]
        elif tmp_len <= 24:
            return x[:3]
        else:
            return x
Exemple #7
0
 def i2m(self, pkt, x):
     if isinstance(x, bytes):
         return x
     s = b"\x05\x00\x00\x0E\x00\x01"
     s += struct.pack("!H", x[0])
     octet = 0
     if x[1] != 0:
         octet += 2**7
     if x[2] != 0:
         octet += 2**6
     s += struct.pack("!B", octet)
     s += struct.pack("!B", x[3])
     s += struct.pack("!H", x[4])
     s += inet_aton(x[5])
     s += struct.pack("!H", x[6])
     return s
Exemple #8
0
 def i2m(self, pkt, x):
     if not x:
         return b""
     if isinstance(x, bytes):
         return x
     s = b"\x01\x00"
     tmp_len = 0
     fec = b""
     for o in x:
         fec += b"\x02\x00\x01"
         # mask length
         fec += struct.pack("!B", o[1])
         # Prefix
         fec += inet_aton(o[0])
         tmp_len += 8
     s += struct.pack("!H", tmp_len)
     s += fec
     return s
Exemple #9
0
    def build_hmac_sha1(self, pw=b'\x00' * 20, ip4l=[], ip6l=[]):
        h = hmac.new(pw, digestmod=hashlib.sha1)
        # XXX: this is a dirty hack. it needs to pack version and type into a single 8bit field  # noqa: E501
        h.update(b'\x21')
        # XXX: mac addy if different from special link layer. comes before vhid
        h.update(struct.pack('!B', self.vhid))

        sl = []
        for i in ip4l:
            # sort ips from smallest to largest
            sl.append(inet_aton(i))
        sl.sort()

        for i in sl:
            h.update(i)

        # XXX: do ip6l sorting

        return h.digest()
Exemple #10
0
 def enc(cls, ipaddr_ascii):
     try:
         s = inet_aton(ipaddr_ascii)
     except Exception:
         raise BER_Encoding_Error("IPv4 address could not be encoded") 
     return chr(cls.tag)+BER_len_enc(len(s))+s
Exemple #11
0
 def enc(cls, ipaddr_ascii):
     try:
         s = inet_aton(ipaddr_ascii)
     except Exception:
         raise BER_Encoding_Error("IPv4 address could not be encoded")
     return chr(cls.tag) + BER_len_enc(len(s)) + s
    sys.exit("Could not resolve host server: %s" % ex)

if args.ciphersuite:
    ciphers = int(args.ciphersuite, 16)
    if ciphers not in list(range(0x1301, 0x1306)):
        ch = TLSClientHello(ciphers=ciphers)
    else:
        ch = TLS13ClientHello(ciphers=ciphers)
else:
    ch = None

server_name = args.sni
# If server name is unknown, try server
if not server_name and args.server:
    try:
        inet_aton(args.server)
    except socket.error:
        server_name = args.server

t = TLSClientAutomaton(server=args.server,
                       dport=args.port,
                       server_name=server_name,
                       client_hello=ch,
                       version=args.version,
                       mycert=basedir + "/test/tls/pki/cli_cert.pem",
                       mykey=basedir + "/test/tls/pki/cli_key.pem",
                       psk=args.psk,
                       psk_mode=psk_mode,
                       resumption_master_secret=args.res_master,
                       session_ticket_file_in=args.session_ticket_file_in,
                       session_ticket_file_out=args.session_ticket_file_out,
Exemple #13
0
def analysis_report_pcap(pcap_file: str,
                         total_flows_from_trace: int = 0) -> None:
    pcap_reader = RawPcapReader(pcap_file)
    skipped = 0
    dropped = 0  # based on seq number
    prev_seq_no = {}  # HW ID -> seq number

    # Local report
    local_reports = 0
    five_tuple_to_prev_local_report_time = {}  # 5-tuple -> latest report time
    flow_with_multiple_local_reports = set()
    valid_local_report_irgs = []
    bad_local_report_irgs = []
    invalid_local_report_irgs = []

    # Drop report
    drop_reports = 0
    five_tuple_to_prev_drop_report_time = {}  # 5-tuple -> latest report time
    flow_with_multiple_drop_reports = set()
    valid_drop_report_irgs = []
    bad_drop_report_irgs = []
    invalid_drop_report_irgs = []
    pkt_processed = 0
    while True:
        try:
            packet_info = pcap_reader.next()
        except EOFError:
            break
        except StopIteration:
            break
        pkt_processed += 1

        # packet_info = (raw-bytes, packet-metadata)
        report_pkt = Ether(packet_info[0])
        # packet enter time in nano seconds
        packet_enter_time = packet_info[1].sec * 1000000000 + packet_info[
            1].usec * 1000

        if IntL45ReportFixed not in report_pkt:
            skipped += 1
            continue

        int_fix_report = report_pkt[IntL45ReportFixed]
        if IntL45LocalReport in report_pkt:
            local_reports += 1
            int_report = report_pkt[IntL45LocalReport]
            packet_enter_time = int_report.egress_tstamp
            five_tuple_to_prev_report_time = five_tuple_to_prev_local_report_time
            flow_with_multiple_reports = flow_with_multiple_local_reports
            valid_report_irgs = valid_local_report_irgs
            bad_report_irgs = bad_local_report_irgs
            invalid_report_irgs = invalid_local_report_irgs
        elif IntL45DropReport in report_pkt:
            drop_reports += 1
            int_report = report_pkt[IntL45DropReport]
            five_tuple_to_prev_report_time = five_tuple_to_prev_drop_report_time
            flow_with_multiple_reports = flow_with_multiple_drop_reports
            valid_report_irgs = valid_drop_report_irgs
            bad_report_irgs = bad_drop_report_irgs
            invalid_report_irgs = invalid_drop_report_irgs
        else:
            # TODO: handle queue report
            skipped += 1
            continue

        # Check the sequence number
        hw_id = int_fix_report.hw_id
        seq_no = int_fix_report.seq_no
        if hw_id in prev_seq_no:
            dropped += seq_no - prev_seq_no[hw_id] - 1
        prev_seq_no[hw_id] = seq_no

        # Curently we only process IPv4 packets, but we can process IPv6 if needed.
        if IP not in int_report:
            skipped += 1
            continue

        # Checks the internal packet
        # Here we skip packets that is not a TCP or UDP packet since they can be
        # fragmented or something else.

        if TCP in int_report:
            internal_l4 = int_report[TCP]
        elif UDP in int_report:
            internal_l4 = int_report[UDP]
        else:
            skipped += 1
            continue

        internal_ip = int_report[IP]
        five_tuple = (
            inet_aton(internal_ip.src),
            inet_aton(internal_ip.dst),
            int.to_bytes(internal_ip.proto, 1, "big"),
            int.to_bytes(internal_l4.sport, 2, "big"),
            int.to_bytes(internal_l4.dport, 2, "big"),
        )

        if five_tuple in five_tuple_to_prev_report_time:
            prev_report_time = five_tuple_to_prev_report_time[five_tuple]
            irg = (packet_enter_time - prev_report_time) / 1000000000
            if irg > 0:
                valid_report_irgs.append(irg)
            flow_with_multiple_reports.add(five_tuple)

            if 0 < irg and irg < 0.9:
                bad_report_irgs.append(irg)
            if irg <= 0:
                invalid_report_irgs.append(irg)

        five_tuple_to_prev_report_time[five_tuple] = packet_enter_time

    log.info("Pkt processed: {}".format(pkt_processed))
    # Local report
    log.info("Local reports: {}".format(local_reports))
    log.info("Total 5-tuples: {}".format(
        len(five_tuple_to_prev_local_report_time)))
    log.info("Flows with multiple report: {}".format(
        len(flow_with_multiple_local_reports)))
    log.info("Total INT IRGs: {}".format(len(valid_local_report_irgs)))
    log.info("Total bad INT IRGs(<0.9s): {}".format(
        len(bad_local_report_irgs)))
    log.info("Total invalid INT IRGs(<=0s): {}".format(
        len(invalid_local_report_irgs)))
    if total_flows_from_trace != 0:
        log.info("Accuracy score: {}".format(
            len(five_tuple_to_prev_local_report_time) * 100 /
            total_flows_from_trace))

    if len(valid_local_report_irgs) <= 0:
        log.info("No valid local report IRGs")
    else:
        log.info("Efficiency score: {}".format(
            (len(valid_local_report_irgs) - len(bad_local_report_irgs)) * 100 /
            len(valid_local_report_irgs)))
        # Plot Histogram and CDF
        report_plot_file = abspath(splitext(pcap_file)[0] + "-local" + ".png")
        plot_histogram_and_cdf(report_plot_file, valid_local_report_irgs)

    # Drop report
    log.info("----------------------")
    log.info("Drop reports: {}".format(drop_reports))
    log.info("Total 5-tuples: {}".format(
        len(five_tuple_to_prev_drop_report_time)))
    log.info("Flows with multiple report: {}".format(
        len(flow_with_multiple_drop_reports)))
    log.info("Total INT IRGs: {}".format(len(valid_drop_report_irgs)))
    log.info("Total bad INT IRGs(<0.9s): {}".format(len(bad_drop_report_irgs)))
    log.info("Total invalid INT IRGs(<=0s): {}".format(
        len(invalid_drop_report_irgs)))
    log.info("Total report dropped: {}".format(dropped))
    log.info("Skipped packets: {}".format(skipped))

    if len(valid_drop_report_irgs) <= 0:
        log.info("No valid drop report IRGs")
    else:
        log.info("Efficiency score: {}".format(
            (len(valid_drop_report_irgs) - len(bad_drop_report_irgs)) * 100 /
            len(valid_drop_report_irgs)))
        report_plot_file = abspath(splitext(pcap_file)[0] + "-drop" + ".png")
        plot_histogram_and_cdf(report_plot_file, valid_drop_report_irgs)
Exemple #14
0
def build_logon_group(ip, port, kernel):
    return 'LG_EYECAT' + '\x01' + inet_aton(ip) + '\x00\x00\x00\x00' + \
        struct.pack('!h', port) + kernel + '\x00'*6 + (' '*5).encode('UTF-16-LE')