def _process_dns(self, pkt):

        domain = pkt[sc.DNS].qd.qname
        device_mac = pkt[sc.Ether].dst

        # No DNS requests from this host
        if device_mac == self._host_state.host_mac:
            return

        # Remove trailing dot from domain
        if domain.endswith('.'):
            domain = domain[0:-1]

        ip_set = set()
        for ix in range(pkt[sc.DNS].ancount):
            # Extracts A-records
            if pkt[sc.DNSRR][ix].type == 1:
                # Extracts IPv4 addr in A-record
                ip = pkt[sc.DNSRR][ix].rdata
                if utils.is_ipv4_addr(ip):
                    ip_set.add(ip)

        with self._host_state.lock:
            self._host_state.pending_dns_responses.append({
                'domain': domain,
                'ip_set': ip_set
            })
Пример #2
0
def start(webserver_context):

    # Read from home directory the user_key. If non-existent, get one from
    # cloud.
    config_dict = utils.get_user_config()

    utils.log('[MAIN] Starting.')

    # Set up environment
    state = HostState()
    state.user_key = config_dict['user_key']
    state.secret_salt = config_dict['secret_salt']
    state.host_mac = utils.get_my_mac()
    state.gateway_ip, _, state.host_ip = utils.get_default_route()

    webserver_context['host_state'] = state

    assert utils.is_ipv4_addr(state.gateway_ip)
    assert utils.is_ipv4_addr(state.host_ip)

    state.packet_processor = PacketProcessor(state)

    utils.log('Initialized:', state.__dict__)

    # Continously discover devices
    arp_scan_thread = ArpScan(state)
    arp_scan_thread.start()

    # Continuously gather SSDP data
    netdisco_thread = NetdiscoWrapper(state)
    netdisco_thread.start()

    # Continuously capture packets
    packet_capture_thread = PacketCapture(state)
    packet_capture_thread.start()

    # Continously spoof ARP
    if '--no_spoofing' not in sys.argv:
        arp_spoof_thread = ArpSpoof(state)
        arp_spoof_thread.start()

    # Continuously upload data
    data_upload_thread = DataUploader(state)
    data_upload_thread.start()
Пример #3
0
    def _process_dns(self, pkt):

        src_mac = pkt[sc.Ether].src
        dst_mac = pkt[sc.Ether].dst

        src_ip = pkt[sc.IP].src
        dst_ip = pkt[sc.IP].dst

        # Find device ID
        if pkt[sc.DNS].qr == 0:
            # DNS request
            if dst_mac == self._host_state.host_mac:
                device_mac = src_mac
                resolver_ip = dst_ip
            else:
                return
        else:
            # DNS response
            if src_mac == self._host_state.host_mac:
                device_mac = dst_mac
                resolver_ip = src_ip
            else:
                return

        device_id = utils.get_device_id(device_mac, self._host_state)

        # Parse domain
        try:
            domain = pkt[sc.DNSQR].qname.lower()
        except AttributeError:
            return

        # Remove trailing dot from domain
        if domain[-1] == '.':
            domain = domain[0:-1]

        # Parse DNS response
        ip_set = set()
        if sc.DNSRR in pkt and pkt[sc.DNS].an:
            for ix in range(pkt[sc.DNS].ancount):
                # Extracts A-records
                if pkt[sc.DNSRR][ix].type == 1:
                    # Extracts IPv4 addr in A-record
                    ip = pkt[sc.DNSRR][ix].rdata
                    if utils.is_ipv4_addr(ip):
                        ip_set.add(ip)

        with self._host_state.lock:
            domain = str(domain)
            dns_key = (device_id, domain, resolver_ip, 0)
            current_ip_set = self._host_state \
                .pending_dns_dict.setdefault(dns_key, set())
            ip_set = ip_set | current_ip_set
            self._host_state.pending_dns_dict[dns_key] = ip_set
Пример #4
0
def ip_query(ip):
    if ip is None or not utils.is_ipv4_addr(ip):
        return error_tip(u'ip地址为空或者格式错误')
    params = {'key': file_utils.get_app_key(u'ip_key'), 'ip': ip}
    url = 'http://apis.juhe.cn/ip/ip2addr?{}'.format(
        utils.dict_to_get_params(params))
    try:
        res = requests.get(url)
        data = json.loads(res.text)['result']
        res_item = {
            'title': data['area'],
            'subtitle': data['location'],
            'url': '',
            'arg': data['area'],
            'icon': 'img/ip.png',
            'valid': True
        }
        return [res_item]
    except Exception, e:
        print e
        return []
