Kali Linuxによる高度なネットワーク調査と脆弱性スキャンの実践

サービスの指紋情報(バナー)の取得と特定

ターゲットシステム上のアクティブなポートを特定した後、次の段階はそれらのポートで稼働しているサービスやバージョンを正確に特定することです。これを「フィンガープリンティング」と呼びます。単にポートが開いていることを知るだけでなく、具体的なソフトウェアとバージョンを知ることで、既知の脆弱性を特定し、攻撃の成功率を高めることができます。

Netcatを用いたバナーグラビング

Netcatは汎用的なネットワークユーティリティですが、単純な接続テストだけでなく、サービスバナーの取得にも利用できます。多くの古いサーバーやデフォルト設定のサービスは、接続時にソフトウェア名やバージョン情報を自動的に応答します。

以下のコマンドは、ターゲットの特定ポートに接続し、返ってきた初期応答メッセージを表示します。

nc -vn 192.168.1.10 22

このコマンドを実行すると、SSHサービスであれば「SSH-2.0-OpenSSH_...」といったバナーが表示されます。-vは詳細表示、-nはDNS解決を避けるオプションです。同様にFTPやSMTPなどのポートに対しても実行することで、サービスの種類を特定できます。

Pythonによる自動バナー収集スクリプト

手動で接続するのは非効率なため、Pythonのsocketモジュールを使用して自動化します。以下のスクリプトは、指定したIPアドレスのポート範囲をスキャンし、バナーが取得できる場合にのみ表示します。

#!/usr/bin/env python
import socket
import sys
import select

def scan_banners(target_ip, start_port, end_port):
    print(f"[*] Scanning {target_ip} from port {start_port} to {end_port}...")
    for port in range(start_port, end_port + 1):
        try:
            # ソケットの作成とタイムアウト設定
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(1)
            s.connect((target_ip, port))
            
            # 読み取り可能なデータがあるか確認
            ready = select.select([s], [], [], 1)
            if ready[0]:
                banner = s.recv(1024).decode().strip()
                print(f"[+] Port {port}/tcp OPEN: {banner}")
            s.close()
        except Exception:
            pass

if __name__ == "__main__":
    if len(sys.argv) != 4:
        print("Usage: ./scan_banners.py [IP] [Start Port] [End Port]")
        sys.exit(1)
    
    target = sys.argv[1]
    p_start = int(sys.argv[2])
    p_end = int(sys.argv[3])
    scan_banners(target, p_start, p_end)

Nmapと高度なツールによるサービス検出

単純なバナー取得に加え、Nmapのサービス検出機能(-sV)は、プローブパケットを送信し、その応答をデータベースと照合することで、より正確なバージョン特定を行います。

nmap -sV 192.168.1.10 -p 80,443,22

また、AmapやDmitryのようなツールも同様の目的で使用できます。特にAmapは、アプリケーション層のプロトコルを識別するのに特化しており、バナー取得と組み合わせることで効果を発揮します。

オペレーティングシステムの識別

ターゲットのOSを特定することは、カーネルレベルの脆弱性を特定する上で重要です。主にTCP/IPスタックの実装の違い(TTL値、ウィンドウサイズ、フラグの挙動など)を利用して推測を行います。

Scapyを用いたTTL分析

WindowsとLinuxでは、ICMPパケットのデフォルトのTTL(Time To Live)値が異なります。一般的に、Linux系は64、Windows系は128です。Scapyを使用してICMP Echo Requestを送信し、返ってきたパケットのTTLを確認することで、大まかなOS判別が可能です。

from scapy.all import *

target_ip = "192.168.1.10"
# ICMPパケットを送信し、最初の応答を取得
resp = sr1(IP(dst=target_ip)/ICMP(), timeout=2, verbose=0)

if resp:
    ttl_value = resp[IP].ttl
    if ttl_value <= 64:
        print(f"Target {target_ip} is likely Linux/Unix (TTL: {ttl_value})")
    else:
        print(f"Target {target_ip} is likely Windows (TTL: {ttl_value})")
else:
    print("No response received.")

NmapとxProbe2による能動的OS検出

Nmapの-Oオプションは、複雑なプローブパケットのスイートを使用してOSを特定します。これにより、単なるTTL値以上の精度でOSとバージョンを推測できます。同様に、xProbe2もICMPやTCPの挙動の細かな違いを利用してOSを特定しますが、Nmapほど署名データベースが更新されていない場合があります。

nmap -O 192.168.1.10

p0fによる受動的OS識別

p0fは能動的にパケットを送信せず、ネットワーク上を流れるパケットをキャプチャして分析する「受動的」なツールです。これにより、検知されることなくターゲットのOSを特定できます。通常、ARPスプーフィング(Ettercapなどを使用)と組み合わせ、ターゲットのトラフィックを観察可能な状態にしてから実行します。

