返回文章列表

Python網路掃描滲透測試技術實踐

本文探討使用 Python 進行網路掃描和滲透測試的技術實務,涵蓋 Ping 掃描、TCP 掃描以及多執行緒效能最佳化等關鍵導向。文章首先介紹 Ping 掃描的基本原理和 Python 實作,接著探討 TCP 掃描的流程和程式碼範例,最後講解如何利用多執行緒技術提升掃描效率,並提供 Linux

資安 Web 開發

網路掃描是滲透測試流程中不可或缺的環節,用於識別目標網路中的活動主機和開放埠。本文將逐步講解如何使用 Python 實作 Ping 掃描和 TCP 掃描,並探討如何利用多執行緒技術提升掃描效率。首先,我們會介紹 Ping 掃描的原理和基本 Python 實作,包括使用 os 模組執行系統 Ping 命令和跨平台程式碼的撰寫。接著,我們將深入 TCP 掃描,根據 TCP 三次握手原理,使用 socket 模組建立 TCP 連線,並判斷目標埠是否開放。最後,針對大規模網路掃描的效能瓶頸,我們將引入多執行緒技術,並提供多執行緒 Ping 掃描和 TCP 掃描的 Python 程式碼範例,同時分析 Linux 環境下使用原始通訊端和 ICMP 封包的高效能掃描器實作。

網路掃描與滲透測試:Python實務應用

網路掃描是指一系列調查主機狀態、主機型別、開放埠及執行服務的程式。這是情報收集的一部分,攻擊者藉此建立目標組織的輪廓。

如何檢查網路中的活動主機

Ping掃描涉及向主機傳送ICMP ECHO請求。如果主機活動,它將傳回ICMP ECHO回應。作業系統的Ping命令提供了檢查主機是否活動的功能。

Ping掃描原理

Ping掃描用於透過傳送ICMP ECHO請求和ICMP ECHO回應來識別活動主機的IP位址範圍。攻擊者或滲透測試者可以從子網路和網路位址計算網路範圍。

使用Python實作Ping掃描

以下是一個簡單的Python程式碼範例,用於Ping掃描:

import os

response = os.popen("ping -n 1 10.0.0.1").readlines()
for line in response:
    print(line)

這個程式碼使用了os模組來執行作業系統的Ping命令,並讀取命令的輸出結果。

程式碼解密:

  1. import os:匯入os模組,以便能夠執行作業系統命令。
  2. response = os.popen("ping -n 1 10.0.0.1").readlines():使用os.popen()函式執行Ping命令,並將輸出結果讀取到response變數中。-n 1引數指定傳送一個ICMP ECHO請求包。
  3. for line in response: print(line):遍歷response中的每一行輸出結果,並將其列印出來。

Ping掃描的改進

為了使Ping掃描更加高效和易於閱讀,我們需要對程式碼進行改進,使其能夠跨平台執行並產生易於閱讀的輸出結果。

範例程式碼:

import os
import platform

def ping_ip(ip_address):
    if platform.system().lower() == 'windows':
        ping_cmd = f'ping -n 1 {ip_address}'
    else:
        ping_cmd = f'ping -c 1 {ip_address}'
    
    response = os.popen(ping_cmd).readlines()
    for line in response:
        print(line.strip())

# 範例使用
ping_ip('10.0.0.1')

程式碼解密:

  1. import osimport platform:匯入必要的模組。
  2. def ping_ip(ip_address)::定義一個函式,用於Ping指定的IP位址。
  3. if platform.system().lower() == 'windows'::檢查作業系統型別,以確定使用的Ping命令引數。
  4. ping_cmd = f'ping -n 1 {ip_address}'(Windows)或 ping_cmd = f'ping -c 1 {ip_address}'(其他作業系統):根據作業系統型別建構Ping命令。
  5. response = os.popen(ping_cmd).readlines():執行Ping命令並讀取輸出結果。
  6. for line in response: print(line.strip()):列印輸出結果,每行去除前後空白字元。

網路掃描與滲透測試的下一步

在下一章中,我們將探討如何使用TCP掃描器來檢測遠端主機上執行的服務。透過結合Ping掃描和TCP掃描,我們可以更全面地瞭解目標網路的拓撲結構和潛在的安全風險。

掃描滲透測試章節 2:網路掃描與TCP掃描實作

在前一章節中,我們探討了使用ICMP ECHO請求和回應來進行網路掃描的技術。然而,許多使用者會關閉ICMP ECHO回應功能或使用防火牆來阻擋ICMP封包,這使得我們的ping掃描器無法正常運作。在這種情況下,我們需要使用TCP掃描技術。

TCP掃描概念及其Python指令碼實作