def main():

    # Read from home directory the user_key. If non-existent, get one from
    # cloud.
    config_dict = utils.get_user_config()

    # Where user would see report
    url = server_config.REPORT_URL.format(user_key=config_dict['user_key'])

    # Open a web browser only if non-root
    if not is_root() and LAUNCH_WEB_BROWSER_UPON_START:
        if 'no_browser' not in sys.argv:
            webbrowser.open_new_tab(url)

    os_platform = sys.platform

    # Run as root
    if os_platform.startswith('linux'):
        elevate(graphical=False)
    else:
        elevate()

    assert is_root()

    utils.log('[MAIN] Starting.')

    # Set up environment
    state = HostState()
    state.user_key = config_dict['user_key']
    state.secret_salt = config_dict['secret_salt']
    state.host_mac = utils.get_my_mac()
    state.gateway_ip, _, state.host_ip = utils.get_default_route()

    assert utils.is_ipv4_addr(state.gateway_ip)
    assert utils.is_ipv4_addr(state.host_ip)

    state.packet_processor = PacketProcessor(state)

    utils.log('Initialized:', state.__dict__)

    # Enable kernal forwarding.
    if os_platform.startswith('darwin'):
        cmd = ['/usr/sbin/sysctl', '-w', 'net.inet.ip.forwarding=1']
    elif os_platform.startswith('linux'):
        cmd = ['sysctl', '-w', 'net.ipv4.ip_forward=1']
    else:
        raise RuntimeError('Unsupported platform.')

    assert subprocess.call(cmd) == 0

    # Continously discover devices
    arp_scan_thread = ArpScan(state)
    arp_scan_thread.start()

    # Continuously capture packets
    packet_capture_thread = PacketCapture(state)
    packet_capture_thread.start()

    # Continously spoof ARP
    arp_spoof_thread = ArpSpoof(state)
    arp_spoof_thread.start()

    # Continuously upload data
    data_upload_thread = DataUploader(state)
    data_upload_thread.start()

    # UI
    try:
        ui.start_main_ui(url, state)
    except KeyboardInterrupt:
        pass

    # Disable kernal forwarding.
    if os_platform.startswith('darwin'):
        cmd = ['/usr/sbin/sysctl', '-w', 'net.inet.ip.forwarding=0']
    elif os_platform.startswith('linux'):
        cmd = ['sysctl', '-w', 'net.ipv4.ip_forward=0']
    assert subprocess.call(cmd) == 0

    utils.log('[MAIN] Done.')
Пример #6
0
def start(webserver_context):

    # Read from home directory the user_key. If non-existent, get one from
    # cloud.
    config_dict = utils.get_user_config()

    utils.log('[MAIN] Starting.')

    # Set up environment
    state = HostState()
    state.user_key = config_dict['user_key'].replace('-', '')
    state.secret_salt = config_dict['secret_salt']
    state.host_mac = utils.get_my_mac()
    state.gateway_ip, _, state.host_ip = utils.get_default_route()

    webserver_context['host_state'] = state

    assert utils.is_ipv4_addr(state.gateway_ip)
    assert utils.is_ipv4_addr(state.host_ip)

    state.packet_processor = PacketProcessor(state)

    utils.log('Initialized:', state.__dict__)

    # Continously discover devices
    arp_scan_thread = ArpScan(state)
    arp_scan_thread.start()

    # Continuously gather SSDP data
    netdisco_thread = NetdiscoWrapper(state)
    netdisco_thread.start()

    # Continuously capture packets
    packet_capture_thread = PacketCapture(state)
    packet_capture_thread.start()

    # Continously spoof ARP
    if '--no_spoofing' not in sys.argv:
        arp_spoof_thread = ArpSpoof(state)
        arp_spoof_thread.start()

    # Continuously upload data
    data_upload_thread = DataUploader(state)
    data_upload_thread.start()

    # Suppress scapy warnings
    try:
        logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
    except Exception:
        pass

    # Suppress flask messages
    try:
        logging.getLogger('werkzeug').setLevel(logging.ERROR)
    except Exception:
        pass

    if state.persistent_mode:
        # Insert a dash every four characters to make user-key easier to type
        pretty_user_key = ''
        for (ix, char) in enumerate(state.user_key):
            if (ix > 0) and (ix % 4 == 0):
                pretty_user_key += '-'
            pretty_user_key += char

        path = 'persistent/' + pretty_user_key
        caution = 'This is your private link. Open it only on trusted computers.' # noqa
    else:
        path = ''
        caution = ''

    print('\n' * 100)
    print("""
        ===========================
          Princeton IoT Inspector
        ===========================

        View the IoT Inspector report at:

        https://inspector.cs.princeton.edu/{0}

        {1}

        Hit Control + C to terminate this process and stop data collection.

    """.format(path, caution))
