示例#1
0
def main():
    aparse = argparse.ArgumentParser(
        description="Connection initiator test script for Sniffle BLE5 sniffer"
    )
    aparse.add_argument("-s",
                        "--serport",
                        default="/dev/ttyACM0",
                        help="Sniffer serial port name")
    args = aparse.parse_args()

    global hw
    hw = SniffleHW(args.serport)

    # set the advertising channel (and return to ad-sniffing mode)
    hw.cmd_chan_aa_phy(37, BLE_ADV_AA, 0)

    # pause after sniffing
    hw.cmd_pause_done(True)

    # capture advertisements
    hw.cmd_endtrim(0x10)

    # turn off RSSI filter
    hw.cmd_rssi(-128)

    # Turn off MAC filter
    hw.cmd_mac()

    # initiator doesn't care about this setting, it always accepts aux
    hw.cmd_auxadv(False)

    # advertiser needs a MAC address
    hw.random_addr()

    # advertise roughly every 200 ms
    hw.cmd_adv_interval(200)

    # zero timestamps and flush old packets
    hw.mark_and_flush()

    # advertising and scan response data
    advData = bytes([
        0x02, 0x01, 0x1A, 0x02, 0x0A, 0x0C, 0x11, 0x07, 0x64, 0x14, 0xEA, 0xD7,
        0x2F, 0xDB, 0xA3, 0xB0, 0x59, 0x48, 0x16, 0xD4, 0x30, 0x82, 0xCB, 0x27,
        0x05, 0x03, 0x0A, 0x18, 0x0D, 0x18
    ])
    devName = b'NCC Goat'
    scanRspData = bytes([len(devName) + 1, 0x09]) + devName

    # now enter advertiser mode
    hw.cmd_advertise(advData, scanRspData)

    while True:
        msg = hw.recv_and_decode()
        print_message(msg)
示例#2
0
def main():
    aparse = argparse.ArgumentParser(
        description="Scanner utility for Sniffle BLE5 sniffer")
    aparse.add_argument("-s",
                        "--serport",
                        default="/dev/ttyACM0",
                        help="Sniffer serial port name")
    aparse.add_argument("-c",
                        "--advchan",
                        default=37,
                        choices=[37, 38, 39],
                        type=int,
                        help="Advertising channel to listen on")
    aparse.add_argument("-r",
                        "--rssi",
                        default=-80,
                        type=int,
                        help="Filter packets by minimum RSSI")
    aparse.add_argument("-e",
                        "--extadv",
                        action="store_const",
                        default=False,
                        const=True,
                        help="Capture BT5 extended (auxiliary) advertising")
    aparse.add_argument(
        "-l",
        "--longrange",
        action="store_const",
        default=False,
        const=True,
        help="Use long range (coded) PHY for primary advertising")
    args = aparse.parse_args()

    # Sanity check argument combinations
    if args.longrange and not args.extadv:
        print("Long-range PHY only supported in extended advertising!",
              file=sys.stderr)
        return

    global hw
    hw = SniffleHW(args.serport)

    # set the advertising channel (and return to ad-sniffing mode)
    hw.cmd_chan_aa_phy(args.advchan, BLE_ADV_AA, 2 if args.longrange else 0)

    # only sniff advertisements (don't follow connections)
    hw.cmd_endtrim(0xB0)

    # configure RSSI filter
    hw.cmd_rssi(args.rssi)

    # turn off MAC address filtering
    hw.cmd_mac()

    # configure BT5 extended (aux/secondary) advertising
    hw.cmd_auxadv(args.extadv)

    # trap Ctrl-C
    signal.signal(signal.SIGINT, sigint_handler)

    print("Starting scanner. Press CTRL-C to stop scanning and show results.")

    while not done_scan:
        msg = hw.recv_and_decode()
        if isinstance(msg, DebugMessage):
            print(msg)
        elif isinstance(msg, PacketMessage):
            handle_packet(msg)

    print("\n\nScan Results:")
    for a in sorted(advertisers.keys(),
                    key=lambda k: advertisers[k].rssi,
                    reverse=True):
        print("=" * 80)
        print("AdvA: %s RSSI: %i Hits: %i" %
              (a, advertisers[a].rssi, advertisers[a].hits))
        if advertisers[a].adv:
            print("\nAdvertisement:")
            print(advertisers[a].adv)
        else:
            print("\nAdvertisement: None")
        if advertisers[a].scan_rsp:
            print("\nScan Response:")
            print(advertisers[a].scan_rsp)
        else:
            print("\nScan Response: None")
        print("=" * 80, end="\n\n")