TCP掃描根據TCP的三次握手原理。建立TCP連線的過程包括以下三個步驟:

  1. 使用者端傳送一個包含SYN旗標的段,請求伺服器啟動一個會話。
  2. 伺服器回應一個包含ACK和SYN旗標的段。
  3. 使用者端回應一個包含ACK旗標的段。

TCP掃描Python指令碼

import socket
from datetime import datetime

net = raw_input("Enter the Network Address ")
net1 = net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(raw_input("Enter the Starting Number "))
en1 = int(raw_input("Enter the Last Number "))
en1 = en1 + 1

t1 = datetime.now()

def scan(addr):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket.setdefaulttimeout(1)
    result = sock.connect_ex((addr, 135))
    if result == 0:
        return 1
    else:
        return 0

def run1():
    for ip in xrange(st1, en1):
        addr = net2 + str(ip)
        if scan(addr):
            print(addr, "is live")

run1()

t2 = datetime.now()
total = t2 - t1
print("scanning complete in ", total)

程式碼解密:

  • 首先,我們匯入必要的模組,包括socketdatetimesocket模組用於建立網路連線,而datetime用於計算掃描所花費的時間。
  • 程式碼要求使用者輸入網路地址、起始數字和最後數字,分別用於定義掃描的IP範圍。
  • scan函式使用socket建立到特定IP和埠(本例中為135)的連線。如果連線成功(即埠開放),函式傳回1,否則傳回0。
  • run1函式遍歷指定的IP範圍,對每個IP呼叫scan函式。如果scan傳回1,表示該IP是活躍的,並列印出來。
  • 最後,程式碼計算並列印掃描所花費的總時間。

網路掃描與TCP掃描的比較

  • 網路掃描(ping掃描)根據ICMP協定,可能被防火牆阻擋或被使用者端關閉ICMP回應功能而失效。
  • TCP掃描則透過嘗試建立TCP連線來判斷主機是否活躍,不依賴ICMP,因此在某些情況下更為可靠。

提升網路掃描效率:多執行緒技術的應用

在網路安全掃描與滲透測試中,掃描網路主機是一項基本任務。然而,傳統的順序掃描方式往往效率低下,尤其是在面對龐大的 IP 地址範圍時。本章將探討如何利用 Python 的多執行緒技術來提升網路掃描的效率,並介紹一個結合多執行緒的 Ping Sweep 掃描器實作。

為何需要多執行緒?

在前面的章節中,我們已經實作了一個簡單的 Ping Sweep 掃描器和一個 TCP 掃描器。雖然這兩個工具能夠完成掃描任務,但它們都是以單執行緒的方式運作。當面對大量 IP 地址時,這種方式會導致掃描過程非常緩慢。例如,掃描 60 個主機時,Ping Sweep 掃描器需要 2 分鐘 35 秒,而 TCP 掃描器也需要接近 1 分鐘。如此低下的效率顯然無法滿足實際需求。

多執行緒技術的優勢

Python 提供了多執行緒(Multithreading)技術,可以有效地提升程式的執行效率。透過將任務分配給多個執行緒平行處理,可以大幅縮短整體執行時間。在網路掃描的場景中,多執行緒技術可以同時對多個 IP 地址進行掃描,從而顯著提升掃描速度。

多執行緒 Ping Sweep 掃描器的實作

下面是一個結合多執行緒技術的 Ping Sweep 掃描器實作範例:

import datetime
import collections
import threading

# 定義網路位址輸入
net = input("Enter the Network Address ")
net1 = net.split('.')
a = '.'

# 取得起始和結束 IP 地址範圍
net2 = input("Enter the Starting Number ")
net3 = int(net2)
net4 = input("Enter the Last Number ")
net5 = int(net4)

# 計算總共需要掃描的 IP 地址數量
net_final = int(net5) - int(net3)

# 建立有序字典用於儲存結果
dic = collections.OrderedDict()

# 定義 Ping 函式
def scan(addr):
    # 省略 Ping 操作的具體實作
    output = os.popen("ping -n 1 " + addr).read()
    if 'TTL=' in output:
        dic[addr] = output

# 多執行緒類別定義
class myThread(threading.Thread):
    def __init__(self, start, end):
        threading.Thread.__init__(self)
        self.start = start
        self.end = end

    def run(self):
        for i in range(self.start, self.end):
            addr = net1[0] + a + net1[1] + a + net1[2] + a + str(i)
            scan(addr)

# 設定每個執行緒處理的 IP 地址數量
num_threads = 20
thread_list = []