Пример #7
0
def start():
    """
    Initializes inspector by spawning a number of background threads.
    
    Returns the host state once all background threats are started.
    
    """
    # Read from home directory the user_key. If non-existent, get one from
    # cloud.
    config_dict = utils.get_user_config()

    utils.log('[MAIN] Starting.')

    # Set up environment
    state = HostState()
    state.user_key = config_dict['user_key'].replace('-', '')
    state.secret_salt = config_dict['secret_salt']
    state.host_mac = utils.get_my_mac()
    state.gateway_ip, _, state.host_ip = utils.get_default_route()

    # Read special command-line arguments
    if '--raspberry_pi_mode' in sys.argv:
        state.raspberry_pi_mode = True

    assert utils.is_ipv4_addr(state.gateway_ip)
    assert utils.is_ipv4_addr(state.host_ip)

    state.packet_processor = PacketProcessor(state)

    utils.log('Initialized:', state.__dict__)

    # Continously discover devices
    arp_scan_thread = ArpScan(state)
    arp_scan_thread.start()

    # Continously discover ports via SYN scans
    syn_scan_thread = SynScan(state)
    syn_scan_thread.start()

    # Continuously gather SSDP data
    netdisco_thread = NetdiscoWrapper(state)
    netdisco_thread.start()

    # Continuously capture packets
    packet_capture_thread = PacketCapture(state)
    packet_capture_thread.start()

    # Continously spoof ARP
    if '--no_spoofing' not in sys.argv:
        arp_spoof_thread = ArpSpoof(state)
        arp_spoof_thread.start()

    # Continuously upload data
    data_upload_thread = DataUploader(state)
    data_upload_thread.start()

    # Suppress scapy warnings
    try:
        logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
    except Exception:
        pass

    # Suppress flask messages
    try:
        logging.getLogger('werkzeug').setLevel(logging.ERROR)
    except Exception:
        pass

    # Insert a dash every four characters to make user-key easier to type
    pretty_user_key = ''
    for (ix, char) in enumerate(state.user_key):
        if (ix > 0) and (ix % 4 == 0):
            pretty_user_key += '-'
        pretty_user_key += char

    print('\n' * 100)

    os_platform = utils.get_os()

    print(WINDOWS_STARTUP_TEXT.format(server_config.BASE_URL, pretty_user_key))

    # Open a browser window on Windows 10. Note that a new webpage will be
    # opened in a non-privileged mode. TODO: Not sure how to do the same
    # for macOS, as the "open" call on macOS will open a browser window
    # in privileged mode.
    if os_platform == 'windows':
        utils.open_browser_on_windows('{0}/user/{1}'.format(
            server_config.BASE_URL, pretty_user_key))

    return state
Пример #8
0
def start():
    """
    Initializes inspector by spawning a number of background threads.

    Returns the host state once all background threats are started.

    """
    # Read from home directory the user_key. If non-existent, get one from
    # cloud.
    config_dict = utils.get_user_config()

    utils.log('[MAIN] Starting.')

    # Set up environment
    state = HostState()
    state.user_key = config_dict['user_key'].replace('-', '')
    state.secret_salt = config_dict['secret_salt']
    state.host_mac = utils.get_my_mac()
    state.gateway_ip, _, state.host_ip = utils.get_default_route()

    assert utils.is_ipv4_addr(state.gateway_ip)
    assert utils.is_ipv4_addr(state.host_ip)

    state.packet_processor = PacketProcessor(state)

    utils.log('Initialized:', state.__dict__)

    # Start web API
    webserver.start_thread(state)

    # Continously discover devices
    arp_scan_thread = ArpScan(state)
    arp_scan_thread.start()

    # Continously discover ports via SYN scans
    syn_scan_thread = SynScan(state)
    syn_scan_thread.start()

    # # Continuously gather SSDP data
    # netdisco_thread = NetdiscoWrapper(state)
    # netdisco_thread.start()

    # Continuously capture packets
    packet_capture_thread = PacketCapture(state)
    packet_capture_thread.start()

    # Continously spoof ARP
    if '--no_spoofing' not in sys.argv:
        arp_spoof_thread = ArpSpoof(state)
        arp_spoof_thread.start()

    # Suppress scapy warnings
    try:
        logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
    except Exception:
        pass

    # Suppress flask messages
    try:
        logging.getLogger('werkzeug').setLevel(logging.ERROR)
    except Exception:
        pass

    # Insert a dash every four characters to make user-key easier to type
    pretty_user_key = ''
    for (ix, char) in enumerate(state.user_key):
        if (ix > 0) and (ix % 4 == 0):
            pretty_user_key += '-'
        pretty_user_key += char

    print(
        'Ready. To test if the API works, visit http://127.0.0.1:46241/get_device_list'
    )

    return state