
こんにちは、セキュリティエンジニアの河村です。
今回はオライリー出版による「ポートスキャナ 自作ではじめるペネトレーションテスト」の書評をお届けします。本書はペネトレーションテストを初めとするセキュリティ業務では必須なツールと言えるポートスキャナについて、基本的な原理から説明してくれる内容です。
■ポートスキャナ自作ではじめるペネトレーションテスト―Linux環境で学ぶ攻撃者の思考
(株式会社ステラセキュリティ 小竹 泰一 著/O’REILLY JAPAN)
本の概要
セキュリティエンジニアが通常、業務でツールを用いるときはsocketモジュールやnmapなどの高度なツールを用います。しかしながら、それらのツールは、多くの人にとって高度に自動化されてるが故に中身がブラックボックスな部分があります。また、特殊なパケットの再現を行いたい場合などでは再現が難しいことがあります。
本書ではサイバー攻撃が具体的に行われるプロセスを表したフレームワーク、Unified Kill Chainの解説から始まり、ScapyというPythonライブラリを通してパケットレベルでSynスキャンなどを体験できるプラットフォームを用意してくれています。第三章以降ではNmap、Nessus、Metasploitとペンテスターにとって基本となるツールの用い方を通して、ペンテスターにとって必要不可欠な攻撃の手順を体系的に学べます。
章ごとの概要
以下に、本書の各章で特に注目したい内容をピックアップしてご紹介します。
第一章 攻撃者はいかにしてシステムを攻撃するのか
この章では攻撃者がシステムを侵害していく過程を具体的に学ぶことで、各種セキュリティ対策をより効率的に実施する方法を学びます。
攻撃者がシステムを侵害していく過程を学ぶことは、管理しているシステムの弱点を把握し、セキュリティ対策を効果的に実施する上で重要です。
本章では具体的な事例として2019年の7payが不正利用によりサービス停止となった事件※1、2021年、徳島県の病院で発生したランサムウェアによる電子カルテが閲覧不能になった事件※2、2009年から2010年の間にイランの核燃料施設を攻撃したStuxnet※3などが紹介されています。この中でもStuxnetの攻撃は特定の組織を狙って周到に準備した上で実行され、標的型攻撃と呼ばれます。
※1 「7pay」決済サービス、開始早々の大量不正アクセス,5500万円の被害
※2 徳島・鳴門の病院にサイバー攻撃 電子カルテにアクセスできず
※3 国家間サイバー戦争の幕開け イラン核施設を攻撃したマルウェア「Stuxnet」(2009~10年)
標的型攻撃の中でも特に高度で持続的に行われるものはAPT(Advanced Persistent Threat)攻撃と呼ばれたりもします。
現在進行形で行われているウクライナでの戦争では現実世界の軍事行動と一体化したハイブリッド攻撃が行われています。このことからわかるように、サイバー攻撃を制す者が現実の戦いをも制す時代になっています。
サイバー攻撃の進行をスケーリングした指標として有名なものがMITRE ATT&CK※4やUnified Kill Chain※5です。本書ではUnified Kill Chainを用いて説明します。このフレームワークを学ぶことでサイバー攻撃の過程をより分析して捉えることが可能になります。
※4 https://attack.mitre.org/
※5 https://www.unifiedkillchain.com/
サイバー攻撃における最初の段階である「初期の足場の確保」から解説します。
初期の足場の確保(Initial Foothold)
流れ:偵察⇒武器化⇒配送⇒ソーシャルエンジニアリング⇒攻撃⇒永続化⇒防衛回避⇒コマンド&コントロール
偵察 Reconnaissance
攻撃者は標的組織の情報を収集し、攻撃に活用出来る情報がないか調査します。この活動で用いる手法はOSINT(Open Source INTeligence)と呼ばれます。
この偵察フェーズは受動的偵察と能動的偵察の2種類に分類出来ます。受動的偵察は標的の組織にアクセスしないので、検知されるリスクが低いです。対して、DNS問い合わせ、Nmapなどのポートスキャン行為を行う能動的偵察は直接標的組織にアクセスするため、検知リスクがあります。Subdomain Takeover※6などの攻撃の実行可能性はこの段階でわかったりします。
武器化 Weaponization
偵察によって得た情報をもとに攻撃に必要な環境を準備するフェーズです。標的組織の環境に合わせてマルウェアを作ることもこのフェーズに含まれます。対象組織がセキュリティ対策を適切に行ってる場合、攻撃に工夫が必要となります。
このような際に必要である検知回避技術にはLOTL攻撃(Living Off The Land攻撃)があります。標的の端末にすでにインストールされているソフトウェアを活用して攻撃を行うことで、検知を回避する手法です。GTFOBins※7などにはこのような攻撃を行うのに有用なコマンドが記載されています。
※7 GTFOBins
配送 Delivery
武器化フェーズで作成したマルウェアを標的組織へ届けるフェーズです。攻撃者の手段として、メールやSNS、USBメモリなど様々な手段を用います。特に特徴的な手法として、
- 水飲み場型攻撃
- サプライチェーン攻撃
があげられます。
ソーシャルエンジニアリング Social Engineering
配送したマルウェアを、メールやSNS等での人を通した会話によって、能動的に起動する手法をソーシャルエンジニアリングと呼びます。ときにはマルウェアの起動をスキップして、直接クレデンシャルを狙う場合もあります。「スミッシング」、「スピアフィッシング」などもソーシャルエンジニアリングにあたります。
攻撃 Exploitation
標的組織にマルウェアを能動的に実行させる方法は前述のソーシャルエンジニアリングの他に「攻撃」があります。例えば、標的にRCE(Remote Code Execution)の脆弱性があれば、それを用いてシステム内でマルウェアを実行させられます。
攻撃フェーズ以前からIPアドレスを偽造したり、SOCKS5プロキシ、Torネットワーク、VPNなどを用いて送信元を偽るケースも多いです。
永続化 Persistence
攻撃者は、システムへの持続的なアクセスの獲得を目的としている場合があり、この場合永続化フェーズが必要になります。永続化の手法として代表的なものに以下の三つがあげられます。
- アカウントの操作⇒サーバへの公開鍵の追加など
- ブートまたはログオンの自動開始実行⇒Linuxでのrcコマンド、Windowsでのスタートアップなど
- スケジュールされたタスク/ジョブ⇒cronなど
防衛回避 Defense Evasion
攻撃者がセキュリティ製品に検知されないようにとる対策のことです。様々な手法がありますが、本書では5章でMetasploitを用いた防衛回避方法を解説します。
コマンド&コントロール Command and Control
「初期の足場の確保」の最後のフェーズとして、マルウェアは攻撃者の用意したC2サーバ※8との通信を確立します。
これらのプロセスではドメインフロンティングやDNSトンネリングなどの隠蔽技術が用いられることがあります。
※8 C2サーバとは
標的ネットワーク内での被害拡大
標的となるネットワークにアクセスした後、目的の資産を獲得する際の活動をUnified Kill Chainでは「ネットワークを介した拡大」(Network Propagation)と名付けています。
ネットワークを介した拡大フェーズは以下のようなプロセスで構成されています。
流れ:ピボッティング⇒探索⇒権限昇格⇒実行⇒クレデンシャルアクセス⇒横展開
ピボッティング Pivoting
攻撃者は必要に応じて侵害した端末を通じて、直接アクセス出来なかった他のネットワークへ通信をトンネリングし、これをピボッティングといいます。横展開と異なり端末間の移動のみをUnified Kill Chainではピボッティングとしてます。
探索 Discovery
攻撃者が現在ログインしているシステムとそのシステムが接続している内部ネットワークに関する情報を得るために行う活動を探索と言います。検知されないようにPowerShell等、OSにデフォルトで備わってるツールが多用されます。
権限昇格 Privilege Escalation
取得出来た権限が制限されたものだった場合、脆弱性を利用してより高いレベルの権限への昇格を試みます。この活動を権限昇格と呼びます。
実行 Execution
コードを実行するのに必要な権限を得た攻撃者は攻撃を実行します。
クレデンシャルアクセス
攻撃者は目的に応じて、クレデンシャルを盗み出そうとします。この活動をクレデンシャルアクセスと呼びます。
⇒ わざわざ侵入行為を働かなくても、GitHubなどで公開されてるリポジトリから機微な情報を取得出来る場合もあります。
横展開 Lateral Movement
侵入した端末から、同一ネットワーク内の他の端末の権限の取得を試みます。
目的の実行 (Action on Objectives)
ここまでのプロセスで攻撃者は標的のネットワークへの足場を広げ、多大な被害を拡大できました。このあと、入手できたデータを収集し、持ち出していきます。
流れ:収穫⇒持ち出し⇒影響⇒目的
収穫 Collection
攻撃者は目的に応じて標的からデータを収集します。システム内のデータ以外にSamba、クラウドストレージから収集したり、キーロガー、Webカメラなどを用いる場合もあります。
持ち出し Exfiltration
目的達成のために収集されたデータを持ち出します。検知回避のためにデータを圧縮・暗号化することも多いです。IDS・IPS回避のための工夫も行われます。この際以下の技術が用いられます。
- Smash&Grab
- Low&Slow
影響 Impact
攻撃者が標的のビジネスプロセスや運用プロセスを操作することで、その可用性や完全性を損なわせる活動です。
目的 Objectives
攻撃者の社会的・技術的な最終目標のことです。以下に例をあげます。
- 知的財産(ソースコードなど)の奪取
- 奪取したアカウントの販売
- ランサムウェアによる身代金の獲得
第二章 Scapyでポートスキャナを自作して動作原理を知ろう
ポートスキャナは前章のUnified Kill Chainの中では「初期の足場の確保」の「偵察」にあたる行為です。この章ではポートスキャナを「Scapy※9」というライブラリを用いて自作することを通して、パケットの操作方法を学んでいき、実在する脆弱性に対する攻撃も体験します。
実際の業務では基本的にポートスキャナはNmapで十分なのですが、ポートスキャナの仕組みを理解するには自作することは非常に有用です。このようなことを学ぶとセキュリティエンジニアにとって必要なPoCのコードの実装を素早くできたりします。
環境構築の細かいことについては本書を読んで欲しいです。また、ここに掲載してるソースコードは本文が冗長にならないよう概要のみなので、そのままでは動作しないものがあることはご了承ください。更に、外部に対してこれらのコードを実行することは法に抵触する可能性があるため、必ず自分の管理下のネットワークで試してください。
ここでは大まかな流れと概要を伝えます。本書の実習環境は、Docker※10を用いており、Scapyが使えるコンテナと各種脆弱性を持ってるコンテナが用意されております。
※10 コンテナの基本
本書はDockerの知識がない方でも環境を十分に扱えるよう基本レベルからDockerの解説が載っているので安心です。また、Dockerの性質上、Windows、Mac、Linuxのどれでも検証環境は動作します。
Scapyに入門する
Scapyは、Pythonでネットワークパケットを操作するための強力なライブラリです。パケットの生成、送信、解析、操作などを簡単に実現でき、ネットワークテストやセキュリティ分析に広く利用されています。使用の仕方として、Pythonから呼び出す方法と、インタプリタから使用する方法があります。
- Pythonコードから使用する方法
from scapy.all import srl, IP, ICMP
のような形で必要な関数、クラスをインポートしてします。
- インタプリタから使用する方法
scapyを使用できる環境のコマンドラインから以下のコマンドを押下します(Linux、Macの場合)。
$ sudo scapy
インタプリタを終了する場合、exitと入力します。
パケットの送受信
ICMPを題材としたパケットの送受信が紹介されています。インタプリタ版の場合、以下のようにしてICMPパケットを作成します。
>>> req = IP(dst="10.8.9.3")/ICMP()
>>> req.show()
scapyの基本的な使い方は本書を実際に読むか、もしくは下記などを参考にしてください。
※11 Scapy入門 https://qiita.com/Howtoplay/items/4080752d0d8c7a9ef2aa
パケットキャプチャを行う
Scapyのsniff関数を用いるとパケットキャプチャが容易に実装できます。以下のようなコードを用います(詳細は本書P.50)。
from scapy.all import sniff
def print_packet(packet):
packet.show()
sniff(filter='icmp', prn=print_packet, count=5)
このPythonスクリプトを実行するとICMPパケットを待ち受けます。
TCP SYNスキャンをScapyで行う
SYNスキャンは、TCP 3ウェイハンドシェイクの特性を利用します。以下はその流れです。
3ウェイハンドシェイクの流れ
- SYNパケット送信スキャナーがターゲットにTCP SYNパケットを送信します。
- 応答の受信
- SYN/ACK: ポートが「オープン」の場合。
- RST: ポートが「クローズ」の場合。
- 応答なし: ポートが「フィルタリング」(ファイアウォールでブロック)されている場合。
- 接続の中断スキャナーは応答を受け取ると、接続を完了せずにRSTパケットを送信して接続を終了します。
SYNスキャンは接続を完全に確立しないため、高速で実行でき、ログに残りにくく比較的検出されづらいことが特徴です。
Scapyにおいては
syn_packet = IP(dst=dst_p)/TCP(dport=target_port, flags='S') # SYNパケットの作成
response_packet = srl(syn_packet) # パケットを送信する
のように記述することで、SYNパケットオブジェクトを作成出来ます。
これでSYNパケットを送信した後にSYN/ACKパケットが返ってくるかを判別するコードを追加すると、ポートが開いてるか判断出来ます。
if(response_packet.haslayer(TCP) and
response_packet[TCP].flags == "SA"):
print(f"TCP port {target_port} is open")
else:
print(f"TCP port {target_port} is closed")
TCP ConnectスキャンをScapyで行う
TCP Connectスキャンでは3ウェイハンドシェイクを最後まで行うので、SYNスキャンのときのコードにTCPの接続を正常に終了するためのFINパケットの送受信のコードも書き加えます。
3ウェイハンドシェイクを完了するにはシーケンス番号や確認応答番号の設定が必要です。Pythonを用いたら容易に実装できます。
パケットの確認
tcpdumpを使います。
$ sudo tcpdump port <port> and host <ip>
socketモジュールを使って実装する
より高性能なsocketモジュールならばTCP Connectスキャンの3ウェイハンドシェイクをより簡単に実装できます。
s = socket.socket()
errno = s.connect_ex((target_ip, target_port)) # これでTCP Connectを試みます
s.close()
特殊なパケットやパケット単位の実装はScapyが便利ですが、それ以外の場合はsocketモジュールが便利だったりします。
パケットを工作しないと攻撃出来ない脆弱性
以下の脆弱性の学習にはパケット単位でカスタマイズ可能なsocketモジュールのカスタマイズ性の高さがいきてきます。
ARPスプーフィング
ARPスプーフィング(ARP Spoofing)は、コンピュータネットワークにおける攻撃手法の一つで、偽のARP(Address Resolution Protocol)メッセージを送信して、通信を傍受したり改ざんしたりする攻撃です。
この攻撃を行う上で、ARP要求を送信し、偽のARP応答を送りつけてキャッシュを改ざんします。偽のARPパケットはScapyでは以下のようにして送信できます。
arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=dest_ip, op='is-at')
send(arp_response)
scapyモジュールのARPクラスでは以上のように、容易に改ざんされたARPパケットを作れます。
DoSを引き起こすCVE-2020-8617
CVE-2020-8617 は、BIND(Berkeley Internet Name Domain)に関連する重大な脆弱性です。BINDは最も広く使用されているDNSサーバーソフトウェアの一つで、この脆弱性を悪用されると、リモートの攻撃者がサービス拒否(DoS)攻撃を引き起こす可能性があります。
この脆弱性では細工されたTSIGリソースレコードを含むリクエストを用います。発見者はPython上でバイト列を組み立て、Socketモジュールで送信していますが、Scapyを用いるともっとシンプルに記述出来ます。
DNSRRTSIG(rrname="local-ddns", algo_name="hmac-sha256", rclass=255, mac_len=0, ac_data="", time_signed=0, fudge=300, error=16)
以上のコードの断片がペイロードの一部です。
第三章 デファクトスタンダードのポートスキャナNmap
Nmap※11の基本的な使い方は以下のような様々なソースで確認出来るので省略します。
※11 https://qiita.com/kenryo/items/1b49bddce44e9412638f
Nmapの機能を拡張するNSE
NmapにはスクリプトエンジンであるNSE(Nmap Scriting Engine)※12上で動くLua製スクリプトが付属してます。これらを使うことで、コマンド一つでブルートフォース攻撃などを行えます。
※12 NSEの使い方の参考
NSEの使用例:ミドルウェアへのログイン試行を行うスクリプト
$ nmap -p 22 --script ssh-brute 127.0.0.1
有名な脆弱性であるHeartbleedやPOODLE、EternalBlueなどをNSEで調査することも出来ます。
$ nmap -p 443 --script ssl-heartbleed example.com
第四章 既知脆弱性を発見できるネットワークスキャナ Nessus
Nessus※13の基本的な使い方は以下のような様々なソースから確認出来るので省略します。
※13 https://qiita.com/mefuku/items/d22a2747bcdb6ff19d75
ネットワークスキャナには他のものもたくさんあります。例として、CloudflareによるFlan Scan、GoogleによるTsunamiなどがあります。
Nmapとの使い分け
NessusのBasic Network ScanやAdvanced Scanでは脆弱性をスキャンする前段階でポートスキャンを行います。ただし、出力結果がNmapとは異なっていたりするので、使い分けとして、網羅性を重視するセキュリティベンダの場合、NessusとNmapを併用して両方の差分を確認する場合したりします。
第五章 攻撃コードを簡単に生成できるMetasploit Framework
MetasploitはRapid7社が開発してるペネトレーションテストツールです。無料版はCUIでしか基本的に使えませんが、有料版のMetasploit ProはGUIで操作できます。
Metasploitの基本的な使い方は以下のような様々なソースから確認出来るので省略します。
※14 https://zenn.dev/sanflat/articles/6c9b007c787035
第六章 攻撃者はどのように被害を拡大するか
Unified Kill ChainにおけるPost-Exploitationで行う行動をここでは解説しています。
ファイル読み込みを成功させたあと
標的端末のファイル読み込みが出来ただけでは、RCEが出来た場合と比べて出来ることが限られています。そこでまず、端末内の多数の重要なファイルを「収集」します。「収集」ファイルを元に、次のステップであるファイル書き込みに向けての権限昇格を目指します。
ファイル書き込みを成功させたあと
RCEへの発展や、マルウェアの書き込みを目指します。Unified Kill Chainでは「初期の足場の確保」の「永続化」にあたります。
以下が具体的に行うことの例です:
・Webシェルの配置
・SSH公開鍵の配置
・cronを用いた永続化と権限昇格
RCEを成功させたあと
RCEを成功させたということは、任意のコマンドが実行可能です。このフェーズで行いたいことを列挙します。
- コンテナエスケープ
⇒既知脆弱性の利用、Dockerソケットがマウントされてる場合、特権コンテナ - マルウェアの実行
⇒Vimプラグインによるキーロガー
⇒LD_PRELOADによる関数フック
C2フレームワークによる侵害した端末の管理
C2フレームワークは侵害した端末を遠隔操作するためのツールです。目的達成には侵略した端末をまとめて操ることが必要だったりするので、攻撃において有用な場合が多いです。
OSSのC2フレームワーク:
⇒Covenant、C3、Empire、PoshC2、Sliverなど
商用のC2フレームワーク:
⇒Brute Ratel C4、Cobalt Strikeなど
DBにアクセス出来たら
DBには重要な情報が格納されてることが多いため、DBにアクセスできる事は目的達成において重要です。
- DB内の情報の閲覧
- ファイル読み込み
- ファイル書き込み
- RCEを行う ⇒ PostgreSQLのCOPYコマンドなど
どのようにして他の端末へ被害を拡大させるか
ここまでのフェーズで目的を達成できなかった場合、組織が管理しているネットワーク上の他の端末への攻撃を試みます。その方法の例をあげます。
- メモリからのクレデンシャルの抽出
- 既存のセッションの活用
⇒ ControlMasterによって既存のSSH接続を活用するなど
⇒ 二回目以降のSSH接続ではPWの入力が不要な場合がある - 認証情報が弱いサーバや既知脆弱性が存在する端末への攻撃
⇒後者はスキャナで発見できることがある
本書を読んで
第一章で学ぶUnified Kill Chainはペネトレーションテストのフレームワークとしてはかなり詳細な部類です。これの各フェーズを日本語で丁寧に解説してる文書はインターネット上には少なく、なので本書の解説は貴重で有用だと思いました。ペンテスター向けのフレームワークですが、セキュリティエンジニアは皆サイバー攻撃と何らかの形で関わり、このフレームワークを知ることでサイバー攻撃についての理解が非常に深まると思います。
第二章でのScapyを用いた自作のポートスキャナの章は本書の目玉といえると思います。本書を読む人で3ウェイハンドシェイクを知らないって方はあまりいないと思いますが、実際にパケット単位で操作できる実行環境を作った人は少ないと思います。Socketモジュール等の一般的なモジュールでは、Synスキャンのような基本的なハッキング技術でさえ再現が意外とめんどくさく、比較的低レイヤーの操作が可能なツールScapyの有用性を感じました。私自身も今後より高度なレベルのScapyの使用法を学び、仕事でのPoC作りなどに活かしたいと思いました。
第三章から第五章の内容は非常にメジャーなツールの入門的な使い方なので今回はほとんど省略しましたが、ペンテスト系の学習をしたことがないセキュリティエンジニアにとっては網羅的に学ぶ上でいい教材だと思いました。これらを学習すればハッキングの登竜門であるHack The Boxなどにも挑みやすくなると思います。
第六章は、第二章から第五章までのツールを用いて標的端末へアクセス出来たあとの手順が第一章に登場したUnified Kill Chainフレームワークに基づいて記載されており、非常にためになります。Hack The Box等では端末のルートを取れたら終わりだったりしますが、現実のハッキングでは違います。機密情報の取得だったり、DoSの達成と言った目標達成にはルートの取得後の端末間の垂直・平行移動や情報収集が必要だったりします。
本書は取り扱ってる内容はペンテスト全域に渡っており、ボリュームはかなりありますが、要求レベル的にはLinux(できればPythonも)の基本がわかってれば十分に読める内容だとも思いました。ポートスキャナの原理に限らず、ペンテスターが用いるツールについて学びたい人は是非一読をお勧めいたします。