# 建立並啟動多個執行緒
for i in range(num_threads):
    start = net3 + i * (net_final // num_threads)
    end = start + (net_final // num_threads)
    thread = myThread(start, end)
    thread_list.append(thread)
    thread.start()

# 等待所有執行緒完成
for thread in thread_list:
    thread.join()

# 列印存活主機的 IP 地址
for key in dic:
    print(key, '
---
> Live')

print('Number of Threads active:', threading.active_count())
print('Exiting Main Thread')

程式碼解析:

  1. 輸入網路位址與範圍:首先,程式要求使用者輸入網路位址和需要掃描的 IP 地址範圍。
  2. 計算總共需要掃描的 IP 地址數量:根據輸入的起始和結束數字,計算需要掃描的 IP 地址總數。
  3. 定義 Ping 函式scan 函式負責對指定的 IP 地址執行 Ping 操作,並將結果儲存在有序字典 dic 中。
  4. 多執行緒類別myThread 繼承自 threading.Thread,用於定義每個執行緒的行為。每個執行緒負責掃描一段 IP 地址範圍。
  5. 建立並啟動多個執行緒:根據設定的執行緒數量,將整個 IP 地址範圍劃分為多段,每段由一個執行緒負責掃描。
  6. 等待所有執行緒完成:主程式等待所有執行緒完成後,再列印存活主機的 IP 地址。

多執行緒技術的優勢與應用場景

透過引入多執行緒技術,Ping Sweep 掃描器的效率得到了顯著提升。在相同的測試環境下,多執行緒版本的掃描器能夠在更短的時間內完成對大量 IP 地址的掃描。

這種技術不僅適用於 Ping Sweep 掃描器,也可以應用於其他需要大量網路操作的場景,如 TCP 埠掃描、網路服務探測等。

掃描滲透測試章節 2:高效能 IP 掃描器的實作與最佳化

在前一章節中,我們探討了使用多執行緒技術實作基本的 IP 掃描器。本章節將深入討論如何進一步最佳化掃描器的效能,特別是在 Linux 環境下。

多執行緒 TCP 掃描器的實作

首先,我們來分析一個使用 TCP 掃描方法的多執行緒程式。這段程式碼展示瞭如何透過多執行緒技術提高掃描效率。

import threading
import time
import socket

def scan(ip):
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, 80))
        print(f"{ip} --> Live")
    except Exception as e:
        pass
    finally:
        s.close()

def main():
    network = input("Enter the Network Address ")
    start = int(input("Enter the starting Number "))
    end = int(input("Enter the last Number "))
    num_threads = 4
    total_ips = end - start + 1
    total_threads = total_ips // num_threads

    threads = []
    for i in range(num_threads):
        thread = threading.Thread(target=scan_ips, args=(network, start + i * total_threads, start + (i + 1) * total_threads - 1))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    print("Exiting Main Thread")

if __name__ == "__main__":
    main()

程式碼解析:

  1. 多執行緒管理:程式碼中使用了 threading 模組來建立和管理多個執行緒,每個執行緒負責掃描指定範圍內的 IP 位址。
  2. TCP 掃描scan 函式嘗試與目標 IP 的特定埠(此例中為 80)建立 TCP 連線,以判斷該 IP 是否活躍。
  3. IP 範圍劃分:根據使用者輸入的起始和結束 IP 號,將掃描任務分配給多個執行緒,以提高掃描效率。

Linux 環境下的高效能 IP 掃描器

在 Linux 環境下,我們可以利用原始通訊端(raw socket)和 ICMP 封包實作更高效的 IP 掃描。

程式碼範例:

import socket
import struct
import threading
import time

def send_ping(sock, ip):
    # 建立 ICMP echo 請求封包
    packet = struct.pack('!BBHHH', 8, 0, 0, 0, 1)
    packet = packet + b'abcdefgh'
    try:
        sock.sendto(packet, (ip, 0))
    except Exception as e:
        print(f"Error sending ping to {ip}: {e}")

def sniffing(sock):
    while True:
        try:
            data, addr = sock.recvfrom(1024)
            # 解析 ICMP 回應封包
            icmp_type, icmp_code = struct.unpack('!BB', data[20:22])
            if icmp_type == 0:  # ICMP echo 回應
                print(f"{addr[0]} --> Live")
        except Exception as e:
            pass

def main():
    # 建立原始通訊端
    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
    # 建立並啟動 sniffing 執行緒
    sniff_thread = threading.Thread(target=sniffing, args=(sock,))
    sniff_thread.daemon = True
    sniff_thread.start()

    # 傳送 ICMP echo 請求
    for ip in ips_to_scan:
        send_ping(sock, ip)

if __name__ == "__main__":
    main()

程式碼解析:

  1. 原始通訊端:使用 socket.SOCK_RAWsocket.IPPROTO_ICMP 建立原始通訊端,直接傳送和接收 ICMP 封包。
  2. ICMP echo 請求send_ping 函式建立並傳送 ICMP echo 請求封包到目標 IP。
  3. Sniffingsniffing 函式負責接收並解析 ICMP 回應封包,判斷目標主機是否活躍。