使用 Python 查看局域網(wǎng)內(nèi)存活主機

概述

當我們的網(wǎng)絡(luò)首次接入一些新的設(shè)備,而且這些設(shè)備不是像手機、電腦一類的有屏幕設(shè)備,如服務(wù)器、Nas、樹莓派等硬件,我們想要通過網(wǎng)絡(luò)連接控制,但是并不知道設(shè)備的 IP 地址,這時,我們就需要掃描網(wǎng)絡(luò)找到我們目標硬件設(shè)備的 IP 地址。

常用的方法如進入路由器管理后臺,我們就可以找到我們的設(shè)備 IP 地址,或者使用現(xiàn)成的軟件,如 Adbanced IP Scanner 軟件,也可以掃描網(wǎng)絡(luò)實現(xiàn)我們想要的目標。但是,實際上我們真正需要的僅僅是要知道設(shè)備名和 IP 地址即可,無論登錄路由器還是使用軟件,都顯得有點牛刀殺雞的感覺,因此我們嘗試使用 Python 編寫一個查找內(nèi)網(wǎng)存活在線主機IP地址的腳本。
關(guān)鍵詞 Python nmap 局域網(wǎng) 存活主機IP

NMAP

Nmap 是一款用于網(wǎng)絡(luò)發(fā)現(xiàn)和安全審計的網(wǎng)絡(luò)安全工具,可以檢測目標主機是否在線、端口開放情況、偵測運行的服務(wù)類型及版本信息、偵測操作系統(tǒng)與設(shè)備類型等信息。

在使用之前,我們需要先安裝 Nmap 軟件。對于 WIndow 系統(tǒng),可以登錄 Nmap 官網(wǎng)下載頁面 下載相應(yīng)版本安裝即可。

對于 MacOS 系統(tǒng),可以使用 HomeBrew 安裝,具體方法如下:

brew update
brew install nmap

對于 Ubuntu/Linux,可以使用 apt 來安裝,具體方法如下:

sudo apt install nmap

完成 nmap 軟件安裝后,我們在繼續(xù)安裝 python 模塊,具體方法如下:

pip install nmap
pip install python-nmap

除此之外,為了我們后面代碼的方便,我們還需要安裝一個 netifaces 模塊,具體方法如下:

pip instal netifaces

腳本代碼詳解

首先,我們可以直接使用 nmap 工具來掃描局域網(wǎng),操作如下:

# 假設(shè)本地 ip 地址范圍為 192.168.100.1 ~ 192.168.100.255
nmap 192.168.100.1-255 -sP
>>
(...省略部分內(nèi)容...)
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).
(...省略部分內(nèi)容...)

我們可以看到,nmap 會把所有 ip 地址都掃描一遍,然后把掃描結(jié)果輸出,如果主機在線,那么就能看到主機名和其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 參數(shù),nmap 會掃描該IP的所有端口,我們可以從結(jié)果看到我的這一只小米手機開放的端口。

接下來,使用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 一樣,如果存在主機在線,能顯示主機名字,否則主機名字為空,這樣我們就可以通過判斷結(jié)果是否存在主機名來篩選在線的主機。判斷主機名是否存在的方法也很簡單,我們根據(jù)上面的輸出獲取 name 字段,判斷其是否為空即可,代碼如下:

mScan['192.168.100.16']['hostnames'][0]['name']
>>
'' # 因為 192.168.100.16 不存在在線主機,所以輸出為空

接下來,我們只需要一個內(nèi)網(wǎng) IP 列表,然后逐個掃描判斷即可,獲取 IP 列表也很簡單,一般簡單的網(wǎng)絡(luò)環(huán)境下我們可以先獲取網(wǎng)關(guān)地址,然后通過網(wǎng)關(guān)地址來拼接 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))

最后,我們根據(jù)上面的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()

接下來,我們嘗試以下運行腳本看一下結(jié)果:

# 因隱私問題,屏蔽結(jié)果的 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:': '**'}

到這里為止,我們就已經(jīng)完成我們使用 Python 查看局域網(wǎng)內(nèi)存活主機的探索以及代碼編寫。我們在本文中探討了 nmap 及相關(guān) python模塊的安裝,簡單的 nmap 掃描使用,以及一些腳本編寫的小技巧,希望本文能對你有用,如果文中有技術(shù)或理論的錯誤,歡迎指出交流,共同探究進步。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容