美文网首页程序员
使用 Python 查看局域网内存活主机

使用 Python 查看局域网内存活主机

作者: speculatecat | 来源:发表于2018-04-30 17:57 被阅读186次

    概述

    当我们的网络首次接入一些新的设备,而且这些设备不是像手机、电脑一类的有屏幕设备,如服务器、Nas、树莓派等硬件,我们想要通过网络连接控制,但是并不知道设备的 IP 地址,这时,我们就需要扫描网络找到我们目标硬件设备的 IP 地址。

    常用的方法如进入路由器管理后台,我们就可以找到我们的设备 IP 地址,或者使用现成的软件,如 Adbanced IP Scanner 软件,也可以扫描网络实现我们想要的目标。但是,实际上我们真正需要的仅仅是要知道设备名和 IP 地址即可,无论登录路由器还是使用软件,都显得有点牛刀杀鸡的感觉,因此我们尝试使用 Python 编写一个查找内网存活在线主机IP地址的脚本。
    关键词 Python nmap 局域网 存活主机IP

    NMAP

    Nmap 是一款用于网络发现和安全审计的网络安全工具,可以检测目标主机是否在线、端口开放情况、侦测运行的服务类型及版本信息、侦测操作系统与设备类型等信息。

    在使用之前,我们需要先安装 Nmap 软件。对于 WIndow 系统,可以登录 Nmap 官网下载页面 下载相应版本安装即可。

    对于 MacOS 系统,可以使用 HomeBrew 安装,具体方法如下:

    brew update
    brew install nmap
    

    对于 Ubuntu/Linux,可以使用 apt 来安装,具体方法如下:

    sudo apt install nmap
    

    完成 nmap 软件安装后,我们在继续安装 python 模块,具体方法如下:

    pip install nmap
    pip install python-nmap
    

    除此之外,为了我们后面代码的方便,我们还需要安装一个 netifaces 模块,具体方法如下:

    pip instal netifaces
    

    脚本代码详解

    首先,我们可以直接使用 nmap 工具来扫描局域网,操作如下:

    # 假设本地 ip 地址范围为 192.168.100.1 ~ 192.168.100.255
    nmap 192.168.100.1-255 -sP
    >>
    (...省略部分内容...)
    Nmap scan report for 192.168.100.16
    Host is up (0.0020s latency).
    Nmap scan report for MIMAX-xiaomishouji (192.168.100.17)
    Host is up (0.0019s latency).
    (...省略部分内容...)
    

    我们可以看到,nmap 会把所有 ip 地址都扫描一遍,然后把扫描结果输出,如果主机在线,那么就能看到主机名和其IP地址。我们也可以单独扫描一个IP地址,具体操作如下:

    # 扫描小米手机ip地址 192.168.100.17
    nmap 192.168.100.17
    >>
    Starting Nmap 7.70 ( https://nmap.org ) at 2018-04-30 17:34 CST
    Nmap scan report for MIMAX-xiaomishouji (192.168.100.17)
    Host is up (0.00099s latency).
    Not shown: 995 filtered ports
    PORT     STATE SERVICE
    80/tcp   open  http
    110/tcp  open  pop3
    143/tcp  open  imap
    3128/tcp open  squid-http
    8080/tcp open  http-proxy
    
    Nmap done: 1 IP address (1 host up) scanned in 4.39 seconds
    

    我们不加 -sP 参数,nmap 会扫描该IP的所有端口,我们可以从结果看到我的这一只小米手机开放的端口。

    接下来,使用python来完成以上的操作,具体代码如下:

    import nmap
    nmScan = nmap.PortScanner()
    nmScan.scan(hosts='192.168.100.17', arguments='-sP')
    >>
    {'nmap': {'command_line': 'nmap -oX - -sP 192.168.100.17',
      'scaninfo': {},
      'scanstats': {'downhosts': '0',
       'elapsed': '0.01',
       'timestr': 'Mon Apr 30 17:39:50 2018',
       'totalhosts': '1',
       'uphosts': '1'}},
     'scan': {'192.168.100.17': {'addresses': {'ipv4': '192.168.100.17'},
       'hostnames': [{'name': 'MIMAX-xiaomishouji', 'type': 'PTR'}],
       'status': {'reason': 'syn-ack', 'state': 'up'},
       'vendor': {}}}}
    nmScan.scan(hosts='192.168.100.16', arguments='-sP')
    >>
    {'nmap': {'command_line': 'nmap -oX - -sP 192.168.100.16',
      'scaninfo': {},
      'scanstats': {'downhosts': '0',
       'elapsed': '0.01',
       'timestr': 'Mon Apr 30 17:40:19 2018',
       'totalhosts': '1',
       'uphosts': '1'}},
     'scan': {'192.168.100.16': {'addresses': {'ipv4': '192.168.100.16'},
       'hostnames': [{'name': '', 'type': ''}],
       'status': {'reason': 'syn-ack', 'state': 'up'},
       'vendor': {}}}}
    

    可以看到,和直接使用 nmap 一样,如果存在主机在线,能显示主机名字,否则主机名字为空,这样我们就可以通过判断结果是否存在主机名来筛选在线的主机。判断主机名是否存在的方法也很简单,我们根据上面的输出获取 name 字段,判断其是否为空即可,代码如下:

    mScan['192.168.100.16']['hostnames'][0]['name']
    >>
    '' # 因为 192.168.100.16 不存在在线主机,所以输出为空
    

    接下来,我们只需要一个内网 IP 列表,然后逐个扫描判断即可,获取 IP 列表也很简单,一般简单的网络环境下我们可以先获取网关地址,然后通过网关地址来拼接 IP 列表,具体代码如下:

    import netifaces
    gateway = netifaces.gateways()['default'][netifaces.AF_INET][0]
    gateway
    >>
    '192.168.100.1'
    # 拼接 IP 列表
    ip_lists = []
    for ip in range(1, 256):
      ip_lists.append('{}{}'.format(gateway[:-1], ip))
    

    最后,我们根据上面的IP列表逐个遍历使用 nmap 扫描即可。

    完整代码

    我们整合一下上面的思路,整理一下代码,以下为完整代码的展示:

    # filename: lan_ip_scan.py
    import netifaces
    import nmap
    
    
    def get_gateways():
        return netifaces.gateways()['default'][netifaces.AF_INET][0]
    
    def get_ip_lists(gateway):
        ip_lists = []
        for i in range(1, 256):
            ip_lists.append('{}{}'.format(gateway[:-1], i))
        return ip_lists
    
    def scan_ip_survial(ip):
        nmScan = nmap.PortScanner()
        nmScan.scan(hosts=ip, arguments='-sP')
        if nmScan[ip]['hostnames'][0]['name']:
            return {'IP Address:': ip,
                    'Hostname:': nmScan[ip]['hostnames'][0]['name']
                   }
        else:
            return None
    
    def get_all_survial_hosts():
        survial_hosts = []
        gateway = get_gateways()
        ip_lists = get_ip_lists(gateway)
        for ip in ip_lists:
            scan_rst = scan_ip_survial(ip)
            if scan_rst:
                survial_hosts.append(scan_rst)
                print(scan_rst)
        return survial_hosts
    
    
    if __name__ == '__main__':
        get_all_survial_hosts()
    

    接下来,我们尝试以下运行脚本看一下结果:

    # 因隐私问题,屏蔽结果的 host 名称
    python lan_ip_scan.py
    {'IP Address:': '192.168.100.1', 'Hostname:': 'ch***n'}
    {'IP Address:': '192.168.100.17', 'Hostname:': 'MIMAX-xiaomishouji'}
    {'IP Address:': '192.168.100.18', 'Hostname:': '*****'}
    {'IP Address:': '192.168.100.19', 'Hostname:': '***MBP'}
    {'IP Address:': '192.168.100.20', 'Hostname:': '***iPhone'}
    {'IP Address:': '192.168.100.21', 'Hostname:': '***-xiaomishouji'}
    {'IP Address:': '192.168.100.22', 'Hostname:': '****-iPhone'}
    {'IP Address:': '192.168.100.23', 'Hostname:': 'raspberrypi'}
    {'IP Address:': '192.168.100.26', 'Hostname:': '**'}
    

    到这里为止,我们就已经完成我们使用 Python 查看局域网内存活主机的探索以及代码编写。我们在本文中探讨了 nmap 及相关 python模块的安装,简单的 nmap 扫描使用,以及一些脚本编写的小技巧,希望本文能对你有用,如果文中有技术或理论的错误,欢迎指出交流,共同探究进步。

    相关文章

      网友评论

        本文标题:使用 Python 查看局域网内存活主机

        本文链接:https://www.haomeiwen.com/subject/pkxtrftx.html