SNMP情報の収集と分析

Simple Network Management Protocol (SNMP) は、ネットワーク機器を管理するために使用されますが、デフォルトのコミュニティ文字列(パスワードのようなもの)「public」や「private」が設定されているままのデバイスが多く存在します。これらを悪用すると、デバイスの詳細情報やネットワーク構成を取得できます。

onesixtyoneは、コミュニティ文字列を総当たりで試すツールであり、snmpwalkは正しいコミュニティ文字列が分かった後に、MIBツリーを走査して詳細情報を取得するために使用されます。

# コミュニティ文字列の推測
onesixtyone 192.168.1.1 public

# 情報の取得
snmpwalk -c public -v 2c 192.168.1.1 iso.3.6.1.2.1.1

ファイアウォールとパケットフィルタの検出

ファイアウォールの存在と設定を特定することは、スキャン結果の解釈や回避策の検討に不可欠です。特にステートフルインスペクションを行うファイアウォールは、接続の状態に基づいてパケットをフィルタリングします。

Scapyによるステートフル検出のロジック

通常、接続を開始するSYNパケットをドロップし、既存の接続に関連するACKパケットを受け入れる(またはRSTで応答する)場合、ステートフルなフィルタリングが行われている可能性があります。Scapyを使用して、SYNパケットとACKパケットを個別に送信し、その応答の違いを分析することでこれを検出します。

ロジックの例:

  • SYNに応答なし、ACKにRST応答:インバウンド接続はブロックされているが、アウトバウンドは許可されている。
  • SYNとACKの両方にRST応答:フィルタリングなし(ポートは閉じている)。
  • 両方に応答なし:ステートレスなフィルタリング、またはホストダウン。

NmapのACKスキャン

Nmapの-sAオプション(ACKスキャン)は、ファイアウォールのルールセットを識別するために使用されます。このスキャンはTCP接続を確立しようとしないため、ステートフルファイアウォールを通過しやすく、ポートが「フィルタリングされている」か「非フィルタリング」かを判別するのに役立ちます。

nmap -sA 192.168.1.10

脆弱性スキャンの実践

サービスとOSの特定が完了したら、既知の脆弱性の存在を自動的にスキャンします。これにより、手動での調査時間を大幅に短縮できます。

Nmapスクリプトエンジン(NSE)による脆弱性検出

NSEには、多数の脆弱性検出スクリプトが含まれています。カテゴリが「vuln」であるスクリプトを使用して、ターゲットシステム上の既知の脆弱性(例:MS08-067、Heartbleedなど)をチェックできます。

nmap --script=vuln 192.168.1.10

特定のスクリプトを実行するには、--scriptオプションでスクリプト名を指定します。

Metasploit Frameworkの補助モジュール

Metasploitには、特定のサービスや脆弱性をスキャンするための補助(auxiliary)モジュールが多数用意されています。これらはMSFconsoleから検索して実行します。例えば、SMBの脆弱性をスキャンするモジュールなどがあります。

msfconsole
use auxiliary/scanner/smb/smb_version
set RHOSTS 192.168.1.0/24
run

Nessusによる包括的なスキャン

Nessusは業界標準の脆弱性スキャナです。Webインターフェースからスキャンポリシー(どのチェックを行うか、認証情報を使うかなど)を作成し、ターゲットを指定してスキャンを実行します。また、CUIのnessuscmdを使用して、特定のプラグインIDを指定した単体チェックを行うことも可能です。

/opt/nessus/bin/nessuscmd -i 19506 192.168.1.10

脆弱性の検証:HTTPとICMP

スキャナで脆弱性が検出された場合、実際にエクスプロイト可能かを確認するために、単純な検証を行うことがあります。

HTTPリスナーによる検証

リモートコード実行(RCE)の脆弱性がある場合、ターゲットに対して攻撃コードを実行し、攻撃者のサーバーへHTTPリクエストを送らせることで、実行権限を確認できます。以下のPythonスクリプトは、単純なHTTPサーバーとして機能し、受信したリクエストの送信元IPを記録します。

#!/usr/bin/env python
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 8080))
server.listen(5)
print("[*] Listening on port 8080 for incoming connections...")

while True:
    client, addr = server.accept()
    print(f"[+] Connection received from: {addr[0]}")
    request = client.recv(1024)
    client.close()

ICMPによる検証

HTTPがブロックされている環境では、ターゲットに攻撃者のIPアドレスに対してping(ICMP Echo Request)を実行させ、それを受信することで検証します。Scapyを使用して特定のIPからのICMPパケットを監視し、ターゲットからPingが返ってきた場合、コマンド実行が成功したと判断できます。

タグ: Kali Linux Nmap Scapy Python Netcat

8月2日 06:03 投稿