示例#3
0
def main():
    aparse = argparse.ArgumentParser(
        description="Host-side receiver for Sniffle BLE5 sniffer")
    aparse.add_argument("-s",
                        "--serport",
                        default="/dev/ttyACM0",
                        help="Sniffer serial port name")
    aparse.add_argument("-c",
                        "--advchan",
                        default=37,
                        choices=[37, 38, 39],
                        type=int,
                        help="Advertising channel to listen on")
    aparse.add_argument("-p",
                        "--pause",
                        action="store_const",
                        default=False,
                        const=True,
                        help="Pause sniffer after disconnect")
    aparse.add_argument("-r",
                        "--rssi",
                        default=-80,
                        type=int,
                        help="Filter packets by minimum RSSI")
    aparse.add_argument("-m",
                        "--mac",
                        default=None,
                        help="Filter packets by advertiser MAC")
    aparse.add_argument(
        "-a",
        "--advonly",
        action="store_const",
        default=False,
        const=True,
        help="Sniff only advertisements, don't follow connections")
    aparse.add_argument("-e",
                        "--extadv",
                        action="store_const",
                        default=False,
                        const=True,
                        help="Capture BT5 extended (auxiliary) advertising")
    aparse.add_argument(
        "-H",
        "--hop",
        action="store_const",
        default=False,
        const=True,
        help="Hop primary advertising channels in extended mode")
    aparse.add_argument(
        "-l",
        "--longrange",
        action="store_const",
        default=False,
        const=True,
        help="Use long range (coded) PHY for primary advertising")
    aparse.add_argument("-o",
                        "--output",
                        default=None,
                        help="PCAP output file name")
    args = aparse.parse_args()

    # Sanity check argument combinations
    if args.hop and args.mac is None:
        print("Primary adv. channel hop requires a MAC address specified!",
              file=sys.stderr)
        return
    if args.longrange and not args.extadv:
        print("Long-range PHY only supported in extended advertising!",
              file=sys.stderr)
        return
    if args.longrange and args.hop:
        # this would be pointless anyway, since long range always uses extended ads
        print("Primary ad channel hopping unsupported on long range PHY!",
              file=sys.stderr)
        return

    global hw
    hw = SniffleHW(args.serport)

    # set the advertising channel (and return to ad-sniffing mode)
    hw.cmd_chan_aa_phy(args.advchan, BLE_ADV_AA, 2 if args.longrange else 0)

    # set whether or not to pause after sniffing
    hw.cmd_pause_done(args.pause)

    # set up endTrim
    if args.advonly:
        hw.cmd_endtrim(0xB0)
    else:
        hw.cmd_endtrim(0x10)

    # configure RSSI filter
    global _rssi_min
    _rssi_min = args.rssi
    hw.cmd_rssi(args.rssi)

    # disable 37/38/39 hop in extended mode unless overridden
    global _allow_hop3
    if args.extadv and not args.hop:
        _allow_hop3 = False

    # configure MAC filter
    global _delay_top_mac
    if args.mac is None:
        hw.cmd_mac()
    elif args.mac == "top":
        hw.cmd_mac()
        _delay_top_mac = True
    else:
        try:
            macBytes = [int(h, 16) for h in reversed(args.mac.split(":"))]
            if len(macBytes) != 6:
                raise Exception("Wrong length!")
        except:
            print("MAC must be 6 colon-separated hex bytes", file=sys.stderr)
            return
        hw.cmd_mac(macBytes, _allow_hop3)

    # configure BT5 extended (aux/secondary) advertising
    hw.cmd_auxadv(args.extadv)

    global pcwriter
    if not (args.output is None):
        pcwriter = PcapBleWriter(args.output)

    while True:
        msg_type, msg_body = hw.recv_msg()
        print_message(msg_type, msg_body)
示例#4
0
def main():
    aparse = argparse.ArgumentParser(
        description="Connection initiator test script for Sniffle BLE5 sniffer"
    )
    aparse.add_argument("-s",
                        "--serport",
                        default="/dev/ttyACM0",
                        help="Sniffer serial port name")
    aparse.add_argument("-c",
                        "--advchan",
                        default=37,
                        choices=[37, 38, 39],
                        type=int,
                        help="Advertising channel to listen on")
    aparse.add_argument("-r",
                        "--rssi",
                        default=-80,
                        type=int,
                        help="Filter packets by minimum RSSI")
    aparse.add_argument("-m",
                        "--mac",
                        default=None,
                        help="Specify target MAC address")
    aparse.add_argument("-i", "--irk", default=None, help="Specify target IRK")
    aparse.add_argument(
        "-l",
        "--longrange",
        action="store_const",
        default=False,
        const=True,
        help="Use long range (coded) PHY for primary advertising")
    aparse.add_argument("-P",
                        "--public",
                        action="store_const",
                        default=False,
                        const=True,
                        help="Supplied MAC address is public")
    args = aparse.parse_args()

    global hw
    hw = SniffleHW(args.serport)

    if args.mac is None and args.irk is None:
        print("Must specify target MAC address or IRK", file=sys.stderr)
        return
    if args.mac and args.irk:
        print("IRK and MAC filters are mutually exclusive!", file=sys.stderr)
        return
    if args.public and args.irk:
        print("IRK only works on RPAs, not public addresses!", file=sys.stderr)
        return

    # set the advertising channel (and return to ad-sniffing mode)
    hw.cmd_chan_aa_phy(args.advchan, BLE_ADV_AA, 2 if args.longrange else 0)

    # pause after sniffing
    hw.cmd_pause_done(True)

    # capture advertisements
    hw.cmd_endtrim(0x10)

    # configure RSSI filter
    hw.cmd_rssi(args.rssi)

    if args.mac:
        try:
            macBytes = [int(h, 16) for h in reversed(args.mac.split(":"))]
            if len(macBytes) != 6:
                raise Exception("Wrong length!")
        except:
            print("MAC must be 6 colon-separated hex bytes", file=sys.stderr)
            return
        hw.cmd_mac(macBytes, False)
    else:
        hw.cmd_irk(unhexlify(args.irk), False)

    # initiator doesn't care about this setting, it always accepts aux
    hw.cmd_auxadv(False)

    # initiator needs a MAC address
    hw.random_addr()

    if args.irk:
        macBytes = get_mac_from_irk()

    # zero timestamps and flush old packets
    hw.mark_and_flush()

    # now enter initiator mode
    global _aa
    _aa = hw.initiate_conn(macBytes, not args.public)

    while True:
        msg = hw.recv_and_decode()
        print_message(msg)