はじめに: changepasswd.py とは? 🤔
changepasswd.py
は、ネットワークセキュリティやペネトレーションテストの分野で広く利用されているPythonライブラリ Impacket スイートに含まれる強力なスクリプトの一つです。
その名の通り、このスクリプトはネットワーク上のユーザーアカウントのパスワードを変更したり、リセットしたりするために設計されています。
Active Directory (AD) 環境などでユーザーのパスワードを操作する必要がある場面は多岐にわたります。例えば、パスワードを忘れてしまったユーザーのパスワードリセット、セキュリティポリシーに基づいた定期的なパスワード変更の強制、あるいは(ペネトレーションテストの文脈では)侵害したアカウントのパスワードを変更してアクセスを維持したり、権限昇格を図ったりする場合などです。
changepasswd.py
の最大の特徴は、複数のプロトコルを介してパスワード操作を実行できる点にあります。具体的には、以下のプロトコルに対応しています。
- MS-SAMR (Security Account Manager Remote) over SMB: SMBプロトコル(通常TCP/445)上でSAMRインターフェースを利用します。古いパスワードがわかっていればパスワード変更が可能です。NTLMハッシュを使用してパスワードを設定することもできますが、その場合パスワードポリシーは無視されるものの、パスワードが「期限切れ」としてフラグ付けされることがあります。パスワードリセット(管理者権限が必要)の場合、NTLMハッシュを使うとパスワードポリシーや履歴を無視できますが、Kerberosキーが生成されないという副作用があります。
- MS-SAMR over RPC: RPC(通常TCP/135と動的ポート)上でSAMRインターフェースを利用します。デフォルトのAD設定では、RPC経由でのユーザーオブジェクトへのハンドル取得が制限されていることが多く、ハッシュのみでのパスワード変更やリセットが難しい場合があります。パスワードポリシーは通常適用されます。
- Kerberos Change/Reset Password: Kerberosプロトコル(通常UDP/88またはTCP/88)のパスワード変更(kpasswd)/リセット機能を利用します。Kerberos認証が必須であり、有効なTGT(Ticket Granting Ticket)やキー、または現在のパスワードが必要です。パスワードリセットには特別な権限(通常はドメイン管理者権限)が必要です。
- LDAP Modify Password: LDAPプロトコル(通常TCP/389またはLDAPS/636)を介してパスワードを変更します。通常、ユーザー自身が自分のパスワードを変更する場合や、管理者権限を持つアカウントが他のユーザーのパスワードをリセットする場合に使用されます。LDAPS(Secure LDAP)を使用すると通信が暗号化されます。
このように、changepasswd.py
は状況に応じて最適なプロトコルを選択できる柔軟性を提供します。Impacket v0.11.0以降、以前は独立していた smbpasswd.py
の機能などが統合され、より使いやすくなっています。
前提条件と準備 🛠️
changepasswd.py
を使用するには、いくつかの準備が必要です。
- Python環境: ImpacketはPythonで書かれているため、Python 3 がインストールされている必要があります。
-
Impacketのインストール: Impacketライブラリ本体が必要です。pipを使ってインストールするのが一般的です。
または、Kali Linuxなどのディストリビューションではパッケージマネージャーでインストールできる場合もあります。pip install impacket
最新版を利用したい場合は、GitHubリポジトリから直接クローンしてインストールすることも可能です。sudo apt update && sudo apt install python3-impacket impacket-scripts
git clone https://github.com/fortra/impacket.git cd impacket pip install .
- ネットワーク接続: ターゲットとなるホスト(通常はドメインコントローラー)に対して、選択したプロトコル(SMB, RPC, Kerberos, LDAP)で通信できる必要があります。ファイアウォール設定などを確認してください。
-
適切な認証情報/権限:
- パスワード変更の場合: 通常、変更対象ユーザー自身の現在のパスワード、またはNTLMハッシュが必要です。Kerberos認証を使用する場合は、有効なTGTやキーが必要です。
- パスワードリセットの場合: より高い権限(通常はドメイン管理者やそれに準ずる権限を持つアカウント)が必要です。
これらの準備が整っていれば、changepasswd.py
を実行する準備は完了です。🚀
基本的な使い方と構文 ⌨️
changepasswd.py
の基本的な構文は以下のようになります。
impacket-changepasswd [connection options] <identity> -newpass <new_password> [protocol options]
各部分を詳しく見ていきましょう。
接続オプション (Connection Options)
ターゲットや認証方法を指定します。
-
<identity>
(必須): ターゲットシステムへの接続と認証に使用する情報です。以下の形式で指定します。[[domain/]username[:password]@][target]
mydomain.local/adminuser:MyPassword123@dc01.mydomain.local
(ドメインユーザー、パスワード、ターゲットを指定)targetuser@ workstation1
(ローカルユーザー、パスワード入力プロンプト、ターゲットを指定)mydomain.local/svc_account@dc01
(ドメインユーザー、パスワード入力プロンプト、ターゲットを指定)
target
はターゲットマシンのホスト名またはIPアドレスです。省略すると、認証情報から推測されることがあります(例: ドメインコントローラー)。 -
-target-ip <ip address>
: ターゲットのIPアドレスを明示的に指定します。ターゲット名がDNSで解決できない場合に便利です。 -
-port <port>
: 接続先のポート番号を指定します。プロトコルによってデフォルトポートが異なります (SMB: 445, RPC: 135, LDAP: 389, LDAPS: 636, Kerberos: 88)。 -
-hashes <LMHASH:NTHASH>
: パスワードの代わりにNTLMハッシュ (LMハッシュは空でも可) を使用して認証します (Pass-the-Hash)。例:-hashes :ACB6xxxxxxxxxxxxxxxxxxxxxxx
-
-no-pass
: パスワード入力を求めません。-k
(Kerberos認証) や-hashes
と併用します。 -
-k
: Kerberos認証を使用します。事前にkinit
やgetTGT.py
などで取得した有効なTGTがキャッシュされている必要があります (KRB5CCNAME
環境変数で指定)。 -
-aesKey <hex key>
: NTLMハッシュの代わりにAESキー (128/256ビット) を使用してKerberos認証を行います (Pass-the-Key)。 -
-dc-ip <ip address>
: ドメインコントローラーのIPアドレスを明示的に指定します。Kerberosや一部のLDAP操作で必要になることがあります。
パスワード変更オプション
-
-newpass <new_password>
(必須): 設定したい新しいパスワードを平文で指定します。 -
-newhashes <LMHASH:NTHASH>
: 新しいパスワードを平文ではなくNTLMハッシュで指定します。通常、SAMR over SMBプロトコルでのみ有効です。この方法で設定されたパスワードはポリシーチェックを回避できますが、「期限切れ」扱いになる可能性があります。管理者権限でのリセットではポリシーと履歴を完全に無視できます。 -
-user <target_username>
: パスワードを変更/リセットする対象のユーザー名を指定します。<identity>
で指定した認証ユーザーとは別のユーザーのパスワードを操作する場合(例: 管理者が一般ユーザーのパスワードをリセットする場合)に使用します。省略した場合、<identity>
で指定したユーザー自身のパスワードが変更対象となります。 -
-reset
: パスワード変更ではなく、パスワードリセット操作を実行します。通常、管理者権限が必要です。SAMRやLDAPプロトコルで利用可能です。
プロトコルオプション (Protocol Options)
-
-p <protocol>
または--protocol <protocol>
: 使用するプロトコルを指定します。指定可能な値は以下の通りです。smb-samr
(デフォルト): SAMR over SMBrpc-samr
: SAMR over RPCkpasswd
: Kerberos Change/Reset Passwordldaps
: LDAP over SSL/TLS (Secure LDAP)ldap
: LDAP (非暗号化)
smb-samr
が試行されます。
その他のオプション
-
-debug
: デバッグ情報を詳細に出力します。問題発生時のトラブルシューティングに役立ちます。 -
-h
/--help
: ヘルプメッセージを表示して終了します。
基本的な使用例: 自分のパスワードを変更する (SMB経由)
ドメイン `mydomain.local` のユーザー `alice` が、ドメインコントローラー `dc01.mydomain.local` に対して自分の現在のパスワード `OldPass123` を使用して、新しいパスワード `NewSecurePass456` に変更する場合:
impacket-changepasswd mydomain.local/alice:OldPass123@dc01.mydomain.local -newpass 'NewSecurePass456'
このコマンドはデフォルトのプロトコル (smb-samr
) を使用します。成功すれば、パスワードが変更された旨のメッセージが表示されます。🎉
応用的な使い方・シナリオ 🚀
changepasswd.py
は基本的なパスワード変更以外にも、様々なシナリオで活用できます。
シナリオ1: NTLMハッシュを使って自分のパスワードを変更 (Pass-the-Hash)
ユーザー `bob` の現在のパスワード平文は不明だが、NTLMハッシュ (aad3b435b51404eeaad3b435b51404ee
) が判明している場合に、新しいパスワード `P@ssword! に変更する (SMB経由)。
impacket-changepasswd mydomain.local/bob@dc01.mydomain.local -hashes :aad3b435b51404eeaad3b435b51404ee -newpass 'P@ssword!' -p smb-samr
この方法は、NTLMハッシュしか入手できなかった場合に有効です。ただし、前述の通り、この方法で変更されたパスワードは「期限切れ」扱いになる可能性があります。
シナリオ2: 管理者権限でユーザーのパスワードをリセット (LDAP経由)
ドメイン管理者 `adminuser` が、ユーザー `charlie` のパスワードを `ResetPass789` にリセットする場合。LDAPS (Secure LDAP) を使用します。
impacket-changepasswd mydomain.local/adminuser:AdminPass@dc01.mydomain.local -user charlie -newpass 'ResetPass789' -reset -p ldaps
-reset
オプションを使用することで、強制的なパスワードリセットを行います。LDAPSを使用することで、通信内容が暗号化され、より安全に操作できます。
シナリオ3: Kerberosチケットを使って自分のパスワードを変更 (Pass-the-Ticket)
ユーザー `david` の有効なKerberos TGT (Ticket Granting Ticket) が david.ccache
というファイルに保存されている場合、これを使って新しいパスワード `Kerb3r0sRul3z` に変更する (kpasswdプロトコル使用)。
export KRB5CCNAME=david.ccache
impacket-changepasswd mydomain.local/david@kdc.mydomain.local -k -no-pass -newpass 'Kerb3r0sRul3z' -p kpasswd
まず環境変数 KRB5CCNAME
でチケットキャッシュファイルのパスを指定します。次に -k
と -no-pass
オプションでKerberos認証を使用し、パスワード入力をスキップします。-p kpasswd
でKerberosのパスワード変更プロトコルを指定します。
この方法は、パスワード平文やハッシュが不明でも、有効なKerberosチケットがあればパスワードを変更できるため、特定の攻撃シナリオ(例: Kerberoasting後にTGTを取得した場合)で有用です。
シナリオ4: NTLMハッシュを使ってパスワードをリセット (管理者権限 + SMB経由)
管理者 `adminuser` のNTLMハッシュ (31d6cfe0d16ae931b73c59d7e0c089c0
) を使用して、ユーザー `eve` のパスワードを新しいNTLMハッシュ (0cb6948805f797bf2a82807973b89537
) にリセットする場合 (SMB経由)。
impacket-changepasswd mydomain.local/adminuser@dc01.mydomain.local -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 -user eve -newhashes :0cb6948805f797bf2a82807973b89537 -reset -p smb-samr
この方法は、管理者権限を持つアカウントのハッシュを奪取した場合などに、他のユーザーのパスワードを制御下に置くために使われることがあります。パスワードポリシーや履歴を完全に無視してハッシュを設定できますが、Kerberosキーは更新されない点に注意が必要です。 2022年頃には、この機能を利用してパスワード履歴を回避する手法に関する議論やプルリクエストがImpacketのGitHubリポジトリで見られました。
エラーハンドリングとトラブルシューティング 🧐
changepasswd.py
の実行中にエラーが発生することもあります。一般的なエラーとその対処法をいくつか紹介します。
エラーメッセージ (例) | 考えられる原因 | 対処法 |
---|---|---|
STATUS_LOGON_FAILURE |
認証に使用したパスワード/ハッシュ/チケットが間違っている。 | 正しい認証情報を確認・入力する。 |
STATUS_ACCESS_DENIED |
操作に必要な権限がない (例: 一般ユーザーが他人のパスワードをリセットしようとした)。RPC経由でのSAMRアクセスが制限されている。 | 適切な権限を持つアカウントを使用する。別のプロトコル (SMB, LDAP, Kerberos) を試す。ドメインポリシーを確認する。 |
STATUS_PASSWORD_RESTRICTION |
新しいパスワードがドメインのパスワードポリシー (複雑さ、履歴、最低有効期間など) を満たしていない。 | パスワードポリシーを確認し、準拠したパスワードを設定する。管理者権限で -reset オプションや -newhashes を使用してポリシーを回避する (注意して使用)。 |
STATUS_WRONG_PASSWORD |
パスワード変更時に指定した現在のパスワードが間違っている。 | 正しい現在のパスワードを確認・入力する。 |
kpasswd: INTERNAL_ERROR - Couldn't change password |
Kerberosパスワード変更サーバー (kpasswd) で内部エラーが発生した。KDCとの通信問題。 | KDCの状態を確認する。-dc-ip オプションを試す。-debug オプションで詳細を確認する。 |
Connection refused / Timeout | ターゲットホストへのネットワーク接続ができない。ファイアウォールでポートがブロックされている。 | ネットワーク接続を確認する。ファイアウォール設定を確認し、必要なポート (445, 135, 88, 389, 636など) が開いているか確認する。 |
問題が解決しない場合は、-debug
オプションを付けて実行し、詳細なログを確認することがトラブルシューティングの鍵となります。🔍
注意点とセキュリティ考慮事項 🛡️
changepasswd.py
は非常に便利なツールですが、その強力さゆえに、悪用されるリスクも伴います。利用にあたっては以下の点に十分注意し、セキュリティ対策を講じることが重要です。
- 悪用リスク: 攻撃者がこのツールを不正に入手した認証情報(特に管理者権限)と組み合わせて使用すると、ドメイン内の他のユーザーアカウントを乗っ取ったり、永続的なアクセスを確保したりする可能性があります。実際に、多くのAPTグループやランサムウェア攻撃者が Impacket スクリプトを攻撃ツールキットの一部として利用していることが報告されています。
- ログ監査の重要性: パスワード変更やリセットの操作は、ドメインコントローラーのセキュリティイベントログに記録されます(イベントID 4724: パスワードリセット試行、4723: パスワード変更試行、4738: ユーザーアカウント変更など)。これらのログを適切に監視し、不審なパスワード変更アクティビティがないか定期的に監査することが不可欠です。SIEM (Security Information and Event Management) システムを活用して、異常なパターン(短時間に大量のパスワード変更、深夜のパスワードリセットなど)を検知することも有効です。
-
強力なパスワードポリシー: 複雑さの要件、パスワード履歴、最低有効期間、定期的な変更強制など、強力なパスワードポリシーを適用することは、ブルートフォース攻撃や推測攻撃のリスクを低減するだけでなく、
changepasswd.py
を使った安易なパスワード変更(特にポリシーチェックが働くプロトコル経由の場合)を防ぐ助けになります。ただし、管理者権限によるリセットはポリシーを回避できるため、ポリシーだけに頼ることはできません。 - 最小権限の原則: 管理者権限を持つアカウントの数を最小限に抑え、特権アクセス管理 (PAM) ソリューションを導入するなどして、強力な権限を持つアカウントの認証情報を厳格に管理することが重要です。不要なアカウントにパスワード変更権限を与えないようにしましょう。
- ネットワークセグメンテーションとファイアウォール: 重要なサーバー(特にドメインコントローラー)へのアクセスを、必要なホストや管理者に限定するようにネットワークをセグメント化し、ファイアウォールで不要なポート(特にSMB, RPC関連)へのアクセスを制限します。
- 認証方法の強化: 可能であれば、パスワードだけでなく多要素認証 (MFA) を導入することを検討してください。また、NTLM認証よりも安全なKerberos認証の使用を推奨し、古いLMハッシュの保存を無効化するなどの設定も有効です。
まとめ ✨
impacket-changepasswd
は、Active Directoryなどの環境でユーザーパスワードを管理するための強力で柔軟なツールです。SMB, RPC, Kerberos, LDAPといった複数のプロトコルに対応し、パスワードだけでなくNTLMハッシュやKerberosチケットを用いた認証・パスワード設定も可能です。
システム管理者にとっては、パスワードリセットやポリシーに基づいた変更作業を効率化する上で役立ちます。一方で、ペネトレーションテスターや攻撃者にとっても、権限昇格やラテラルムーブメントのための重要なツールとなり得ます。
このツールの能力を理解し、その利用に伴うリスクを認識した上で、適切なセキュリティ対策(ログ監視、強力なポリシー、権限管理など)を講じることが、安全なシステム運用には不可欠です。正しく使えば管理の助けとなり、悪用されれば大きな脅威となる、まさに諸刃の剣と言えるでしょう。⚔️
常に最新の情報を確認し、セキュリティのベストプラクティスに従って、責任ある利用を心がけましょう。Happy (ethical) hacking/administering! 😊
コメント