NetExec と WinRM による列挙
このページで扱うこと
Section titled “このページで扱うこと”HTB の Windows / Active Directory マシンで初期資格情報を得たあと、NetExec で何を確認し、WinRM 接続後にどこを調べるかを順にまとめます。
扱う範囲は次の通りです。
netexec/nxcによる SMB、LDAP、WinRM の初期確認。- 共有、ユーザー、グループ、コンピュータ、WinRM 候補の見方。
- WinRM 接続後のユーザー、ホスト、ファイル、資格情報、ドメイン、共有の手動列挙。
- 手動列挙の見落としを winPEAS で確認する方法。
AD の ACL や Kerberos 委任など、個別の仕組みは関連ページで詳しく扱います。
- Active Directory Access Control と BloodHound Edge
- Kerberos(Active Directory 認証)
- Kerberos Delegation と SPN Abuse
- NTLM Relay and Coercion
- Windows ローカル資格情報
前提値を固定する
Section titled “前提値を固定する”最初に target、domain、DC の名前解決を固定する。
<dc-ip> <dc-fqdn> <domain> <hostname>例:
10.129.13.247 DC01.checkpoint.htb checkpoint.htb DC01以後のコマンド例では次を使う。
DC='<dc-fqdn-or-ip>'DC_FQDN='<dc-fqdn>'DOMAIN='<domain>'REALM='<DOMAIN uppercase>'USER='<user>'PASS='<password>'HASH='<nt-hash>'Kerberos を使う場合は、IP ではなく FQDN を優先する。/etc/hosts で名前解決できても、MIT Kerberos の realm mapping が合っていないと TGT/TGS 取得で失敗することがある。
ポートスキャンから読むこと
Section titled “ポートスキャンから読むこと”netexec に入る前に、Nmap の出力から環境の前提を読む。
| 観察 | 読み方 |
|---|---|
53, 88, 389, 445, 464, 3268, 9389 | Domain Controller (DC) として扱う根拠になる。 |
389 / 3268 に Domain: <domain> | LDAP / Global Catalog から domain 名が取れている。 |
5985/tcp open | 有効な資格情報を得たら WinRM を試す価値がある。ただし認可までは意味しない。 |
smb2-security-mode: signing required | SMB relay を主経路にせず、認証済み SMB/LDAP/Kerberos 列挙を優先する。 |
clock-skew が大きい | Kerberos、BloodHound/RustHound、TGS 要求の失敗原因になる。 |
LDAP signing / channel binding / NTLM:False | LDAP の認証方式、relay 可否、Kerberos 必須化の判断材料になる。 |
Kerberos で KRB_AP_ERR_SKEW が出る場合は、攻撃端末側の時刻を target に合わせる。HTB では ntpdate <dc-fqdn> や faketime を使った記録がある。
sudo ntpdate "$DC_FQDN"
FAKETIME_DONT_FAKE_MONOTONIC=1 faketime '+7 hours' <kerberos-command>NetExec で最初に確認すること
Section titled “NetExec で最初に確認すること”SMB / LDAP / WinRM の到達性
Section titled “SMB / LDAP / WinRM の到達性”初期資格情報を得たら、まず protocol ごとに認証と認可を分けて見る。
netexec smb "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS"netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS"netexec winrm "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS"見るべき分離は次の通り。
| 結果 | 意味 |
|---|---|
SMB + | credential が SMB で受理された。共有を読めるとは限らない。 |
LDAP + | AD object の認証済み列挙に使える。WinRM 可能とは限らない。 |
WinRM + / Pwn3d! | WinRM shell の候補。evil-winrm で prompt を取って事後確認する。 |
WinRM - | password 不正とは限らない。Remote Management Users などの認可不足や認証方式不一致を疑う。 |
STATUS_NOT_SUPPORTED と NTLM:False | NTLM が無効または使えない可能性が高い。Kerberos に切り替える。 |
No Kerberos credentials available | password ではなく ccache 選択の問題。 |
Puppy、Pirate、Checkpoint では、SMB/LDAP は成功しても初期ユーザーでは WinRM できない状態があった。一方 Administrator では初期ユーザーが WinRM まで通っている。5985 が開いていること、資格情報が正しいこと、WinRM への認可があることは別々に確認する。
Kerberos キャッシュを使う場合
Section titled “Kerberos キャッシュを使う場合”NTLM が使えない、Protected Users に入っている、または Kerberos を明示したい場合は TGT を取って cache を使う。
getTGT.py "$DOMAIN/$USER:$PASS" -dc-ip '<dc-ip>'export KRB5CCNAME="$USER.ccache"
netexec smb "$DC_FQDN" --use-kcache --shares --rid-brutenetexec ldap "$DC_FQDN" --use-kcache --users --groups --computersnetexec winrm "$DC_FQDN" --use-kcacheWinRM / WSMan は HTTP/<host> service principal (SPN) の TGS を使う。TGT は KDC に認証済みであることを示す ticket であり、WinRM サーバーに直接提示する ticket ではない。KRB_AP_ERR_MODIFIED が出る場合は、hostname、SPN、realm、ccache を疑う。
krb5.conf とチケットを確認する
Section titled “krb5.conf とチケットを確認する”/etc/hosts に FQDN を書いただけでは、MIT Kerberos が <dc-fqdn> を正しい realm に属すると判断できないことがある。その場合は target ごとの krb5.conf を作り、KRB5_CONFIG で明示する。
一時的に使うなら /tmp に置く。
cat > /tmp/krb5-example.conf <<'EOF'[libdefaults] default_realm = EXAMPLE.HTB dns_lookup_realm = false dns_lookup_kdc = false rdns = false udp_preference_limit = 1
[realms] EXAMPLE.HTB = { kdc = dc01.example.htb admin_server = dc01.example.htb }
[domain_realm] .example.htb = EXAMPLE.HTB example.htb = EXAMPLE.HTB dc01.example.htb = EXAMPLE.HTBEOF
export KRB5_CONFIG=/tmp/krb5-example.confTGT を取得し、使う ccache を明示する。
getTGT.py 'example.htb/<user>:<password>' -dc-ip '<dc-ip>'export KRB5CCNAME='<user>.ccache'klistTGT だけでなく、実際に使う service principal の TGS が取れるか確認する。
KRB5_TRACE=/dev/stderr kvno "ldap/dc01.example.htb"KRB5_TRACE=/dev/stderr kvno "cifs/dc01.example.htb"KRB5_TRACE=/dev/stderr kvno "http/dc01.example.htb"klist| SPN | 主な用途 |
|---|---|
ldap/<dc-fqdn> | LDAP query、BloodHound / RustHound、ADSI 系。 |
cifs/<dc-fqdn> | SMB share、netexec smb --use-kcache。 |
http/<dc-fqdn> | WinRM / WSMan、Evil-WinRM Kerberos。 |
TGS 取得で別 realm が出る、または KDC が見つからない場合は、[domain_realm]、default_realm、KRB5_CONFIG の参照先を確認する。
永続的に切り替えたい場合は、target ごとの設定を ~/.config/krb5/ に置く。
mkdir -p ~/.config/krb5 ~/.ccache
cat > ~/.config/krb5/example.htb.conf <<'EOF'[libdefaults] default_realm = EXAMPLE.HTB dns_lookup_realm = false dns_lookup_kdc = false rdns = false udp_preference_limit = 1
[realms] EXAMPLE.HTB = { kdc = dc01.example.htb admin_server = dc01.example.htb }
[domain_realm] .example.htb = EXAMPLE.HTB example.htb = EXAMPLE.HTB dc01.example.htb = EXAMPLE.HTBEOF~/.zshrc や ~/.bashrc に alias を置くと、box ごとの Kerberos 設定と ccache を簡単に切り替えられる。
alias krb_example='export KRB5_CONFIG=$HOME/.config/krb5/example.htb.conf; export KRB5CCNAME=$HOME/.ccache/example.htb.ccache; klist'alias krb_off='unset KRB5_CONFIG KRB5CCNAME'読み込み直す。
source ~/.zshrc# またはsource ~/.bashrc使い方。
krb_example
# kinit を使える場合は KRB5CCNAME の場所に直接 TGT を作るkinit '<user>@EXAMPLE.HTB'klistImpacket getTGT.py を使う場合は、出力された ccache を alias が参照する場所へ移す。
getTGT.py 'example.htb/<user>:<password>' -dc-ip '<dc-ip>'mv '<user>.ccache' "$HOME/.ccache/example.htb.ccache"krb_example
netexec ldap dc01.example.htb --use-kcache --users --groupsnetexec smb dc01.example.htb --use-kcache --sharesevil-winrm -i dc01.example.htb -r example.htb --ccache "$HOME/.ccache/example.htb.ccache"
krb_offprofile には password を置かない。保存するのは KRB5_CONFIG と KRB5CCNAME の切り替えだけにする。
NT ハッシュを使う場合
Section titled “NT ハッシュを使う場合”NT hash が得られたら、まず SMB と WinRM の両方で検証する。
netexec smb "$DC" -d "$DOMAIN" -u "$USER" -H "$HASH" --sharesnetexec winrm "$DC" -d "$DOMAIN" -u "$USER" -H "$HASH"
evil-winrm-py -i "$DC" -u "$USER" -H "$HASH"machine account や gMSA は末尾の $ を shell が展開しないように quote する。
evil-winrm-py -i "$DC" -u 'gMSA_ADCS_prod$' -H '<nt-hash>'ローカルアカウントで認証する場合
Section titled “ローカルアカウントで認証する場合”Standalone host や local administrator credential を試すときだけ --local-auth を使う。Domain Controller 上では通常の domain auth と混同しない。
netexec smb '<host>' -u '<local-user>' -p '<password>' --local-authnetexec winrm '<host>' -u '<local-user>' -p '<password>' --local-auth初期列挙の基本セット
Section titled “初期列挙の基本セット”SMB 共有と RID
Section titled “SMB 共有と RID”netexec smb "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" --shares --rid-bruteIPC$、NETLOGON、SYSVOL の READ は domain user として自然な baseline である。DEV、Logs、IT、VMBackups、DevDrop、Finance のような業務名の共有が見えたら優先して中を見る。
smbclient "//$DC_FQDN/<share>" -U "$DOMAIN/$USER%$PASS" -m SMB3NT hash の場合:
smbclient "//$DC_FQDN/<share>" \ -U "$DOMAIN/$USER%$HASH" \ --pw-nt-hash -m SMB3共有名が見えることと読めることは違う。Puppy では DEV は最初に見えたが、グループ所属変更後に初めて READ が得られた。Checkpoint では VMBackups が見えても初期ユーザーでは読めず、BackupAccess に属する svc_deploy で読み直して初めて使えた。
SMB share に入った後は、share root を基準にパスを書く。//dc/IT に接続しているなら remote path はすでに C:\IT 相当であり、C:\IT\... を指定すると NT_STATUS_OBJECT_NAME_INVALID になり得る。
LDAP でユーザー・グループ・コンピューターを調べる
Section titled “LDAP でユーザー・グループ・コンピューターを調べる”netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" \ --users --groups --computers最初に見るもの。
| 対象 | 注目点 |
|---|---|
| users | svc_*、*_adm、職位名、description、password hint、無効化状態。 |
| groups | Remote Management Users、業務名グループ、Backup/Recovery/IT/WSUS/Certificate 関連。 |
| computers | DC 以外の server、pre-created computer account、machine account。 |
| gMSA | msDS-GroupMSAMembership、Remote Management Users 所属。 |
| descriptions | password、運用メモ、担当、共有名の手がかり。 |
候補ユーザーは LDAP query で絞って確認する。
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" \ --query "(sAMAccountName=<target-user>)" \ "sAMAccountName memberOf description userAccountControl servicePrincipalName"Remote Management Users 所属は WinRM 候補であって、password や hash が正しいことの証明ではない。BackupAccess のような名前も SeBackupPrivilege とは限らない。Checkpoint の svc_deploy は BackupAccess に属していたが、whoami /all では SeBackupPrivilege はなく、実際には VMBackups share の READ につながった。
Kerberoasting と AS-REP Roasting の候補
Section titled “Kerberoasting と AS-REP Roasting の候補”初期資格情報で AS-REP roast / Kerberoast を試す価値はあるが、空振りは珍しくない。
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" --asreproast asrep.hashesnetexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" --kerberoasting kerberoast.hashesまたは Impacket:
GetNPUsers.py "$DOMAIN/$USER:$PASS" -dc-ip '<dc-ip>' -request -outputfile asrep.hashesGetUserSPNs.py "$DOMAIN/$USER:$PASS" -dc-ip '<dc-ip>' -request -outputfile kerberoast.hashesTargeted Kerberoasting は単なる列挙ではなく、対象の servicePrincipalName を一時変更できる ACL が必要になる。詳細は AD ACL ノートへ回す。
BloodHound / RustHound で関係を読む
Section titled “BloodHound / RustHound で関係を読む”rusthound-ce -d "$DOMAIN" -f "$DC_FQDN" -u "$USER" -p "$PASS" -c All --zipBloodHound は「最短経路を押す道具」ではなく、LDAP 属性、group membership、ACL、SPN、delegation の関係をまとめる地図として読む。
確認するときは次を分ける。
- Principal: 誰が権限を持つか。
- Object: どの user / group / computer / OU / domain に対する権限か。
- Edge:
GenericAll、GenericWrite、WriteOwner、AddMember、WriteSPNなどの意味。 - 実操作: password reset、group member 追加、SPN 追加、shadow credentials 追加など。
- 再読取り: 変更後に LDAP / SMB / WinRM で事後確認できたか。
BloodHound が LDAPS へ逃げて失敗する場合、LDAPS そのものではなく Kerberos の時刻差や realm 解決が根本原因のことがある。Checkpoint では clock skew が原因で Kerberos が失敗し、NTLM LDAP に落ち、LDAP signing に阻まれ、LDAPS が reset される流れだった。
WinRM でログインする
Section titled “WinRM でログインする”Password:
evil-winrm -i "$DC_FQDN" -u "$USER" -p "$PASS"Kerberos:
export KRB5CCNAME="$USER.ccache"evil-winrm -i "$DC_FQDN" -r "$DOMAIN" --ccache "$USER.ccache"NT hash:
evil-winrm-py -i "$DC_FQDN" -u "$USER" -H "$HASH"接続に成功したら、prompt がどの user と host を示しているかを記録する。netexec winrm の成功だけで止めず、実際の remote PowerShell prompt を事後確認にする。
失敗理由を層で分ける
Section titled “失敗理由を層で分ける”| 症状 | 優先して疑うこと |
|---|---|
SMB/LDAP は +、WinRM は - | WinRM 認可不足、Remote Management Users 未所属、WinRM の認証方式不一致。 |
No Kerberos credentials available | KRB5CCNAME または --ccache 指定漏れ。 |
KRB_AP_ERR_SKEW | attack box と DC の時刻差。 |
KRB_AP_ERR_MODIFIED | SPN、hostname、realm、service ticket の不一致。WinRM では HTTP/<host> を意識する。 |
STATUS_NOT_SUPPORTED | NTLM 不可。Kerberos cache を使う。 |
WinRM 接続後の列挙
Section titled “WinRM 接続後の列挙”ユーザー ID とトークン
Section titled “ユーザー ID とトークン”最初に現在の security context を確定する。
whoamiwhoami /upnwhoami /allwhoami /groupswhoami /privhostname見るべき点。
| 観察 | 判断 |
|---|---|
BUILTIN\Remote Management Users | WinRM できる理由。管理者権限そのものではない。 |
SeImpersonatePrivilege / SeAssignPrimaryTokenPrivilege | token abuse の候補。 |
SeBackupPrivilege / SeRestorePrivilege | NTFS ACL を越えた backup 系読み取りや hive / NTDS 取得の候補。 |
SeDebugPrivilege | process memory / credential access の候補。 |
SeMachineAccountPrivilege、SeChangeNotifyPrivilege、SeIncreaseWorkingSetPrivilege 程度 | 即時 local privesc ではなく、ファイル、共有、AD、資格情報を優先する。 |
| Custom group | 共有 ACL、アプリ権限、証明書、WSUS、backup などの運用権限につながるか確認する。 |
whoami /all は必ず残す。Puppy の最終セッションではこれを記録しておらず、最終アカウントの正確な group / privilege を後から説明しづらくなった。
ホストの基本情報
Section titled “ホストの基本情報”systeminfoipconfig /allroute printnetstat -anoサービスとタスク:
Get-CimInstance Win32_Service | Select-Object Name,StartName,State,PathName
Get-ScheduledTask | Select-Object TaskName,TaskPath,Stateプロセス:
Get-Process -ErrorAction SilentlyContinue | Select-Object ProcessName,Id,Pathここでは「全部を暗記する」より、実行ユーザー、path、書き込み可能な directory、設定ファイル、credential を探す。
ファイルシステムはルート直下から絞る
Section titled “ファイルシステムはルート直下から絞る”いきなり C:\ 全体を再帰しない。まず root 直下を見る。
Get-ChildItem -LiteralPath 'C:\' -Force次に意味のある候補だけを深掘りする。
$targets = @( 'C:\Backups', 'C:\inetpub', 'C:\IT', 'C:\Logs', 'C:\Shares', 'C:\StorageReports', 'C:\ProgramData') | Where-Object { Test-Path $_ }
if ($targets) { Get-ChildItem -LiteralPath $targets -Force -ErrorAction SilentlyContinue Get-ChildItem -LiteralPath $targets -Recurse -Force -ErrorAction SilentlyContinue}優先して見る名前。
| 名前 | 意味 |
|---|---|
Backups, VMBackups, NightlyBackup | 設定、旧 DB、snapshot、memory dump、NTDS / hive の候補。 |
inetpub, wwwroot, app directory | Web config、LDAP bind password、connection string。 |
IT, Dev, DevDrop, Logs | 運用共有、deployment artifact、script、credential leak。 |
StorageReports, WSUSTemp, vendor directory | 標準外の運用痕跡。 |
| user profile archive | DPAPI、SSH key、browser、Credential Manager の候補。 |
検索は範囲を絞ってから行う。
if ($targets) { Get-ChildItem -LiteralPath $targets -Recurse -Force -ErrorAction SilentlyContinue | Where-Object { -not $_.PSIsContainer } | Where-Object { $_.Length -lt 5MB } | Select-String -Pattern 'password|passwd|pwd|secret|token|credential|ldap|bind|backup|winrm' ` -ErrorAction SilentlyContinue}flag や既知ファイル名の検索も範囲を限定する。
Get-ChildItem -LiteralPath 'C:\Users' -Filter 'root.txt' -Recurse -Force -ErrorAction SilentlyContinueユーザープロファイルと履歴
Section titled “ユーザープロファイルと履歴”Get-ChildItem -LiteralPath 'C:\Users' -Force
$userDirs = @( "$env:USERPROFILE\Desktop", "$env:USERPROFILE\Documents", "$env:USERPROFILE\Downloads") | Where-Object { Test-Path $_ }
if ($userDirs) { Get-ChildItem -LiteralPath $userDirs -Force -ErrorAction SilentlyContinue}PowerShell history:
Get-Content (Get-PSReadLineOption).HistorySavePath -ErrorAction SilentlyContinueEvil-WinRM では ls は Get-ChildItem、type は Get-Content の alias である。後から再利用するコマンドは完全名と -LiteralPath に直す。
Get-Content -LiteralPath 'C:\Users\<user>\Desktop\user.txt'Credential Manager と DPAPI
Section titled “Credential Manager と DPAPI”まず現在ユーザーの保存済み資格情報を確認する。
cmdkey /list
Get-ChildItem "$env:APPDATA\Microsoft\Credentials" ` -Force -ErrorAction SilentlyContinue
Get-ChildItem "$env:LOCALAPPDATA\Microsoft\Credentials" ` -Force -ErrorAction SilentlyContinue
Get-ChildItem "$env:APPDATA\Microsoft\Protect" ` -Recurse -Force -ErrorAction SilentlyContinue他ユーザーや archived profile が読める場合は、次の組を探す。
AppData\Roaming\Microsoft\CredentialsAppData\Local\Microsoft\CredentialsAppData\Roaming\Microsoft\Protect\<SID>AppData\Local\Microsoft\VaultDPAPI で必要なのは、Credential Blob だけではない。
Credential Blob | | 参照する Master Key GUID vProtect\<SID>\<MasterKeyGUID> | | user password + SID、または domain backup key などで復号 vdecrypted masterkey | vCredential Blob の復号Puppy では Credentials と Protect\<SID> の対応を winPEAS が示し、ユーザー password と SID で Master Key を復号した。Voleur では archived profile から Credentials と Protect\<SID> を両方回収し、削除済み AD object から SID を確認した。
Domain 情報を host 内から見る
Section titled “Domain 情報を host 内から見る”WinRM で入った後も、AD の事実は LDAP / AD module / ADSI で確認できる。
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = [ADSI]'LDAP://RootDSE'$root.defaultNamingContext現在ユーザーの group membership:
$searcher = [adsisearcher]"(sAMAccountName=$env:USERNAME)"$result = $searcher.FindOne()$result.Properties.memberofユーザーを探す:
$searcher = New-Object DirectoryServices.DirectorySearcher$searcher.Filter = '(objectClass=user)'$searcher.PageSize = 1000$searcher.PropertiesToLoad.AddRange(@( 'samaccountname', 'distinguishedname', 'memberof', 'useraccountcontrol', 'description', 'serviceprincipalname'))
$searcher.FindAll() | ForEach-Object { $_.Properties }AD module がある場合:
Import-Module ActiveDirectory
Get-ADUser '<user>' -Properties MemberOf,Description,ServicePrincipalName,UserAccountControl | Select-Object SamAccountName,Enabled,Description,MemberOf,ServicePrincipalName,UserAccountControl
Get-ADPrincipalGroupMembership '<user>' | Select-Object Name,DistinguishedNameBloodHound が見せる edge は、最終的には LDAP 属性、ACE、group membership、SPN、delegation などの事実に戻せる。グラフだけで判断せず、実際に読める属性と操作結果で裏付ける。
Share を再確認する
Section titled “Share を再確認する”新しい user、hash、group membership を得たら、attacker 側から SMB shares を再列挙する。
netexec smb "$DC_FQDN" -d "$DOMAIN" -u "$USER" -p "$PASS" --sharesnetexec smb "$DC_FQDN" -d "$DOMAIN" -u "$USER" -H "$HASH" --sharesWinRM target 内から見る場合:
$dc = '<dc-fqdn>'net view "\\$dc"net use共有 ACL は「今の credential」で変わる。初期ユーザーで access denied だった共有でも、別ユーザー、別グループ、別 hash で読めることがある。
winPEAS は差分確認として使う
Section titled “winPEAS は差分確認として使う”winPEAS は最初から答えを探すためではなく、手動列挙の抜けを確認する baseline として使う。
.\winPEASx64.exe *> C:\Windows\Temp\winpeas.txt比較する観察点。
| 観察項目 | 手動で確認 | winPEAS で確認 | 次の判断 |
|---|---|---|---|
| root 直下の非標準 directory | C:\Backups, C:\IT など | 追加候補があるか | 深掘り対象を限定する。 |
| Credential Manager / DPAPI | Credentials, Protect\<SID> | Master Key と Blob の対応 | 復号材料が揃うか確認する。 |
| PowerShell history | history path | 抽出漏れがあるか | command / password leak を確認する。 |
| services / scheduled tasks | service path、run user | writable path の候補 | 実行コンテキストと ACL を確認する。 |
| writable path | 手動 ACL / file write | 追加候補 | 実行される path かを確認する。 |
| token privileges | whoami /all | 特権候補 | share access と token privilege を混同しない。 |
Living off the Land (LOTL) なら検知されないわけではない。PowerShell command line、Script Block Logging、AMSI、短時間での大量 file enumeration、WMI/CIM 列挙、資格情報 directory への access、WinRM provider host 配下の process は監視対象になり得る。巨大ツールか手動コマンドかより、何をどの範囲で読んだかを意識する。
同じ事実を複数レイヤーで取る
Section titled “同じ事実を複数レイヤーで取る”1 つの事実を、専用ツール、OS 標準機能、LDAP / API の 3 層で確認できると強い。
例: ユーザーの group membership。
NetExec:
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" \ --query "(sAMAccountName=<user>)" "sAMAccountName memberOf"Windows 標準:
whoami /groupsAD module:
Get-ADPrincipalGroupMembership '<user>' | Select-Object Name,DistinguishedNameADSI:
$searcher = [adsisearcher]'(sAMAccountName=<user>)'$searcher.FindOne().Properties.memberofBloodHound、bloodyAD、Impacket は強力だが、裏では LDAP、Kerberos、SMB、RPC、WinRM、Windows API を使っている。ツール名ではなく、観測したい事実と使われる protocol / API を対応付ける。
| 目的 | よく使うツール | 別経路 |
|---|---|---|
| SMB 共有列挙 | netexec smb --shares | smbclient, net view |
| LDAP users / groups | netexec ldap --users --groups | ADSI, Get-ADUser, ldapsearch |
| Kerberos TGT/TGS | getTGT.py, GetUserSPNs.py | kinit, kvno, Rubeus |
| AD graph | BloodHound / RustHound | LDAP query, AD module, ADSI |
| LDAP 属性変更 | bloodyAD | Set-ADUser, ADSI, ldapmodify |
| WinRM shell | Evil-WinRM | PowerShell Remoting, Metasploit WinRM module |
Writeup から得た観察の手がかり
Section titled “Writeup から得た観察の手がかり”| Box | 観察 | 一般化 |
|---|---|---|
| Puppy | 5985 は開いていたが、Remote Management Users と Kerberos ccache を分けて確認した。C:\Backups から LDAP bind password、DPAPI から別 credential へ進んだ。 | WinRM は認証と認可を分ける。foothold 後は root 直下の非標準 directory、backup、DPAPI を狭い範囲で見る。 |
| Checkpoint | svc_deploy は Remote Management Users と BackupAccess に所属。SeBackupPrivilege はなく、VMBackups share の READ が本線だった。 | group 名を privilege と誤読しない。whoami /all と share 再列挙で意味を確定する。 |
| Pirate | 初期 pentest は LDAP/SMB 可、WinRM 不可。gMSA が Remote Management Users に所属し、hash で WinRM できた。 | machine account、gMSA、group membership は WinRM 候補の発見に使う。 |
| Certified | management_svc が Remote Management Users に所属することを LDAP と BloodHound で確認し、hash で WinRM した。 | Remote Management Users は候補であり、最終的には shell 成功で裏付ける。 |
| Administrator | 初期ユーザー Olivia は WinRM が Pwn3d!。後続で Kerberos 時刻ずれも問題になった。 | 初期資格情報が WinRM まで通る box もある。成功時点で identity と group を残す。 |
| Logging | Logs share、Remote Management Users、Emergency Recovery、msa_health$ が序盤から見えていた。WinRM 後に whoami /groups で認可を確認した。 | share 名と group 名は運用設計のヒント。machine account の WinRM も候補になる。 |
| Voleur | NTLM が使えず STATUS_NOT_SUPPORTED。Kerberos cache で SMB/LDAP を列挙し、archived profile の DPAPI へ進んだ。 | password 不正と認証方式不一致を混同しない。profile archive は DPAPI の入口になる。 |
短いチェックリスト
Section titled “短いチェックリスト”初期資格情報を得たら:
smb,ldap,winrmを別々に確認する。--shares --rid-bruteと--users --groups --computersを取る。Remote Management Users、custom groups、service accounts、machine accounts、gMSA を拾う。- SMB signing、LDAP signing、NTLM 可否、clock skew を読む。
- BloodHound/RustHound は関係の地図として使い、実操作と再読取りで検証する。
WinRM に入れたら:
whoami /allを最初に保存する。C:\直下から非標準 directory を探し、候補だけ再帰する。- user profile、PowerShell history、Credential Manager、DPAPI、backup、app config を確認する。
- 新 credential / hash / group membership を得るたびに SMB shares と WinRM を再確認する。
- winPEAS は手動列挙の差分確認に使う。

