├── LICENSE ├── README.md ├── appendix_a └── appendix_a_listings.ps1 ├── chapter_10 ├── chapter_10_listings.ps1 ├── listing_10_16.ps1 ├── listing_10_17.ps1 ├── listing_10_20.ps1 ├── listing_10_21_to_10_34.ps1 ├── listing_10_3.ps1 ├── listing_10_35_to_10_36.ps1 ├── listing_10_40.ps1 ├── listing_10_6.ps1 └── listing_10_8.ps1 ├── chapter_11 ├── chapter_11_listings.ps1 └── listing_11_7.ps1 ├── chapter_12 ├── chapter_12_listings.ps1 ├── listing_12_10.ps1 ├── listing_12_11.ps1 ├── listing_12_12.ps1 ├── listing_12_2.ps1 ├── listing_12_4.ps1 └── listing_12_9.ps1 ├── chapter_13 ├── chapter_13_listings.ps1 ├── listing_13_12.ps1 ├── network_protocol_client.ps1 ├── network_protocol_common.psm1 └── network_protocol_server.ps1 ├── chapter_14 ├── chapter_14_listings.ps1 └── listing_14_32.ps1 ├── chapter_15 ├── chapter_15_listings.ps1 ├── get_server_cert.ps1 ├── listing_15_13.ps1 ├── listing_15_23_to_15_26.ps1 └── listing_15_27_to_15_29.ps1 ├── chapter_2 └── chapter_2_listings.ps1 ├── chapter_3 └── chapter_3_listings.ps1 ├── chapter_4 ├── chapter_4_listings.ps1 ├── listing_4_29.ps1 └── listing_4_35.ps1 ├── chapter_5 └── chapter_5_listings.ps1 ├── chapter_6 ├── chapter_6_listings.ps1 ├── listing_6_1.ps1 └── listing_6_45.ps1 ├── chapter_7 ├── chapter_7_access_check_impl.psm1 ├── chapter_7_listings.ps1 ├── listing_7_14.ps1 ├── listing_7_32.ps1 └── listing_7_33.ps1 ├── chapter_8 └── chapter_8_listings.ps1 └── chapter_9 └── chapter_9_listings.ps1 /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # windows-security-internals 2 | A repository for additional files related to the book Windows Security Internals with PowerShell from No Starch Press. 3 | 4 | Most chapters have consolidated PowerShell listings in the file *chapter_X_listings.ps1*. 5 | The individual listings should be copied and ran in a PowerShell console, it's not recommended to execute the entire script at once. 6 | Some chapters also have individual listings where special setup is required, primarily when the script needs to be run as an administrator. 7 | 8 | The book can be purchased from book sellers or direct from [No Starch Press](https://nostarch.com/windows-security-internals). 9 | -------------------------------------------------------------------------------- /appendix_a/appendix_a_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing A-1 2 | New-VMSwitch -Name "Domain Network" -SwitchType Internal 3 | $index = (Get-NetAdapter | Where-Object Name -Match "Domain Network").ifIndex 4 | New-NetIPAddress -IPAddress 192.168.99.1 -PrefixLength 24 -InterfaceIndex $index 5 | New-NetNat -Name DomNAT -InternalIPInterfaceAddressPrefix 192.168.99.0/24 6 | 7 | # Listing A-2 8 | function New-TestVM { 9 | param( 10 | [Parameter(Mandatory)] 11 | [string]$VmName, 12 | [Parameter(Mandatory)] 13 | [string]$InstallerImage, 14 | [Parameter(Mandatory)] 15 | [string]$VmDirectory 16 | ) 17 | New-VM -Name $VmName -MemoryStartupBytes 2GB -Generation 2 -NewVHDPath "$VmDirectory\$VmName\$VmName.vhdx" -NewVHDSizeBytes 80GB -Path "$VmDirectory" -SwitchName "Domain Network" 18 | Set-VM -Name $VmName -ProcessorCount 2 -DynamicMemory 19 | Add-VMScsiController -VMName $VmName 20 | Add-VMDvdDrive -VMName $VmName -ControllerNumber 1 -ControllerLocation 0 -Path $InstallerImage 21 | $dvd = Get-VMDvdDrive -VMName $VmName 22 | Set-VMFirmware -VMName $VmName -FirstBootDevice $dvd 23 | } 24 | 25 | # Listing A-3 26 | New-TestVM -VmName "PRIMARYDC" -InstallerImage "C:\iso\server.iso" -VmDirectory "C:\vms" 27 | vmconnect localhost PRIMARYDC 28 | Start-VM -VmName "PRIMARYDC" 29 | 30 | # Listing A-4 31 | $index = (Get-NetAdapter).ifIndex 32 | New-NetIPAddress -InterfaceIndex $index -IPAddress 192.168.99.10 -PrefixLength 24 -DefaultGateway 192.168.99.1 33 | Set-DnsClientServerAddress -InterfaceIndex $index -ServerAddresses 8.8.8.8 34 | 35 | # Listing A-5 36 | Rename-Computer -NewName "PRIMARYDC" -Restart 37 | 38 | # Listing A-6 39 | Install-WindowsFeature AD-Domain-Services 40 | Install-ADDSForest -DomainName mineral.local -DomainNetbiosName MINERAL -InstallDns -Force 41 | 42 | # Listing A-7 43 | Set-ADDefaultDomainPasswordPolicy -Identity mineral.local -MaxPasswordAge 0 44 | $pwd = ConvertTo-SecureString -String "Passw0rd1" -AsPlainText -Force 45 | New-ADUser -Name alice -Country USA -AccountPassword $pwd -GivenName "Alice Bombas" -Enabled $PS> $pwd = ConvertTo-SecureString -String "Passw0rd2" -AsPlainText -Force 46 | New-ADUser -Name bob -Country JP -AccountPassword $pwd -GivenName "Bob Cordite" -Enabled $true 47 | New-ADGroup -Name 'Local Resource' -GroupScope DomainLocal 48 | Add-ADGroupMember -Identity 'Local Resource' -Members 'alice' 49 | New-ADGroup -Name 'Universal Group' -GroupScope Universal 50 | Add-ADGroupMember -Identity 'Universal Group' -Members 'bob' 51 | New-ADGroup -Name 'Global Group' -GroupScope Global 52 | Add-ADGroupMember -Identity 'Global Group' -Members 'alice','bob' 53 | 54 | # Listing A-8 55 | New-TestVM -VmName "GRAPHITE" -InstallerImage "C:\iso\client.iso" -VmDirectory "C:\vms" 56 | vmconnect localhost GRAPHITE 57 | Start-VM -VmName "GRAPHITE" # Listing A-9 $index = (Get-NetAdapter).ifIndex 58 | New-NetIPAddress -InterfaceIndex $index -IPAddress 192.168.99.50 -PrefixLength 24 -DefaultGateway 192.168.99.1 59 | Set-DnsClientServerAddress -InterfaceIndex $index -ServerAddresses 192.168.99.10 60 | Resolve-DnsName primarydc.mineral.local 61 | Rename-Computer -NewName "GRAPHITE" -Restart 62 | 63 | # Listing A-10 64 | $creds = Get-Credential 65 | Add-Computer -DomainName MINERAL -Credential $creds 66 | Add-LocalGroupMember -Group 'Administrators' -Member 'MINERAL\alice' 67 | Restart-Computer 68 | 69 | # Listing A-11 70 | New-TestVM -VmName "SALESDC" -InstallerImage "C:\iso\server.iso" -VmDirectory "C:\vms" 71 | vmconnect localhost SALESDC 72 | Start-VM -VmName "SALESDC" 73 | 74 | # Listing A-12 75 | $index = (Get-NetAdapter).ifIndex 76 | New-NetIPAddress -InterfaceIndex $index -IPAddress 192.168.99.110 -PrefixLength 24 -DefaultGateway 192.168.99.1 77 | Set-DnsClientServerAddress -InterfaceIndex $index -ServerAddresses 192.168.99.10 78 | Rename-Computer -NewName "SALESDC" -Restart 79 | 80 | # Listing A-13 81 | Install-WindowsFeature AD-Domain-Services 82 | Install-ADDSDomain -NewDomainName sales -ParentDomainName mineral.local -NewDomainNetbiosName SALES -InstallDns -Credential (Get-Credential) -Force 83 | 84 | # Listing A-14 85 | Get-ADTrust -Filter * | Select Target, Direction 86 | 87 | -------------------------------------------------------------------------------- /chapter_10/chapter_10_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 10-1 2 | Get-LocalUser | Select-Object Name, Enabled, Sid 3 | 4 | # Listing 10-2 5 | Get-NtSid -Name $env:COMPUTERNAME 6 | 7 | # Listing 10-4 8 | Get-LocalGroup | Select-Object Name, Sid 9 | 10 | # Listing 10-5 11 | Get-LocalGroupMember -Name "Awesome Users" 12 | 13 | # Listing 10-7 14 | Get-NtAccountRight -Type Privilege 15 | 16 | # Listing 10-9 17 | $server = Connect-SamServer -ServerName 'localhost' 18 | Format-NtSecurityDescriptor $server -Summary -MapGeneric 19 | 20 | # Listing 10-10 21 | Get-SamDomain -Server $server -InfoOnly 22 | $domain = Get-SamDomain -Server $server -Name "$env:COMPUTERNAME" 23 | $domain.PasswordInformation 24 | 25 | # Listing 10-11 26 | Get-SamUser -Domain $domain -InfoOnly 27 | $user = Get-SamUser -Domain $domain -Name "WDAGUtilityAccount" 28 | $user.UserAccountControl 29 | Format-NtSecurityDescriptor $user -Summary 30 | 31 | # Listing 10-12 32 | Get-SamGroup -Domain $domain -InfoOnly 33 | $group = Get-SamGroup $domain -Name "None" 34 | Get-SamGroupMember -Group $group 35 | 36 | # Listing 10-13 37 | Get-SamAlias -Domain $domain -InfoOnly 38 | $alias = Get-SamAlias -Domain $domain -Name "Awesome Users" 39 | Get-SamAliasMember -Alias $alias 40 | 41 | # Listing 10-14 42 | $policy = Get-LsaPolicy 43 | Format-NtSecurityDescriptor $policy -Summary 44 | 45 | # Listing 10-15 46 | $policy = Get-LsaPolicy -Access ViewLocalInformation 47 | Get-LsaAccount -Policy $policy -InfoOnly 48 | $sid = Get-NtSid -KnownSid BuiltinUsers 49 | $account = Get-LsaAccount -Policy $policy -Sid $sid 50 | Format-NtSecurityDescriptor -Object $account -Summary 51 | 52 | # Listing 10-18 53 | $policy = Get-LsaPolicy -ServerName "PRIMARYDC" 54 | Get-LsaTrustedDomain -Policy $policy -InfoOnly 55 | 56 | # Listing 10-19 57 | $policy = Get-LsaPolicy -Access LookupNames 58 | Get-LsaName -Policy $policy -Sid "S-1-1-0", "S-1-5-32-544" 59 | Get-LsaSid -Policy $policy -Name "Guest" | Select-Object Sddl 60 | 61 | # Listing 10-37 62 | function Get-SidNames { 63 | param( 64 | [string]$Server, 65 | [string]$Domain, 66 | [int]$MinRid = 500, 67 | [int]$MaxRid = 1499 68 | ) 69 | if ("" -eq $Domain) { 70 | $Domain = $Server 71 | } 72 | Use-NtObject($policy = Get-LsaPolicy -SystemName $Server -Access LookupNames) { 73 | $domain_sid = Get-LsaSid $policy "$Domain\" 74 | $sids = $MinRid..$MaxRid | ForEach-Object { 75 | Get-NtSid -BaseSid $domain_sid -RelativeIdentifier $_ 76 | } 77 | Get-LsaName -Policy $policy -Sid $sids | Where-Object NameUse -ne "Unknown" 78 | } 79 | } 80 | Get-SidNames -Server $env:COMPUTERNAME | Select-Object QualifiedName, Sddl 81 | 82 | # Listing 10-38 83 | function Get-UserObject([string]$Server, [string]$User) { 84 | Use-NtObject($sam = Connect-SamServer -ServerName $Server) { 85 | Use-NtObject($domain = Get-SamDomain -Server $sam -User) { 86 | Get-SamUser -Domain $domain -Name $User -Access ForcePasswordChange 87 | } 88 | } 89 | } 90 | 91 | function Set-UserPassword([string]$Server, [string]$User, [bool]$Expired) { 92 | Use-NtObject($user_obj = Get-UserObject $Server $User) { 93 | $pwd = Read-Host -AsSecureString -Prompt "New Password" 94 | $user_obj.SetPassword($pwd, $Expired) 95 | } 96 | } 97 | 98 | # Listing 10-39 99 | Set-UserPassword -Server $env:COMPUTERNAME "user" -------------------------------------------------------------------------------- /chapter_10/listing_10_16.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 10-16 4 | $policy = Get-LsaPolicy -Access ViewLocalInformation 5 | Get-LsaAccount -Policy $policy -InfoOnly 6 | $sid = Get-NtSid -KnownSid BuiltinUsers 7 | $account = Get-LsaAccount -Policy $policy -Sid $sid 8 | Format-NtSecurityDescriptor -Object $account -Summary 9 | 10 | $account.Privileges 11 | $account.SystemAccess -------------------------------------------------------------------------------- /chapter_10/listing_10_17.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 10-17 4 | $policy = Get-LsaPolicy 5 | $secret = Get-LsaSecret -Policy $policy -Name "DPAPI_SYSTEM" 6 | Format-NtSecurityDescriptor $secret -Summary 7 | $value = $secret.Query() 8 | $value 9 | $value.CurrentValue | Out-HexDump -ShowAll -------------------------------------------------------------------------------- /chapter_10/listing_10_20.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 10-20 4 | $domain_sid = Get-NtSid -SecurityAuthority Nt -RelativeIdentifier 99 5 | $user_sid = Get-NtSid -BaseSid $domain_sid -RelativeIdentifier 1000 6 | $domain = "CUSTOMDOMAIN" 7 | $user = "USER" 8 | Invoke-NtToken -System { 9 | Add-NtSidName -Domain $domain -Sid $domain_sid -Register 10 | Add-NtSidName -Domain $domain -Name $user -Sid $user_sid -Register 11 | Use-NtObject($policy = Get-LsaPolicy) { 12 | Get-LsaName -Policy $policy -Sid $domain_sid, $user_sid 13 | } 14 | Remove-NtSidname -Sid $user_sid -Unregister 15 | Remove-NtSidName -Sid $domain_sid -Unregister 16 | } -------------------------------------------------------------------------------- /chapter_10/listing_10_21_to_10_34.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 10-21 4 | Enable-NtTokenPrivilege SeBackupPrivilege 5 | New-PSDrive -PSProvider NtObjectManager -Name SEC -Root ntkey:MACHINE 6 | ls -Depth 1 -Recurse SEC:\SAM\SAM 7 | 8 | # Listing 10-22 9 | $rid = 500 10 | $key = Get-Item ("SEC:\SAM\SAM\Domains\Account\Users\{0:X08}" -f $rid) 11 | $key.Values 12 | function Get-VariableAttribute($key, [int]$Index) { 13 | $MaxAttr = 0x11 14 | $V = $key["V"].Data 15 | $base_ofs = $Index * 12 16 | $curr_ofs = [System.BitConverter]::ToInt32($V, $base_ofs) + ($MaxAttr * 12) 17 | $len = [System.BitConverter]::ToInt32($V, $base_ofs + 4) 18 | if ($len -gt 0) { 19 | $V[$curr_ofs..($curr_ofs+$len-1)] 20 | } else { 21 | @() 22 | } 23 | } 24 | $sd = Get-VariableAttribute $key -Index 0 25 | New-NtSecurityDescriptor -Byte $sd 26 | Get-VariableAttribute $key -Index 1 | Out-HexDump -ShowAll 27 | 28 | $sd = Get-VariableAttribute $key -Index 0 29 | New-NtSecurityDescriptor -Byte $sd 30 | $lm = Get-VariableAttribute $key -Index 13 31 | $lm | Out-HexDump -ShowAddress 32 | $nt = Get-VariableAttribute $key -Index 14 33 | $nt | Out-HexDump -ShowAddress 34 | 35 | # Listing 10-23 36 | function Get-LsaSystemKey { 37 | $names = "JD", "Skew1", "GBG", "Data" 38 | $keybase = "NtKey:\MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\" 39 | $key = $names | ForEach-Object { 40 | $key = Get-Item "$keybase\$_" 41 | $key.ClassName | ConvertFrom-HexDump 42 | } 43 | 8, 5, 4, 2, 11, 9, 13, 3, 0, 6, 1, 12, 14, 10, 15, 7 | 44 | ForEach-Object { 45 | $key[$_] 46 | } 47 | } 48 | Get-LsaSystemKey | Out-HexDump 49 | 50 | # Listing 10-24 51 | function Unprotect-PasswordEncryptionKey { 52 | $key = Get-Item SEC:\SAM\SAM\Domains\Account 53 | $fval = $key["F"].Data 54 | $enctype = [BitConverter]::ToInt32($fval, 0x68) 55 | $endofs = [BitConverter]::ToInt32($fval, 0x6C) + 0x68 56 | $data = $fval[0x70..($endofs-1)] 57 | switch($enctype) { 58 | 1 { Unprotect-PasswordEncryptionKeyRC4 -Data $data } 59 | 2 { Unprotect-PasswordEncryptionKeyAES -Data $data } 60 | default { throw "Unknown password encryption format" } 61 | } 62 | } 63 | 64 | # Listing 10-25 65 | function Get-MD5Hash([byte[]]$Data) { 66 | $md5 = [System.Security.Cryptography.MD5]::Create() 67 | $md5.ComputeHash($Data) 68 | } 69 | 70 | function Get-StringBytes([string]$String) { 71 | [System.Text.Encoding]::ASCII.GetBytes($String + "`0") 72 | } 73 | 74 | function Compare-Bytes([byte[]]$Left, [byte[]]$Right) { 75 | [Convert]::ToBase64String($Left) -eq [Convert]::ToBase64String($Right) 76 | } 77 | 78 | function Unprotect-PasswordEncryptionKeyRC4([byte[]]$Data) { 79 | $syskey = Get-LsaSystemKey 80 | $qiv = Get-StringBytes '!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%' 81 | $niv = Get-StringBytes '0123456789012345678901234567890123456789' 82 | $rc4_key = Get-MD5Hash -Data ($Data[0..15] + $qiv + $syskey + $niv) 83 | $decbuf = Unprotect-RC4 -Data $data -Offset 0x10 -Length 32 -Key $rc4_key 84 | $pek = $decbuf[0..15] 85 | $hash = $decbuf[16..31] 86 | $pek_hash = Get-MD5Hash -Data ($pek + $niv + $pek + $qiv) 87 | if (!(Compare-Bytes $hash $pek_hash)) { 88 | throw "Invalid password key for RC4." 89 | } 90 | $pek 91 | } 92 | 93 | function Unprotect-AES([byte[]]$Data, [byte[]]$IV, [byte[]]$Key) { 94 | $aes = [System.Security.Cryptography.Aes]::Create() 95 | $aes.Mode = "CBC" 96 | $aes.Padding = "PKCS7" 97 | $aes.Key = $Key 98 | $aes.IV = $IV 99 | $aes.CreateDecryptor().TransformFinalBlock($Data, 0, $Data.Length) 100 | } 101 | 102 | # Listing 10-26 103 | function Unprotect-PasswordEncryptionKeyAES([byte[]]$Data) { 104 | $syskey = Get-LsaSystemKey 105 | $hash_len = [System.BitConverter]::ToInt32($Data, 0) 106 | $enc_len = [System.BitConverter]::ToInt32($Data, 4) 107 | $iv = $Data[0x8..0x17] 108 | $pek = Unprotect-AES -Key $syskey -IV $iv -Data $Data[0x18..(0x18+$enc_len-1)] 109 | $hash_ofs = 0x18+$enc_len 110 | $hash_data = $Data[$hash_ofs..($hash_ofs+$hash_len-1)] 111 | $hash = Unprotect-AES -Key $syskey -IV $iv -Data $hash_data 112 | $sha256 = [System.Security.Cryptography.SHA256]::Create() 113 | $pek_hash = $sha256.ComputeHash($pek) 114 | if (!(Compare-Bytes $hash $pek_hash)) { 115 | throw "Invalid password key for AES." 116 | } 117 | $pek 118 | } 119 | 120 | # Listing 10-27 121 | Unprotect-PasswordEncryptionKey | Out-HexDump 122 | 123 | # Listing 10-28 124 | function Unprotect-PasswordHash([byte[]]$Key, [byte[]]$Data, [int]$Rid, [int]$Type) { 125 | $enc_type = [BitConverter]::ToInt16($Data, 2) 126 | switch($enc_type) { 127 | 1 { Unprotect-PasswordHashRC4 -Key $Key -Data $Data -Rid $Rid -Type $Type } 128 | 2 { Unprotect-PasswordHashAES -Key $Key -Data $Data } 129 | default { throw "Unknown hash encryption format" } 130 | } 131 | } 132 | 133 | # Listing 10-29 134 | function Unprotect-PasswordHashRC4([byte[]]$Key, [byte[]]$Data, [int]$Rid, [int]$Type) { 135 | if ($Data.Length -lt 0x14) { 136 | return @() 137 | } 138 | $iv = switch($Type) { 139 | 1 { "LMPASSWORD" } 140 | 2 { "NTPASSWORD" } 141 | 3 { "LMPASSWORDHISTORY" } 142 | 4 { "NTPASSWORDHISTORY" } 143 | 5 { "MISCCREDDATA" } 144 | } 145 | $key_data = $Key + [BitConverter]::GetBytes($Rid) + (Get-StringBytes $iv) 146 | $rc4_key = Get-MD5Hash -Data $key_data 147 | Unprotect-RC4 -Key $rc4_key -Data $Data -Offset 4 -Length 16 148 | } 149 | 150 | # Listing 10-30 151 | function Unprotect-PasswordHashAES([byte[]]$Key, [byte[]]$Data) { 152 | $length = [BitConverter]::ToInt32($Data, 4) 153 | if ($length -eq 0) { 154 | return @() 155 | } 156 | $IV = $Data[8..0x17] 157 | $value = $Data[0x18..($Data.Length-1)] 158 | Unprotect-AES -Key $Key -IV $IV -Data $value 159 | } 160 | 161 | # Listing 10-31 162 | $pek = Unprotect-PasswordEncryptionKey 163 | $lm_dec = Unprotect-PasswordHash -Key $pek -Data $lm -Rid $rid -Type 1 164 | $lm_dec | Out-HexDump 165 | 166 | $nt_dec = Unprotect-PasswordHash -Key $pek -Data $nt -Rid $rid -Type 2 167 | $nt_dec | Out-HexDump 168 | 169 | # Listing 10-32 170 | function Get-UserDESKey([uint32]$Rid) { 171 | $ba = [System.BitConverter]::GetBytes($Rid) 172 | $key1 = ConvertTo-DESKey $ba[2], $ba[1], $ba[0], $ba[3], $ba[2], $ba[1], $ba[0] 173 | $key2 = ConvertTo-DESKey $ba[1], $ba[0], $ba[3], $ba[2], $ba[1], $ba[0], $ba[3] 174 | $key1, $key2 175 | } 176 | 177 | function ConvertTo-DESKey([byte[]]$Key) { 178 | $k = [System.BitConverter]::ToUInt64($Key + 0, 0) 179 | for($i = 7; $i -ge 0; $i--) { 180 | $curr = ($k -shr ($i * 7)) -band 0x7F 181 | $b = $curr 182 | $b = $b -bxor ($b -shr 4) 183 | $b = $b -bxor ($b -shr 2) 184 | $b = $b -bxor ($b -shr 1) 185 | ($curr -shl 1) -bxor ($b -band 0x1) -bxor 1 186 | } 187 | } 188 | 189 | # Listing 10-33 190 | function Unprotect-DES([byte[]]$Key, [byte[]]$Data, [int]$Offset) { 191 | $des = [Security.Cryptography.DES]::Create() 192 | $des.Key = $Key 193 | $des.Mode = "ECB" 194 | $des.Padding = "None" 195 | $des.CreateDecryptor().TransformFinalBlock($Data, $Offset, 8) 196 | } 197 | 198 | function Unprotect-PasswordHashDES([byte[]]$Hash, [uint32]$Rid) { 199 | $keys = Get-UserDESKey -Rid $Rid 200 | (Unprotect-DES -Key $keys[0] -Data $Hash -Offset 0) + 201 | (Unprotect-DES -Key $keys[1] -Data $Hash -Offset 8) 202 | } 203 | 204 | # Listing 10-34 205 | Unprotect-PasswordHashDES -Hash $nt_dec -Rid $rid | Out-HexDump 206 | Get-MD4Hash -String "adminpwd" | Out-HexDump -------------------------------------------------------------------------------- /chapter_10/listing_10_3.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 10-3 4 | $password = Read-Host -AsSecureString -Prompt "Password" 5 | $name = "Test" 6 | New-LocalUser -Name $name -Password $password -Description "Test User" 7 | Get-NtSid -Name "$env:COMPUTERNAME\$name" 8 | 9 | Remove-LocalUser -Name $name -------------------------------------------------------------------------------- /chapter_10/listing_10_35_to_10_36.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | Enable-NtTokenPrivilege SeBackupPrivilege 4 | New-PSDrive -PSProvider NtObjectManager -Name SEC -Root ntkey:MACHINE 5 | 6 | # Listing 10-35 7 | ls -Depth 1 -Recurse SEC:\SECURITY 8 | 9 | # Listing 10-36 10 | ls SEC:\SECURITY\Policy\Secrets 11 | ls SEC:\SECURITY\Policy\Secrets\DPAPI_SYSTEM 12 | $key = Get-Item SEC:\SECURITY\Policy\Secrets\DPAPI_SYSTEM\CurrVal 13 | $key.DefaultValue.Data | Out-HexDump -ShowAll -------------------------------------------------------------------------------- /chapter_10/listing_10_40.ps1: -------------------------------------------------------------------------------- 1 | function Get-PasswordHash { 2 | param( 3 | [byte[]]$Pek, 4 | $Key, 5 | $Rid, 6 | [switch]$LmHash 7 | ) 8 | $index = 14 9 | $type = 2 10 | if ($LmHash) { 11 | $index = 13 12 | $type = 1 13 | } 14 | $hash_enc = Get-VariableAttribute $key -Index $Index 15 | if ($null -eq $hash_enc) { 16 | return @() 17 | } 18 | $hash_dec = Unprotect-PasswordHash -Key $Pek -Data $hash_enc -Rid $Rid -Type $type 19 | if ($hash_dec.Length -gt 0) { 20 | Unprotect-PasswordHashDES -Hash $hash_dec -Rid $Rid 21 | } 22 | } 23 | 24 | function Get-UserHashes { 25 | param( 26 | [Parameter(Mandatory)] 27 | [byte[]]$Pek, 28 | [Parameter(Mandatory, ValueFromPipeline)] 29 | $Key 30 | ) 31 | 32 | PROCESS { 33 | try { 34 | if ($null -eq $Key["V"]) { 35 | return 36 | } 37 | $rid = [int]::Parse($Key.Name, "HexNumber") 38 | $name = Get-VariableAttribute $key -Index 1 39 | [PSCustomObject]@{ 40 | Name=[System.Text.Encoding]::Unicode.GetString($name) 41 | LmHash = Get-PasswordHash $Pek $key $rid -LmHash 42 | NtHash = Get-PasswordHash $Pek $key $rid 43 | Rid = $rid 44 | } 45 | } catch { 46 | Write-Error $_ 47 | } 48 | } 49 | } 50 | $pek = Unprotect-PasswordEncryptionKey 51 | ls "SEC:\SAM\SAM\Domains\Account\Users" | Get-UserHashes $pek -------------------------------------------------------------------------------- /chapter_10/listing_10_6.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator $name = "TestGroup" New-LocalGroup -Name $name -Description "Test Group" 2 | Get-NtSid -Name "$env:COMPUTERNAME\$name" 3 | Add-LocalGroupMember -Name $name -Member "$env:USERDOMAIN\$env:USERNAME" 4 | Get-LocalGroupMember -Name $name 5 | 6 | Remove-LocalGroup -Name $name -------------------------------------------------------------------------------- /chapter_10/listing_10_8.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 10-8 4 | Get-NtAccountRight -Type Logon -------------------------------------------------------------------------------- /chapter_11/chapter_11_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 11-1 2 | $cap_name = Get-WindowsCapability -Online | Where-Object Name -Match 'Rsat.ActiveDirectory.DS-LDS.Tools' 3 | Add-WindowsCapability -Name $cap_name.Name -Online 4 | 5 | # Listing 11-2 6 | $forest = Get-ADForest 7 | $forest.Domains 8 | $forest.GlobalCatalogs 9 | Get-ADDomain | Format-List PDCEmulator, DomainSID, DNSRoot, NetBIOSName 10 | Get-ADDomainController | Select-Object Name, Domain 11 | Get-ADTrust -Filter * | Select-Object Target, Direction, TrustType 12 | 13 | # Listing 11-3 14 | Get-ADUser -Filter * | Select-Object SamAccountName, Enabled, SID 15 | 16 | # Listing 11-4 17 | Get-ADGroup -Filter * | Select-Object SamAccountName, SID, GroupScope 18 | 19 | # Listing 11-5 20 | Get-ADGroupMember -Identity Administrators | Select Name, objectClass 21 | Get-LocalGroupMember -Name Administrators 22 | 23 | # Listing 11-6 24 | Get-ADComputer -Filter * | Select-Object SamAccountName, Enabled, SID 25 | 26 | # Listing 11-8 27 | Get-ADRootDSE | Format-List '*NamingContext' # Listing 11-9 $root_dn = (Get-ADRootDSE).defaultNamingContext 28 | Get-ADObject -SearchBase $root_dn -SearchScope OneLevel -Filter * | Select-Object DistinguishedName, ObjectClass 29 | Get-ADObject -Identity "CN=Builtin,$root_dn" | Format-List 30 | Get-ADObject -Identity "CN=Builtin,$root_dn" -Properties * | Format-List 31 | 32 | # Listing 11-10 33 | Get-ADObject -Identity 'CN=Users,DC=sales,DC=mineral,DC=local' 34 | 35 | # Listing 11-11 36 | $dn = 'CN=Users,DC=sales,DC=mineral,DC=local' 37 | $obj_sales = Get-ADObject -Identity $dn -Server SALES -Properties * 38 | $obj_sales.DistinguishedName 39 | $obj_gc = Get-ADObject -Identity $dn -Server :3268 -Properties * 40 | $obj_gc.DistinguishedName 41 | ($obj_sales | Get-Member -MemberType Property | Measure-Object).Count 42 | ($obj_gc | Get-Member -MemberType Property | Measure-Object).Count 43 | 44 | # Listing 11-12 45 | $schema_dn = (Get-ADRootDSE).schemaNamingContext 46 | Get-ADObject -SearchBase $schema_dn -SearchScope OneLevel -Filter * | Sort-Object Name | Select-Object Name, ObjectClass 47 | Get-ADObject -SearchBase $schema_dn -Filter { 48 | ObjectClass -eq "classSchema" 49 | } -Properties * | Sort-Object Name | Format-List Name, {[guid]$_.schemaIDGUID}, mayContain, mustContain, systemMayContain, systemMustContain, auxiliaryClass, systemAuxiliaryClass, SubClassOf 50 | Get-ADObject -SearchBase $schema_dn -Filter { 51 | lDAPDisplayName -eq "uid" 52 | } -Properties * | Format-List adminDescription, {[guid]$_.schemaIDGUID}, attributeSyntax, oMSyntax, oMObjectClass 53 | 54 | # Listing 11-13 55 | Get-DsSchemaClass | Sort-Object Name 56 | 57 | # Listing 11-14 58 | $cls = Get-DsSchemaClass -Name "account" 59 | $cls | Format-List 60 | $cls.Attributes 61 | $cls.Attributes | Get-DsSchemaAttribute 62 | Get-DsSchemaClass -Parent $cls -Recurse 63 | 64 | # Listing 11-15 65 | (Get-DsSchemaClass top).Attributes | Where-Object Name -Match nTSecurityDescriptor 66 | 67 | # Listing 11-16 68 | $root_dn = (Get-ADRootDSE).defaultNamingContext 69 | $obj = Get-ADObject -Identity $root_dn -Properties "nTSecurityDescriptor" 70 | $obj.nTSecurityDescriptor.Access 71 | Format-Win32SecurityDescriptor -Name $root_dn -Type Ds 72 | 73 | # Listing 11-17 74 | $sd = New-NtSecurityDescriptor -Type DirectoryService 75 | Add-NtSecurityDescriptorAce $sd -KnownSid BuiltinAdministrators -Access All 76 | $root_dn = (Get-ADRootDSE).defaultNamingContext 77 | $obj = New-ADObject -Type "container" -Name "SDDEMO" -Path $root_dn -OtherAttributes @{nTSecurityDescriptor=$sd.ToByteArray()} -PassThru 78 | Format-Win32SecurityDescriptor -Name $obj.DistinguishedName -Type Ds 79 | 80 | # Listing 11-18 81 | $root_dn = (Get-ADRootDSE).defaultNamingContext 82 | $cls = Get-DsSchemaClass -Name "container" 83 | $parent = Get-Win32SecurityDescriptor $root_dn -Type Ds 84 | $sd = New-NtSecurityDescriptor -Parent $parent -EffectiveToken -ObjectType $cls.SchemaId -Creator $cls.DefaultSecurityDescriptor -Type DirectoryService -AutoInherit DaclAutoInherit, SaclAutoInherit -Container 85 | Format-NtSecurityDescriptor $sd -Summary 86 | $std_sd = Edit-NtSecurityDescriptor $sd -Standardize -PassThru 87 | Compare-NtSecurityDescriptor $std_sd $sd -Report 88 | 89 | # Listing 11-19 90 | (Get-DsHeuristics).DontStandardizeSDs 91 | 92 | # Listing 11-20 93 | $dn = "CN=SomeObject,DC=mineral,DC=local" 94 | $sd = New-NtSecurityDescriptor "D:(A;;GA;;;WD)" 95 | Set-Win32SecurityDescriptor $dn -Type Ds -SecurityDescriptor $sd -SecurityInformation Dacl 96 | 97 | # Listing 11-21 98 | Get-DsSDRightsEffective -DistinguishedName $dn 99 | 100 | # Listing 11-22 101 | $root_dn = (Get-ADRootDSE).defaultNamingContext 102 | $user_dn = "CN=Users,$root_dn" 103 | $curr_sd = Get-Win32SecurityDescriptor "CN=Users,$root_dn" -Type Ds 104 | Format-NtSecurityDescriptor $curr_sd -Summary 105 | $new_sd = New-NtSecurityDescriptor "D:(A;;GA;;;WD)" 106 | Edit-NtSecurityDescriptor -SecurityDescriptor $curr_sd -NewSecurityDescriptor $new_sd -SecurityInformation Dacl -Flags DaclAutoInherit, SaclAutoInherit 107 | $cls = Get-DsObjectSchemaClass $user_dn 108 | $parent = Get-Win32SecurityDescriptor $root_dn -Type Ds 109 | $sd = New-NtSecurityDescriptor -Parent $parent -ObjectType $cls.SchemaId -Creator $curr_sd -Container -Type DirectoryService -AutoInherit DaclAutoInherit, SaclAutoInherit, AvoidOwnerCheck, AvoidOwnerRestriction, AvoidPrivilegeCheck -EffectiveToken 110 | Edit-NtSecurityDescriptor $sd -Standardize 111 | Format-NtSecurityDescriptor $sd -Summary 112 | 113 | # Listing 11-23 114 | $root_dn = (Get-ADRootDSE).defaultNamingContext 115 | $user_dn = "CN=Users,$root_dn" 116 | $cls = Get-DsObjectSchemaClass -DistinguishedName $user_dn 117 | Search-Win32SecurityDescriptor -Name $user_dn -Type Ds -ObjectType $cls.SchemaId 118 | 119 | # Listing 11-24 120 | $sd = New-NtSecurityDescriptor -Type DirectoryService -Owner "SY" -Group "SY" 121 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type Allowed -Access List 122 | $user = Get-DsSchemaClass -Name "user" 123 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type AllowedObject -Access CreateChild -ObjectType $user.SchemaId 124 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation Dacl -ResolveObjectType 125 | Get-NtGrantedAccess $sd -ObjectType $user CreateChild, List 126 | $cont = Get-DsSchemaClass -Name "container" 127 | Get-NtGrantedAccess $sd -ObjectType $cont 128 | 129 | # Listing 11-25 130 | Get-DsSchemaClass "user" -Inferior 131 | 132 | # Listing 11-26 133 | $sd = New-NtSecurityDescriptor -Type DirectoryService -Owner "DA" -Group "DA" 134 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type Allowed -Access ReadProp 135 | $attr = Get-DsSchemaAttribute -Name "accountExpires" 136 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type AllowedObject -Access WriteProp -ObjectType $attr.SchemaId 137 | Get-NtGrantedAccess $sd -ObjectType $attr 138 | $pwd = Get-DsSchemaAttribute -Name "pwdLastSet" 139 | Get-NtGrantedAccess $sd -ObjectType $pwd 140 | 141 | # Listing 11-27 142 | $user = Get-DsSchemaClass -Name "user" 143 | $obj_tree = New-ObjectTypeTree $user 144 | Add-ObjectTypeTree -Tree $obj_tree $attr 145 | Add-ObjectTypeTree -Tree $obj_tree $pwd 146 | Get-NtGrantedAccess $sd -ObjectType $obj_tree -ResultList -PassResult | Format-Table Status, SpecificGrantedAccess, Name 147 | Get-NtGrantedAccess $sd -ObjectType $obj_tree -ResultList -PassResult -Access WriteProp | Format-Table Status, SpecificGrantedAccess, Name 148 | 149 | # Listing 11-28 150 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type AllowedObject -Access WriteProp -ObjectType $user.SchemaId 151 | Get-NtGrantedAccess $sd -ObjectType $obj_tree -ResultList -PassResult | Format-Table Status, SpecificGrantedAccess, Name 152 | 153 | # Listing 11-29 154 | (Get-DsSchemaClass user -Recurse -IncludeAuxiliary | Sort-Object SchemaId -Unique | Select-Object -ExpandProperty Attributes).Count 155 | 156 | # Listing 11-30 157 | $config_dn = (Get-ADRootDSE).configurationNamingContext 158 | $extended_dn = "CN=Extended-Rights,$config_dn" 159 | Get-ADObject -SearchBase $extended_dn -SearchScope OneLevel -Filter * -Properties * | Group-Object { 160 | Get-NtAccessMask $_.validAccesses -AsSpecificAccess DirectoryService 161 | } 162 | 163 | # Listing 11-31 164 | $attr = Get-DsSchemaAttribute -Name "accountExpires" 165 | $prop_set = Get-DsExtendedRight -Attribute $attr 166 | $prop_set 167 | $user = Get-DsSchemaClass user 168 | Get-DsExtendedRight -SchemaClass $user 169 | 170 | # Listing 11-32 171 | $sd = New-NtSecurityDescriptor -Type DirectoryService -Owner "SY" -Group "SY" 172 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type AllowedObject -Access ReadProp -ObjectType $prop_set.RightsId 173 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type AllowedObject -Access WriteProp -ObjectType $attr.SchemaId 174 | $obj_tree = New-ObjectTypeTree -SchemaObject $user 175 | Add-ObjectTypeTree -Tree $obj_tree -SchemaObject $prop_set 176 | Get-NtGrantedAccess $sd -ObjectType $prop_set -ResultList -PassResult | Format-Table SpecificGrantedAccess, Name 177 | 178 | # Listing 11-33 179 | $pwd = Get-DsSchemaAttribute -Name "pwdLastSet" 180 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type DeniedObject -Access ReadProp -ObjectType $pwd.SchemaId 181 | Edit-NtSecurityDescriptor $sd -CanonicalizeDacl 182 | Get-NtGrantedAccess $sd -ObjectType $obj_tree -ResultList -PassResult | Format-Table SpecificGrantedAccess, Name 183 | 184 | # Listing 11-34 185 | Get-DsExtendedRight | Where-Object { 186 | $_.IsControl -and $_.Name -match "password" 187 | } | Select-Object Name, RightsId 188 | 189 | # Listing 11-35 190 | $sd = New-NtSecurityDescriptor -Type DirectoryService -Owner "SY" -Group "SY" 191 | $right = Get-DsExtendedRight -Name 'User-Change-Password' 192 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Type AllowedObject -Access ControlAccess -ObjectType $right.RightsId 193 | $user = Get-DsSchemaClass user 194 | $obj_tree = New-ObjectTypeTree -SchemaObject $user 195 | Add-ObjectTypeTree -Tree $obj_tree -SchemaObject $right 196 | $force = Get-DsExtendedRight -Name 'User-Force-Change-Password' 197 | Add-ObjectTypeTree -Tree $obj_tree -SchemaObject $force 198 | Get-NtGrantedAccess $sd -ObjectType $obj_tree -ResultList -PassResult | Format-Table Status, SpecificGrantedAccess, Name 199 | 200 | # Listing 11-36 201 | Get-DsExtendedRight | Where-Object IsValidatedWrite 202 | 203 | # Listing 11-37 204 | $computer = Get-ADComputer -Identity $env:COMPUTERNAME 205 | $computer.SID.ToString() 206 | Get-DsObjectSid -DistinguishedName $computer.DistinguishedName 207 | 208 | # Listing 11-38 209 | $root_dn = (Get-ADRootDSE).defaultNamingContext 210 | $obj = Get-ADObject $root_dn -Properties 'ms-DS-MachineAccountQuota' 211 | $obj['ms-DS-MachineAccountQuota'] 212 | Get-ADComputer -Filter * -Properties 'mS-DS-CreatorSID' | ForEach-Object { 213 | $creator = $_['mS-DS-CreatorSID'] 214 | if ($creator.Count -gt 0) { 215 | $sid = Get-NtSid -Sddl $creator[0] 216 | Write-Host $_.Name, " - ", $sid.Name 217 | } 218 | } 219 | 220 | # Listing 11-39 221 | $pwd = ConvertTo-SecureString -String "Passw0rd1!!!" -AsPlainText -Force 222 | $name = "DEMOCOMP" 223 | $dnsname = "$name.$((Get-ADDomain).DNSRoot)" 224 | New-ADComputer -Name $name -SAMAccountName "$name`$" -DNSHostName $dnsname -ServicePrincipalNames "HOST/$name" -AccountPassword $pwd -Enabled $true 225 | 226 | # Listing 11-40 227 | $sam = Connect-SamServer -ServerName PRIMARYDC 228 | $domain = Get-SamDomain -Server $sam -User 229 | $user = New-SamUser -Domain $domain -Name 'DEMOCOMP$' -AccountType Workstation 230 | $pwd = ConvertTo-SecureString -String "Passw0rd1!!!" -AsPlainText -Force 231 | $user.SetPassword($pwd, $false) 232 | 233 | # Listing 11-41 234 | $conf_nc = (Get-ADRootDSE).configurationNamingContext 235 | Get-ADObject -SearchBase $conf_nc -SearchScope Subtree -Filter * | ForEach-Object { 236 | $sd = Get-Win32SecurityDescriptor -Name $_.DistinguishedName -Type Ds 237 | if ($sd.RmControl -eq 1) { 238 | $_.DistinguishedName 239 | } 240 | } 241 | 242 | # Listing 11-42 243 | Get-ADClaimType -Filter {DisplayName -eq "Country"} | Format-List ID, ValueType, SourceAttribute, AppliesToClasses 244 | 245 | # Listing 11-43 246 | $policy = Get-ADCentralAccessPolicy -Identity "Secure Room Policy" 247 | $policy | Format-List PolicyID, Members 248 | $policy.Members | ForEach-Object {Get-ADCentralAccessRule -Identity $_} | Format-List Name, ResourceCondition, CurrentAcl 249 | 250 | # Listing 11-44 251 | Get-ADOrganizationalUnit -Filter * -Properties gpLink | Format-List Name, LinkedGroupPolicyObjects 252 | $policy = Get-ADObject -Filter { 253 | ObjectClass -eq "groupPolicyContainer" 254 | } -Properties * 255 | $policy | Format-List displayName, gPCFileSysPath 256 | ls $policy[0].gPCFileSysPath 257 | $dc_policy = $policy | Where-Object DisplayName -eq "Default Domain Controllers Policy" 258 | $dc_path = $dc_policy.gPCFileSysPath 259 | Get-Content "$dc_path\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf" | Select-String "SeEnableDelegationPrivilege", "SeMachineAccountPrivilege" 260 | 261 | # Listing 11-45 262 | function Add-Member($Set, $MemberOf) { 263 | foreach($name in $MemberOf) { 264 | if ($Set.Add($name)) { 265 | $group = Get-ADGroup $name -Properties MemberOf 266 | Add-Member $Set $group.MemberOf 267 | } 268 | } 269 | } 270 | 271 | function Get-UserGroupMembership($User) { 272 | $groups = [System.Collections.Generic.HashSet[string]]::new( 273 | [System.StringComparer]::OrdinalIgnoreCase 274 | ) 275 | Add-Member $groups $User.PrimaryGroup 276 | Add-Member $groups $User.MemberOf 277 | $auth_users = Get-ADObject -Filter { 278 | ObjectClass -eq "foreignSecurityPrincipal" -and Name -eq "S-1-5-11" 279 | } -Properties memberOf 280 | Add-Member $groups $auth_users.MemberOf 281 | $groups | ForEach-Object { Get-DsObjectSid $_ } 282 | } 283 | 284 | function Get-AuthContext($username) { 285 | $user = Get-ADUser -Identity $username -Properties memberOf, primaryGroup -ErrorAction Continue 286 | if ($null -eq $user) { 287 | $user = Get-ADComputer -Identity $username -Properties memberOf, primaryGroup 288 | } 289 | $sids = Get-UserGroupMembership $user 290 | $rm = New-AuthZResourceManager 291 | $ctx = New-AuthZContext -ResourceManager $rm -Sid $user.SID.Value -Flags SkipTokenGroups 292 | Add-AuthZSid $ctx -KnownSid World 293 | Add-AuthZSid $ctx -KnownSid AuthenticatedUsers 294 | Add-AuthZSid $ctx -Sid $sids 295 | $rm.Dispose() 296 | $ctx 297 | } 298 | 299 | $ctx = Get-AuthContext "alice" 300 | $ctx.Groups 301 | 302 | # Listing 11-46 303 | function Get-ObjectInformation($Name) { 304 | $schema_class = Get-DsObjectSchemaClass $Name 305 | $sid = Get-DsObjectSid $Name 306 | $all_classes = Get-DsSchemaClass $schema_class.Name -Recurse -IncludeAuxiliary 307 | $attrs = $all_classes.Attributes | Get-DsSchemaAttribute | Sort Name -Unique 308 | $infs = Get-DsSchemaClass $schema_class.Name -Inferior 309 | $rights = $all_classes | ForEach-Object {Get-DsExtendedRight -SchemaClass $_ } | Sort Name -Unique 310 | [PSCustomObject]@{ 311 | Name=$Name 312 | SecurityDescriptor=Get-Win32SecurityDescriptor -Name $Name -Type Ds 313 | SchemaClass=Get-DsObjectSchemaClass $Name 314 | Principal=$sid 315 | Attributes=$attrs 316 | Inferiors=$infs 317 | PropertySets=$rights | Where-Object IsPropertySet 318 | ControlRight=$rights | Where-Object IsControl 319 | ValidatedWrite=$rights | Where-Object IsValidatedWrite 320 | } 321 | } 322 | 323 | # Listing 11-47 324 | $dn_root = (Get-ADRootDSE).defaultNamingContext 325 | Get-ObjectInformation $dn_root 326 | 327 | # Listing 11-48 328 | function Test-Access($Ctx, $Obj, $ObjTree, $Access) { 329 | Get-AuthZGrantedAccess -Context $ctx -ObjectType $ObjTree -SecurityDescriptor $Obj.SecurityDescriptor -Principal $Obj.Principal -Access $Access | Where-Object IsSuccess 330 | } 331 | 332 | function Get-PropertyObjTree($Obj) { 333 | $obj_tree = New-ObjectTypeTree $obj.SchemaClass 334 | foreach($prop_set in $Obj.PropertySets) { 335 | Add-ObjectTypeTree $obj_tree $prop_set 336 | } 337 | $fake_set = Add-ObjectTypeTree $obj_tree -PassThru -ObjectType "771727b1-31b8-4cdf-ae62-4fe39fadf89e" 338 | foreach($attr in $Obj.Attributes) { 339 | if (-not $attr.IsPropertySet) { 340 | Add-ObjectTypeTree $fake_set $attr 341 | } 342 | } 343 | $obj_tree 344 | } 345 | 346 | function Get-AccessCheckResult($Ctx, $Name) { 347 | try { 348 | $obj = Get-ObjectInformation $Name 349 | $access = Test-Access $ctx $obj $obj.SchemaClass "MaximumAllowed" | Select-Object -ExpandProperty SpecificGrantedAccess 350 | $obj_tree = Get-PropertyObjTree $obj 351 | $write_attr = Test-Access $ctx $obj $obj_tree "WriteProp" 352 | $write_sets = $write_attr | Where-Object Level -eq 1 | Select-Object -ExpandProperty Name 353 | $write_attr = $write_attr | Where-Object Level -eq 2 | Select-Object -ExpandProperty Name 354 | $obj_tree = New-ObjectTypeTree -ObjectType "771727b1-31b8-4cdf-ae62-4fe39fadf89e" 355 | $obj.Inferiors | Add-ObjectTypeTree -Tree $obj_tree 356 | $create_child = Test-Access $ctx $obj $obj_tree "CreateChild" | Where-Object Level -eq 1 | Select-Object -ExpandProperty Name 357 | $delete_child = Test-Access $ctx $obj $obj_tree "DeleteChild" | Where-Object Level -eq 1 | Select-Object -ExpandProperty Name 358 | $control = if ($obj.ControlRight.Count -gt 0) { 359 | $obj_tree = New-ObjectTypeTree -SchemaObject $obj.SchemaClass 360 | $obj.ControlRight | Add-ObjectTypeTree $obj_tree 361 | Test-Access $ctx $obj $obj_tree "ControlAccess" | Where-Object Level -eq 1 | Select-Object -ExpandProperty Name 362 | } 363 | 364 | $write_valid = if ($obj.ValidatedWrite.Count -gt 0) { 365 | $obj_tree = New-ObjectTypeTree -SchemaObject $obj.SchemaClass 366 | $obj.ValidatedWrite | Add-ObjectTypeTree $obj_tree 367 | Test-Access $ctx $obj $obj_tree "Self" | Where-Object Level -eq 1 | Select-Object -ExpandProperty Name 368 | } 369 | [PSCustomObject]@{ 370 | Name=$Obj.Name 371 | Access=$access 372 | WriteAttributes=$write_attr 373 | WritePropertySets=$write_sets 374 | CreateChild=$create_child 375 | DeleteChild=$delete_child 376 | Control=$control 377 | WriteValidated=$write_valid 378 | } 379 | } catch { 380 | Write-Error "Error testing $Name - $_" 381 | } 382 | } 383 | 384 | # Listing 11-49 385 | $dn = "CN=GRAPHITE,CN=Computers,DC=mineral,DC=local" 386 | $ctx = Get-AuthContext 'alice' 387 | Get-AccessCheckResult $ctx $dn 388 | $ctx = Get-AuthContext $dn 389 | Get-AccessCheckResult $ctx $dn 390 | 391 | # Listing 11-50 392 | Get-AccessibleDsObject -NamingContext Default -Recurse 393 | 394 | -------------------------------------------------------------------------------- /chapter_11/listing_11_7.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 11-7 4 | Get-LsaPrivateData '$MACHINE.ACC' | Out-HexDump -ShowAll -------------------------------------------------------------------------------- /chapter_12/chapter_12_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 12-1 2 | Get-LsaPackage | Select-Object Name, Comment 3 | 4 | # Listing 12-3 5 | Get-NtConsoleSession 6 | 7 | # Listing 12-4 8 | $password = Read-Host -AsSecureString -Prompt "Password" 9 | $token = Get-NtToken -Logon -User user -Domain $env:COMPUTERNAME -Password $password -LogonType Network 10 | Get-NtLogonSession -Token $token 11 | 12 | # Listing 12-5 13 | Get-NtTokenId -Authentication 14 | Get-NtTokenId -Token $token -Origin 15 | 16 | # Listing 12-6 17 | Get-NtTokenIntegrityLevel -Token $token 18 | Test-NtTokenImpersonation $token 19 | Set-NtTokenIntegrityLevel -Token $token Medium 20 | Test-NtTokenImpersonation $token 21 | 22 | # Listing 12-7 23 | $token = Get-NtToken -Logon -User user -Domain $env:COMPUTERNAME -Password $password -LogonType Interactive 24 | New-Win32Process cmd.exe -Token $token 25 | 26 | # Listing 12-8 27 | $creds = Read-LsaCredential 28 | $proc = New-Win32Process -CommandLine cmd.exe -Credential $creds 29 | $proc.Process.User -------------------------------------------------------------------------------- /chapter_12/listing_12_10.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 12-10 4 | $password = Read-Host -AsSecureString -Prompt "Password" 5 | $user = New-LocalUser -Name "Test" -Password $password 6 | $sid = $user.Sid.Value 7 | $token = Get-NtToken -Logon -User $user.Name -Password $password -LogonType Interactive 8 | $token.ElevationType 9 | $token.Close() 10 | Add-NtAccountRight -Privilege SeDebugPrivilege -Sid $sid 11 | $token = Get-NtToken -Logon -User $user.Name -SecurePassword $password -LogonType Interactive 12 | Enable-NtTokenPrivilege -Token $token SeDebugPrivilege -PassThru 13 | $token.ElevationType 14 | $token.Close() 15 | $token = Get-NtToken -Logon -User $user.Name -SecurePassword $password -LogonType Network 16 | Enable-NtTokenPrivilege -Token $token SeDebugPrivilege -PassThru 17 | $token.ElevationType 18 | $token.Close() 19 | Add-NtAccountRight -LogonType SeDenyInteractiveLogonRight -Sid $sid 20 | Add-NtAccountRight -LogonType SeBatchLogonRight -Sid $sid 21 | Get-NtToken -Logon -User $user.Name -SecurePassword $password -LogonType Interactive 22 | $token = Get-NtToken -Logon -User $user.Name -SecurePassword $password -LogonType Batch 23 | Get-NtTokenGroup $token | Where-Object {$_.Sid.Name -eq "NT AUTHORITY\BATCH"} 24 | $token.Close() 25 | Remove-NtAccountRight -Privilege SeDebugPrivilege -Sid $sid 26 | Remove-NtAccountRight -LogonType SeDenyInteractiveLogonRight -Sid $sid 27 | Remove-NtAccountRight -LogonType SeBatchLogonRight -Sid $sid 28 | Remove-LocalUser $user -------------------------------------------------------------------------------- /chapter_12/listing_12_11.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | $curr_sid = Get-NtSid 4 | if ($curr_sid.ToString() -ne "S-1-5-18") { 5 | throw "Must be run as the SYSTEM user." 6 | } 7 | 8 | # Listing 12-11 9 | #$username = "GRAPHITE\user" 10 | $username = "BORON\tyranid" 11 | $console = Get-NtConsoleSession | Where-Object FullyQualifiedUserName -eq $username 12 | $token = Get-NtToken -Duplicate -TokenType Primary 13 | Enable-NtTokenPrivilege SeTcbPrivilege 14 | $token.SessionId = $console.SessionId 15 | $cmd = "cmd.exe" 16 | $proc = New-Win32Process $cmd -Token $token -Desktop "WinSta0\Default" -CreationFlags NewConsole 17 | $proc.Process.SessionId -eq $console.SessionId 18 | $proc.Dispose() 19 | $token.Close() -------------------------------------------------------------------------------- /chapter_12/listing_12_12.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 12-12 4 | $domain_sid = Get-NtSid "S-1-5-99" 5 | $group_sid = Get-NtSid -BaseSid $domain_sid -RelativeIdentifier 6 | $user_sid = Get-NtSid -BaseSid $domain_sid -RelativeIdentifier 7 | $domain = "CUSTOMDOMAIN" 8 | $group = "ALL USERS" 9 | $user = "USER" 10 | $token = Invoke-NtToken -System { 11 | Add-NtSidName -Domain $domain -Sid $domain_sid -Register 12 | Add-NtSidName -Domain $domain -Name $group -Sid $group_sid -Register 13 | Add-NtSidName -Domain $domain -Name $user -Sid $user_sid -Register 14 | Add-NtAccountRight -Sid $user_sid -LogonType SeInteractiveLogonRight 15 | Get-NtToken -Logon -Domain $domain -User $user -LogonProvider Virtual -LogonType Interactive 16 | Remove-NtAccountRight -Sid $user_sid -LogonType SeInteractiveLogonRight 17 | Remove-NtSidName -Sid $domain_sid -Unregister 18 | } 19 | Format-NtToken $token -User -Group 20 | $token.Close() -------------------------------------------------------------------------------- /chapter_12/listing_12_2.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 12-2 4 | Get-NtLogonSession | Sort-Object LogonId -------------------------------------------------------------------------------- /chapter_12/listing_12_4.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 12-4 4 | $password = Read-Host -AsSecureString -Prompt "Password" 5 | $token = Get-NtToken -Logon -User user -Domain $env:COMPUTERNAME -Password $password -LogonType Network 6 | Get-NtLogonSession -Token $token 7 | $token.Close() -------------------------------------------------------------------------------- /chapter_12/listing_12_9.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 12-9 4 | Get-NtToken -Logon -LogonType Service -Domain 'NT AUTHORITY' -User SYSTEM -WithTcb 5 | Get-NtToken -Service System -WithTcb -------------------------------------------------------------------------------- /chapter_13/chapter_13_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 13-1 2 | $credout = New-LsaCredentialHandle -Package "NTLM" -UseFlag Outbound -UserName $env:USERNAME -Domain $env:USERDOMAIN 3 | $client = New-LsaClientContext -CredHandle $credout 4 | $negToken = $client.Token 5 | Format-LsaAuthToken -Token $negToken 6 | 7 | # Listing 13-2 8 | Format-LsaAuthToken -Token $client.Token -AsBytes 9 | 10 | # Listing 13-3 11 | $credin = New-LsaCredentialHandle -Package "NTLM" -UseFlag Inbound 12 | $server = New-LsaServerContext -CredHandle $credin 13 | Update-LsaServerContext -Server $server -Token $client.Token 14 | $challengeToken = $server.Token 15 | Format-LsaAuthToken -Token $server.Token 16 | 17 | # Listing 13-4 18 | Update-LsaClientContext -Client $client -Token $server.Token 19 | $authToken = $client.Token 20 | Format-LsaAuthToken -Token $client.Token 21 | 22 | # Listing 13-5 23 | Update-LsaServerContext -Server $server -Token $client.Token 24 | if ((Test-LsaContext $client) -and (Test-LsaContext $server)) { 25 | Use-NtObject($token = Get-LsaAccessToken $server) { 26 | Get-NtLogonSession -Token $token 27 | } 28 | } 29 | 30 | # Listing 13-6 31 | function Get-Md5Hmac { 32 | Param( 33 | $Key, 34 | $Data 35 | ) 36 | $algo = [System.Security.Cryptography.HMACMD5]::new($Key) 37 | if ($Data -is [string]) { 38 | $Data = [System.Text.Encoding]::Unicode.GetBytes($Data) 39 | } 40 | $algo.ComputeHash($Data) 41 | } 42 | 43 | # Listing 13-7 44 | function Get-NtOwfv2 { 45 | Param( 46 | $Password, 47 | $UserName, 48 | $Domain 49 | ) 50 | $key = Get-MD4Hash -String $Password 51 | Get-Md5Hmac -Key $key -Data ($UserName.ToUpperInvariant() + $Domain) 52 | } 53 | 54 | $key = Get-NtOwfv2 -Password "pwd" -UserName $authToken.UserName -Domain $authToken.Domain 55 | $key | Out-HexDump 56 | 57 | # Listing 13-8 58 | function Get-NtProofStr { 59 | Param( 60 | $Key, 61 | $ChallengeToken, 62 | $AuthToken 63 | ) 64 | $data = $ChallengeToken.ServerChallenge 65 | $last_index = $AuthToken.NtChallengeResponse.Length - 1 66 | $data += $AuthToken.NtChallengeResponse[16..$last_index] 67 | Get-Md5Hmac -Key $Key -Data $data 68 | } 69 | 70 | $proof = Get-NtProofStr -Key $key -ChallengeToken $ChallengeToken -AuthToken $AuthToken 71 | $proof | Out-HexDump 72 | 73 | # Listing 13-9 74 | function Get-Mic { 75 | Param( 76 | $Key, 77 | $Proof, 78 | $NegToken, 79 | $ChallengeToken, 80 | $AuthToken 81 | ) 82 | $session_key = Get-Md5Hmac -Key $Key -Data $Proof 83 | $auth_data = $AuthToken.ToArray() 84 | [array]::Clear($auth_data, $AuthToken.MessageIntegrityCodeOffset, 16) 85 | $data = $NegToken.ToArray() + $ChallengeToken.ToArray() + $auth_data 86 | Get-Md5Hmac -Key $session_key -Data $data 87 | } 88 | $mic = Get-Mic -Key $key -Proof $proof -NegToken $NegToken -ChallengeToken $ChallengeToken -AuthToken $AuthToken 89 | $mic | Out-HexDump 90 | 91 | # Listing 13-10 92 | $credout = New-LsaCredentialHandle -Package "NTLM" -UseFlag Outbound 93 | $client = New-LsaClientContext -CredHandle $credout 94 | Format-LsaAuthToken $client 95 | 96 | $credin = New-LsaCredentialHandle -Package "NTLM" -UseFlag Inbound 97 | $server = New-LsaServerContext -CredHandle $credin 98 | Update-LsaServerContext -Server $server -Client $client 99 | Format-LsaAuthToken $server 100 | 101 | Update-LsaClientContext -Client $client -Server $server 102 | Format-LsaAuthToken $client 103 | 104 | Update-LsaServerContext -Server $server -Client $client 105 | if ((Test-LsaContext $client) -and (Test-LsaContext $server)) { 106 | Use-NtObject($token = Get-LsaAccessToken $server) { 107 | Get-NtLogonSession -Token $token 108 | } 109 | } 110 | Get-NtTokenId -Authentication 111 | 112 | # Listing 13-11 113 | $cout = New-LsaCredentialHandle -Package NTLM -UseFlag Outbound -ReadCredential 114 | 115 | # Listing 13-13 116 | $password = Read-Host -AsSecureString -Prompt "Password" 117 | $new_token = Get-NtToken -Logon -LogonType NewCredentials -User "Administrator" -Domain "GRAPHITE" -SecurePassword $password 118 | $credout = Invoke-NtToken $new_token { 119 | New-LsaCredentialHandle -Package "NTLM" -UseFlag Outbound 120 | } 121 | 122 | # Listing 13-14 123 | $client = New-LsaClientContext -CredHandle $credout -RequestAttribute Integrity 124 | 125 | # Listing 13-15 126 | function Get-Mic { 127 | Param( 128 | $Key, 129 | $Proof, 130 | $NegToken, 131 | $ChallengeToken, 132 | $AuthToken 133 | ) 134 | $session_key = Get-Md5Hmac -Key $Key -Data $Proof 135 | if ($authToken.EncryptedSessionKey.Count -gt 0) { 136 | $session_key = Unprotect-RC4 -Key $session_key -Data $AuthToken.EncryptedSessionKey 137 | } 138 | $auth_data = $AuthToken.ToArray() 139 | [array]::Clear($auth_data, $AuthToken.MessageIntegrityCodeOffset, 16) 140 | $data = $NegToken.ToArray() + $ChallengeToken.ToArray() + $auth_data 141 | Get-Md5Hmac -Key $session_key -Data $data 142 | } 143 | 144 | # Listing 13-16 145 | $server = New-LsaServerContext -CredHandle $credin 146 | Update-LsaServerContext $server $client 147 | Update-LsaClientContext $client $server 148 | Update-LsaServerContext $server $client 149 | $msg = $(0, 1, 2, 3) 150 | $sig = Get-LsaContextSignature -Context $client -Message $msg 151 | $sig | Out-HexDump 152 | Test-LsaContextSignature -Context $server -Message $msg -Signature $sig 153 | Test-LsaContextSignature -Context $server -Message $msg -Signature $sig 154 | 155 | # Listing 13-17 156 | $server.SessionKey | Out-HexDump 157 | $client.SessionKey | Out-HexDump 158 | 159 | # Listing 13-18 160 | function Get-BindingHash { 161 | Param( 162 | [byte[]]$ChannelBinding 163 | ) 164 | $stm = [System.IO.MemoryStream]::new() 165 | $writer = [System.IO.BinaryWriter]::new($stm) 166 | $writer.Write(0) # dwInitiatorAddrType 167 | $writer.Write(0) # cbInitiatorLength 168 | $writer.Write(0) # dwAcceptorAddrType 169 | $writer.Write(0) # cbAcceptorLength 170 | $writer.Write($ChannelBinding.Count) # cbApplicationDataLength 171 | $writer.Write($ChannelBinding) # Application Data 172 | [System.Security.Cryptography.MD5Cng]::new().ComputeHash($stm.ToArray()) 173 | } 174 | Get-BindingHash -ChannelBinding @(1, 2, 3) | Out-HexDump -------------------------------------------------------------------------------- /chapter_13/listing_13_12.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 13-12 4 | $credout = Invoke-NtToken -System { 5 | New-LsaCredentialHandle -Package "NTLM" -UseFlag Outbound 6 | } 7 | -------------------------------------------------------------------------------- /chapter_13/network_protocol_client.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [ipaddress]$Address = [ipaddress]::Loopback, 3 | [int]$Port = 6543 4 | ) 5 | 6 | Import-Module "$PSScriptRoot\network_protocol_common.psm1" 7 | 8 | $socket = $null 9 | $context = $null 10 | $credout = $null 11 | 12 | try { 13 | $socket = [System.Net.Sockets.TcpClient]::new() 14 | $socket.Connect($Address, $port) 15 | $client = Get-SocketClient -Socket $socket 16 | Write-Host "Connected to server $($socket.Client.RemoteEndPoint)" 17 | 18 | $credout = New-LsaCredentialHandle -Package "NTLM" -UseFlag Outbound 19 | $context = New-LsaClientContext -CredHandle $credout -RequestAttribute Confidentiality -Target "BOOK/$Address" 20 | Send-Message -Client $client -Message $context.Token.ToArray() 21 | $chal_token = Receive-Message -Client $client 22 | Update-LsaClientContext -Client $context -Token $chal_token 23 | Send-Message -Client $client -Message $context.Token.ToArray() 24 | 25 | if (!(Test-LsaContext -Context $context)) { 26 | throw "Authentication didn't complete as expected." 27 | } 28 | 29 | $ok_msg = Receive-TextMessage -Client $client -Context $context 30 | if ($ok_msg -ne "OK") { 31 | throw "Failed to authenticate." 32 | } 33 | 34 | $msg = Read-Host -Prompt "MSG" 35 | while($msg -ne "") { 36 | Send-TextMessage -Client $client -Context $context -Message $msg 37 | $recv_msg = Receive-TextMessage -Client $client -Context $context 38 | Write-Host "> $recv_msg" 39 | $msg = Read-Host -Prompt "MSG" 40 | } 41 | 42 | } catch { 43 | Write-Error $_ 44 | } finally { 45 | if ($null -ne $socket) { 46 | $socket.Close() 47 | } 48 | if ($null -ne $context) { 49 | $context.Dispose() 50 | } 51 | if ($null -ne $credout) { 52 | $credout.Dispose() 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /chapter_13/network_protocol_common.psm1: -------------------------------------------------------------------------------- 1 | function Get-SocketClient { 2 | param( 3 | [Parameter(Mandatory)] 4 | $Socket 5 | ) 6 | 7 | #$Socket.ReceiveTimeout = 10000 8 | $Socket.Client.NoDelay = $true 9 | $stream = $Socket.GetStream() 10 | $reader = [System.IO.StreamReader]::new($stream) 11 | $writer = [System.IO.StreamWriter]::new($stream) 12 | $writer.AutoFlush = $true 13 | return @{ 14 | Reader = $reader 15 | Writer = $writer 16 | } 17 | } 18 | 19 | function Send-Message { 20 | param( 21 | [Parameter(Mandatory)] 22 | $Client, 23 | [Parameter(Mandatory)] 24 | $Message 25 | ) 26 | 27 | Write-Verbose "Sending Message" 28 | Format-HexDump -Byte $Message -ShowAll | Write-Verbose 29 | $text = [System.Convert]::ToBase64String($Message) 30 | $Client.Writer.WriteLine($text) 31 | } 32 | 33 | function Receive-Message { 34 | param( 35 | [Parameter(Mandatory)] 36 | $Client 37 | ) 38 | 39 | $text = $Client.Reader.ReadLine() 40 | $ba = [System.Convert]::FromBase64String($text) 41 | Write-Verbose "Received Message" 42 | Format-HexDump -Byte $ba -ShowAll | Write-Verbose 43 | 44 | Write-Output -NoEnumerate $ba 45 | } 46 | 47 | function Send-TextMessage { 48 | param( 49 | [Parameter(Mandatory)] 50 | $Client, 51 | [Parameter(Mandatory)] 52 | $Message, 53 | [Parameter(Mandatory)] 54 | $Context 55 | ) 56 | 57 | $bytes = [System.Text.Encoding]::UTF8.GetBytes($Message) 58 | $enc = Protect-LsaContextMessage -Context $Context -Message $bytes 59 | Send-Message -Client $Client -Message $enc.Message 60 | Send-Message -Client $Client -Message $enc.Signature 61 | } 62 | 63 | function Receive-TextMessage { 64 | param( 65 | [Parameter(Mandatory)] 66 | $Client, 67 | [Parameter(Mandatory)] 68 | $Context 69 | ) 70 | 71 | $msg = Receive-Message -Client $Client 72 | if ($msg.Length -eq 0) { 73 | return "" 74 | } 75 | 76 | $sig = Receive-Message -Client $Client 77 | if ($sig.Length -eq 0) { 78 | return "" 79 | } 80 | 81 | $dec = Unprotect-LsaContextMessage -Context $Context -Message $msg -Signature $sig 82 | [System.Text.Encoding]::UTF8.GetString($dec) 83 | } 84 | 85 | Export-ModuleMember -Function 'Get-SocketClient', 'Send-Message', 'Receive-Message', 'Send-TextMessage', 'Receive-TextMessage' -------------------------------------------------------------------------------- /chapter_13/network_protocol_server.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [switch]$Global, 3 | [int]$Port = 6543 4 | ) 5 | 6 | Import-Module "$PSScriptRoot\network_protocol_common.psm1" 7 | 8 | $socket = $null 9 | $listener = $null 10 | $context = $null 11 | $credin = $null 12 | 13 | try { 14 | $Address = if ($Global) { 15 | [ipaddress]::Any 16 | } else { 17 | [ipaddress]::Loopback 18 | } 19 | 20 | $listener = [System.Net.Sockets.TcpListener]::new($Address, $port) 21 | $listener.Start() 22 | $socket = $listener.AcceptTcpClient() 23 | $client = Get-SocketClient -Socket $socket 24 | 25 | Write-Host "Connection received from $($socket.Client.RemoteEndPoint)" 26 | 27 | $credin = New-LsaCredentialHandle -Package "NTLM" -UseFlag Inbound 28 | $context = New-LsaServerContext -CredHandle $credin -RequestAttribute Confidentiality 29 | 30 | $neg_token = Receive-Message -Client $client 31 | Update-LsaServerContext -Server $context -Token $neg_token 32 | Send-Message -Client $client -Message $context.Token.ToArray() 33 | $auth_token = Receive-Message -Client $client 34 | Update-LsaServerContext -Server $context -Token $auth_token 35 | 36 | if (!(Test-LsaContext -Context $context)) { 37 | throw "Authentication didn't complete as expected." 38 | } 39 | 40 | $target = "BOOK/$($socket.Client.LocalEndPoint.Address)" 41 | if ($context.ClientTargetName -ne $target) { 42 | throw "Incorrect target name specified: $($context.ClientTargetName)." 43 | } 44 | 45 | $user = Use-NtObject($token = Get-LsaAccessToken -Server $context) { 46 | $token.User 47 | } 48 | Write-Host "User $user has authenticated." 49 | Send-TextMessage -Client $client -Message "OK" -Context $context 50 | 51 | $msg = Receive-TextMessage -Client $client -Context $context 52 | while($msg -ne "") { 53 | Write-Host "> $msg" 54 | $reply = "User {0} said: {1}" -f $user, $msg.ToUpper() 55 | Send-TextMessage -Client $client -Message $reply -Context $context 56 | $msg = Receive-TextMessage -Client $client -Context $context 57 | } 58 | } catch { 59 | Write-Error $_ 60 | } finally { 61 | if ($null -ne $socket) { 62 | $socket.Close() 63 | } 64 | if ($null -ne $listener) { 65 | $listener.Stop() 66 | } 67 | if ($null -ne $context) { 68 | $context.Dispose() 69 | } 70 | if ($null -ne $credin) { 71 | $credin.Dispose() 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /chapter_14/chapter_14_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 14-1 2 | Get-ADComputer -Identity $env:COMPUTERNAME -Properties ServicePrincipalNames | Select-Object -ExpandProperty ServicePrincipalNames 3 | 4 | # Listing 14-2 5 | $credout = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Outbound 6 | $spn = "HOST/$env:COMPUTERNAME" 7 | $client = New-LsaClientContext -CredHandle $credout -Target $spn 8 | Format-LsaAuthToken -Token $client.Token 9 | 10 | # Listing 14-3 11 | $credin = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Inbound 12 | $server = New-LsaServerContext -CredHandle $credin 13 | Update-LsaServerContext -Server $server -Token $client.Token 14 | 15 | # Listing 14-4 16 | $credout = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Outbound 17 | $spn = "RestrictedKrbHost/$env:COMPUTERNAME" 18 | $client = New-LsaClientContext -CredHandle $credout -Target $spn 19 | Format-LsaAuthToken -Token $client.Token 20 | $credin = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Inbound 21 | $server = New-LsaServerContext -CredHandle $credin 22 | Update-LsaServerContext -Server $server -Token $client.Token 23 | Use-NtObject($token = Get-LsaAccessToken $server) { 24 | Get-NtLogonSession $token | Format-Table 25 | } 26 | 27 | # Listing 14-5 28 | $client = New-LsaClientContext -CredHandle $credout -Target "RestrictedKrbHost/$env:COMPUTERNAME" -RequestAttribute MutualAuth 29 | Format-LsaAuthToken -Token $client.Token 30 | $server = New-LsaServerContext -CredHandle $credin 31 | Update-LsaServerContext -Server $server -Token $client.Token 32 | $ap_rep = $server.Token 33 | $ap_rep | Format-LsaAuthToken 34 | 35 | # Listing 14-6 36 | $credout = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Outbound 37 | $client = New-LsaClientContext -CredHandle $credout -Target "HTTP/graphite" 38 | Format-LsaAuthToken -Token $client.Token 39 | 40 | # Listing 14-7 41 | $key = Get-KerberosKey -Password "AlicePassw0rd" -KeyType ARCFOUR_HMAC_MD5 -NameType SRV_INST -Principal "HTTP/graphite@mineral.local" 42 | $key.Key | Out-HexDump 43 | 44 | # Listing 14-8 45 | $ap_req = Unprotect-LsaAuthToken -Token $client.Token -Key $key 46 | $ap_req | Format-LsaAuthToken 47 | 48 | # Listing 14-16 49 | $sesskey = (Unprotect-LsaAuthToken -Token $ap_req -Key $key).Ticket.Key 50 | Unprotect-LsaAuthToken -Token $ap_rep -Key $sesskey | Format-LsaAuthToken 51 | 52 | # Listing 14-17 53 | Set-ADAccountControl -Identity alice -TrustedForDelegation $true 54 | Get-ADUser -Identity alice -Properties TrustedForDelegation | Select-Object TrustedForDelegation 55 | 56 | # Listing 14-18 57 | $credout = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Outbound 58 | $client = New-LsaClientContext -CredHandle $credout -Target "HTTP/graphite" -RequestAttribute MutualAuth, Delegate 59 | $key = Get-KerberosKey -Password "AlicePassw0rd" -KeyType ARCFOUR_HMAC_MD5 -NameType SRV_INST -Principal "HTTP/graphite@mineral.local" 60 | Unprotect-LsaAuthToken -Token $client.Token -Key $key | Format-LsaAuthToken 61 | 62 | # Listing 14-20 63 | $credin = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Inbound 64 | $server = New-LsaServerContext -CredHandle $credin 65 | Update-LsaServerContext -Server $server -Client $client 66 | Use-NtObject($token = Get-LsaAccessToken $server) { 67 | Format-NtToken $token -Information 68 | } 69 | 70 | # Listing 14-21 71 | $spns = @{'msDS-AllowedToDelegateTo'=@('CIFS/graphite')} 72 | Set-ADUser -Identity alice -Add $spns 73 | 74 | # Listing 14-22 75 | Get-ADUser -Identity alice -Properties 'msDS-AllowedToDelegateTo' | Select-Object -Property 'msDS-AllowedToDelegateTo' 76 | 77 | # Listing 14-23 78 | Set-ADAccountControl -Identity alice -TrustedToAuthForDelegation $true 79 | Get-ADUser -Identity alice -Properties TrustedToAuthForDelegation | Select-Object -Property TrustedToAuthForDelegation 80 | 81 | # Listing 14-24 82 | Show-NtTokenEffective 83 | $token = Get-NtToken -S4U -User bob -Domain MINERAL 84 | Format-NtToken $token 85 | Format-NtToken $token -Information 86 | 87 | # Listing 14-25 88 | Set-ADUser -Identity alice -PrincipalsAllowedToDelegateToAccount (Get-ADComputer GRAPHITE) 89 | Get-ADUser -Identity alice -Properties PrincipalsAllowedToDelegateToAccount | Select-Object PrincipalsAllowedToDelegateToAccount 90 | $name = "msDS-AllowedToActOnBehalfOfOtherIdentity" 91 | (Get-ADUser -Identity alice -Properties $name)[$name] | ConvertTo-NtSecurityDescriptor | Format-NtSecurityDescriptor -Summary 92 | 93 | # Listing 14-26 94 | Set-ADUser -Identity alice -AccountNotDelegated $true 95 | Get-ADUser -Identity alice -Properties AccountNotDelegated | Select-Object AccountNotDelegated 96 | $client = New-LsaClientContext -CredHandle $credout -Target "HTTP/graphite" 97 | Unprotect-LsaAuthToken -Token $client.Token -Key $key | Format-LsaAuthToken 98 | 99 | # Listing 14-27 100 | $credout = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Outbound 101 | $client = New-LsaClientContext -CredHandle $credout -Target bob@mineral.local 102 | Format-LsaAuthToken -Token $client.Token 103 | 104 | # Listing 14-28 105 | $credin = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Inbound -ReadCredential 106 | $server = New-LsaServerContext -CredHandle $credin 107 | Update-LsaServerContext -Server $server -Client $client 108 | Format-LsaAuthToken -Token $server.Token 109 | 110 | # Listing 14-29 111 | Update-LsaClientContext -Client $client -Server $server 112 | Format-LsaAuthToken -Token $client.Token 113 | 114 | # Listing 14-30 115 | Update-LsaServerContext -Server $server -Client $client 116 | Use-NtObject($token = Get-LsaAccessToken $server) { 117 | Get-NtLogonSession $token | Format-Table 118 | } 119 | 120 | # Listing 14-31 121 | Get-KerberosTicket | Select-Object ServiceName, EndTime 122 | Get-KerberosTicket | Select-Object -First 1 | Format-KerberosTicket 123 | 124 | # Listing 14-33 125 | Get-ADUser -Filter { 126 | ObjectClass -eq 'user' 127 | } -Properties ServicePrincipalName | Where-Object ServicePrincipalName -ne $null | Select SamAccountName, ServicePrincipalName 128 | 129 | # Listing 14-34 130 | $creds = New-LsaCredentialHandle -Package "Kerberos" -UseFlag Outbound 131 | $client = New-LsaClientContext -CredHandle $creds -Target "MSSQL/topaz.mineral.local" 132 | Format-LsaAuthToken $client 133 | 134 | # Listing 14-35 135 | $pwds = "ABC!!!!", "SQLRUS", "DBPassw0rd" 136 | foreach($pwd in $pwds) { 137 | $key = Get-KerberosKey -Password $pwd -KeyType ARCFOUR_HMAC_MD5 -NameType SRV_INST -Principal "MSSQL/topaz.mineral.local@mineral.local" 138 | $dec_token = Unprotect-LsaAuthToken -Key $key -Token $client.Token 139 | if ($dec_token.Ticket.Decrypted) { 140 | Write-Host "Decrypted ticket with password: $pwd" 141 | break 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /chapter_14/listing_14_32.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 14-32 4 | $sess = Get-NtLogonSession 5 | $tickets = Invoke-NtToken -System { Get-KerberosTicket -LogonSession $sess } 6 | $tickets | Select-Object ServiceName, { Format-HexDump $_.SessionKey.Key } -------------------------------------------------------------------------------- /chapter_15/chapter_15_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 15-1 2 | $in_buf = New-LsaSecurityBuffer -Type PkgParams -String "AuthParam" 3 | $out_buf = New-LsaSecurityBuffer -Type Data -Size 100 4 | Update-LsaClientContext -Client $client -Token $token -InputBuffer $in_buf -OutputBuffer $out_buf 5 | $out_buf.Type 6 | ConvertFrom-LsaSecurityBuffer $out_buf | Out-HexDump 7 | 8 | # Listing 15-2 9 | $header = New-LsaSecurityBuffer -Type Data -Byte @(0, 1, 3, 4) -ReadOnlyWithChecksum 10 | $data = New-LsaSecurityBuffer -Type Data -String "HELLO" 11 | $sig = Protect-LsaContextMessage -Context $client -Buffer $header, $data 12 | ConvertFrom-LsaSecurityBuffer -Buffer $header | Out-HexDump 13 | ConvertFrom-LsaSecurityBuffer -Buffer $data | Out-HexDump 14 | Unprotect-LsaContextMessage -Context $server -Buffer $header, $data -Signature $sig 15 | ConvertFrom-LsaSecurityBuffer -Buffer $data -AsString 16 | 17 | # Listing 15-3 18 | $credout = New-LsaCredentialHandle -Package "Negotiate" -UseFlag Outbound 19 | $client = New-LsaClientContext -CredHandle $credout 20 | Format-LsaAuthToken -Token $client.Token 21 | 22 | # Listing 15-4 23 | $credin = New-LsaCredentialHandle -Package "Negotiate" -UseFlag Inbound 24 | $server = New-LsaServerContext -CredHandle $credin 25 | Update-LsaServerContext -Server $server -Token $client.Token 26 | Format-LsaAuthToken -Token $server.Token 27 | 28 | # Listing 15-5 29 | Update-LsaClientContext -Client $client -Token $server.Token 30 | Format-LsaAuthToken -Token $client.Token 31 | Update-LsaServerContext -Server $server -Token $client.Token 32 | Format-LsaAuthToken -Token $server.Token 33 | Update-LsaClientContext -Client $client -Token $server.Token 34 | $client.PackageName 35 | 36 | # Listing 15-6 37 | $credout = New-LsaCredentialHandle -Package "Schannel" -UseFlag Outbound 38 | $name = "NotReallyReal.com" 39 | $client = New-LsaClientContext -CredHandle $credout -Target $name -RequestAttribute ManualCredValidation 40 | Format-LsaAuthToken -Token $client.Token 41 | 42 | # Listing 15-7 43 | $store = "Cert:\CurrentUser\My" 44 | $cert = Get-ChildItem $store | Where-Object Subject -Match $name 45 | if ($null -eq $cert) { 46 | $cert = New-SelfSignedCertificate -DnsName $name -CertStoreLocation $store 47 | } 48 | $server_cred = Get-LsaSchannelCredential -Certificate $cert 49 | $credin = New-LsaCredentialHandle -Package "Schannel" -UseFlag Inbound -Credential $server_cred 50 | $server = New-LsaServerContext -CredHandle $credin 51 | while(!(Test-LsaContext $client) -and !(Test-LsaContext $server)) { 52 | Update-LsaServerContext -Server $server -Client $client 53 | Update-LsaClientContext -Client $client -Server $server 54 | } 55 | 56 | # Listing 15-8 57 | $client.ConnectionInfo 58 | $client.RemoteCertificate 59 | $server.ConnectionInfo 60 | 61 | # Listing 15-9 62 | $header = New-LsaSecurityBuffer -Type StreamHeader -Size $client.StreamHeaderSize 63 | $data = New-LsaSecurityBuffer -Type Data -Byte 0, 1, 2, 3 64 | $trailer = New-LsaSecurityBuffer -Type StreamTrailer -Size $client.StreamTrailerSize 65 | $empty = New-LsaSecurityBuffer -Empty 66 | $bufs = $header, $data, $trailer, $empty 67 | Protect-LsaContextMessage -Context $client -Buffer $bufs -NoSignature 68 | $msg = $header, $data, $trailer | ConvertFrom-LsaSecurityBuffer 69 | $msg_token = Get-LsaAuthToken -Context $client -Token $msg 70 | Format-LsaAuthToken $msg_token 71 | $header = New-LsaSecurityBuffer -Type Data -Byte $msg 72 | $data = New-LsaSecurityBuffer -Empty 73 | $trailer = New-LsaSecurityBuffer -Empty 74 | $empty = New-LsaSecurityBuffer -Empty 75 | $bufs = $header, $data, $trailer, $empty 76 | Unprotect-LsaContextMessage -Context $server -Buffer $bufs -NoSignature 77 | ConvertFrom-LsaSecurityBuffer $data | Out-HexDump 78 | 79 | # Listing 15-10 80 | Get-Win32Credential "TERMSRV/primarydc.domain.local" DomainPassword | Format-Table UserName, Password 81 | 82 | # Listing 15-11 83 | ls "$env:LOCALAPPDATA\Microsoft\Credentials" -Hidden 84 | 85 | # Listing 15-12 86 | Add-Type -AssemblyName "System.Security" 87 | ls "$env:LOCALAPPDATA\Microsoft\Credentials" -h | ForEach-Object { 88 | $ba = Get-Content -Path $_.FullName -Encoding Byte 89 | [Security.Cryptography.ProtectedData]::Unprotect($ba,$null,"CurrentUser") 90 | } 91 | 92 | # Listing 15-14 93 | $client = New-LsaClientContext -CredHandle $credout -RequestAttribute NullSession 94 | 95 | # Listing 15-20 96 | $cred = New-LsaCredentialHandle -Package "Negotiate" -UseFlag Outbound 97 | $sid = Get-NtSid -PackageName "network_auth_test" 98 | Use-NtObject($token = Get-NtToken -LowBox -PackageSid $sid) { 99 | Invoke-NtToken $token { New-LsaClientContext -CredHandle $cred } 100 | } 101 | 102 | $cap = Get-NtSid -KnownSid CapabilityEnterpriseAuthentication 103 | Use-NtObject($token = Get-NtToken -LowBox -PackageSid $sid -CapabilitySid $cap) { 104 | $auth = Invoke-NtToken $token { New-LsaClientContext -CredHandle $cred } 105 | Format-LsaAuthToken $auth 106 | } 107 | 108 | # Listing 15-21 109 | $cred = New-LsaCredentialHandle -Package "NTLM" -UseFlag Outbound 110 | $client = New-Object System.Net.WebClient 111 | $proxy = $client.Proxy.GetProxy("http://www.microsoft.com").Authority 112 | $target = "HTTP/$proxy" 113 | $target | Write-Output 114 | $sid = Get-NtSid -PackageName "network_auth_test" 115 | Use-NtObject($token = Get-NtToken -LowBox -PackageSid $sid) { 116 | $client = Invoke-NtToken $token { 117 | New-LsaClientContext -CredHandle $cred -Target $target 118 | } 119 | Format-LsaAuthToken $client 120 | } 121 | 122 | # Listing 15-22 123 | $cred = New-LsaCredentialHandle -Package "Negotiate" -UseFlag Outbound -ReadCredential 124 | $sid = Get-NtSid -PackageName "network_auth_test" 125 | Use-NtObject($token = Get-NtToken -LowBox -PackageSid $sid) { 126 | Invoke-NtToken $token { 127 | $c = New-LsaClientContext -CredHandle $cred -Target "CIFS/localhost" 128 | Format-LsaAuthToken $c 129 | } 130 | } 131 | 132 | # Listing 15-31 133 | $cert = .\get_server_cert.ps1 -Hostname www.microsoft.com 134 | $cert 135 | $cert | Export-Certificate -FilePath output.cer -------------------------------------------------------------------------------- /chapter_15/get_server_cert.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory, Position = 0)] 3 | [string]$Hostname, 4 | [int]$Port = 443 5 | ) 6 | 7 | Import-Module NtObjectManager 8 | $ErrorActionPreference = "Stop" 9 | 10 | function Get-SocketClient { 11 | param( 12 | [Parameter(Mandatory)] 13 | $Socket 14 | ) 15 | 16 | $Socket.ReceiveTimeout = 1000 17 | $Socket.Client.NoDelay = $true 18 | $stream = $Socket.GetStream() 19 | return @{ 20 | Reader = [System.IO.BinaryReader]::new($stream) 21 | Writer = [System.IO.BinaryWriter]::new($stream) 22 | } 23 | } 24 | 25 | function Read-TlsRecordToken { 26 | param( 27 | [Parameter(Mandatory)] 28 | $Client 29 | ) 30 | $reader = $Client.Reader 31 | $header = $reader.ReadBytes(5) 32 | $length = ([int]$header[3] -shl 8) -bor ($header[4]) 33 | $data = @() 34 | while($length -gt 0) { 35 | $next = $reader.ReadBytes($length) 36 | if ($next.Length -eq 0) { 37 | throw "End of stream." 38 | } 39 | $data += $next 40 | $length -= $next.Length 41 | } 42 | 43 | Get-LsaAuthToken -Token ($header+$data) 44 | } 45 | 46 | Use-NtObject($socket = [System.Net.Sockets.TcpClient]::new($Hostname, 443)) { 47 | $tcp_client = Get-SocketClient $socket 48 | 49 | $credout = New-LsaCredentialHandle -Package "SChannel" -UseFlag Outbound 50 | $client = New-LsaClientContext -CredHandle $credout -Target $Hostname -RequestAttribute ManualCredValidation 51 | 52 | while(!(Test-LsaContext -Context $client)) { 53 | if ($client.Token.Length -gt 0) { 54 | $tcp_client.Writer.Write($client.Token.ToArray()) 55 | } 56 | 57 | $record = Read-TlsRecordToken -Client $tcp_client 58 | Update-LsaClientContext -Client $client -Token $record 59 | } 60 | 61 | $client.RemoteCertificate 62 | } -------------------------------------------------------------------------------- /chapter_15/listing_15_13.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 15-13 4 | Enable-NtTokenPrivilege SeDebugPrivilege 5 | $token = Use-NtObject($ps = Get-NtProcess -Name "winlogon.exe" -Access QueryLimitedInformation) { 6 | $p = $ps | Select-Object -First 1 7 | Get-NtToken -Process $p -Duplicate 8 | } 9 | $user_token = Get-NtToken 10 | $ba = Invoke-NtToken -Token $token 11 | Enable-NtTokenPrivilege SeTrustedCredmanAccessPrivilege 12 | Backup-Win32Credential -Token $user_token 13 | } 14 | Select-BinaryString -Byte $ba -Type Unicode | 15 | Select-String "^Domain:" -Context 0, 2 -------------------------------------------------------------------------------- /chapter_15/listing_15_23_to_15_26.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 15-23 4 | Get-WinEvent -FilterHashtable @{logname='Security';id=@(4624)} | 5 | Select-Object -ExpandProperty Message 6 | 7 | # Listing 15-25 8 | Get-WinEvent -FilterHashtable @{logname='Security';id=@(4625)} | 9 | Select-Object -ExpandProperty Message 10 | 11 | # Listing 15-26 12 | Get-WinEvent -FilterHashtable @{logname='Security';id=@(4634)} | 13 | Select-Object -ExpandProperty Message -------------------------------------------------------------------------------- /chapter_15/listing_15_27_to_15_29.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 15-27 4 | $record = Get-WinEvent -FilterHashtable @{logname='Security';id=@(4634)} | Select -First 1 5 | $record.Properties 6 | 7 | # Listing 15-28 8 | function Get-EventLogProperty { 9 | [CmdletBinding()] 10 | param( 11 | [parameter(Mandatory, Position = 0, ValueFromPipeLine)] 12 | [System.Diagnostics.Eventing.Reader.EventRecord]$Record 13 | ) 14 | PROCESS { 15 | $xml = [xml]$Record.ToXml() 16 | $ht = @{ 17 | TimeCreated = $Record.TimeCreated 18 | Id = $Record.Id 19 | } 20 | foreach($ent in $xml.Event.EventData.data) { 21 | $ht.Add($ent.Name, $ent."#text") 22 | } 23 | [PSCustomObject]$ht 24 | } 25 | } 26 | Get-EventLogProperty $record 27 | 28 | # Listing 15-29 29 | function Get-AuthFailureStatus { 30 | [CmdletBinding()] 31 | param( 32 | [parameter(Mandatory, Position = 0, ValueFromPipeLine)] 33 | $Record 34 | ) 35 | PROCESS { 36 | [PSCustomObject]@{ 37 | TimeCreated = $Record.TimeCreated 38 | UserName = $Record.TargetUserName 39 | DomainName = $Record.TargetDomainName 40 | SubStatus = (Get-NtStatus -Status $Record.SubStatus).StatusName 41 | } 42 | } 43 | } 44 | Get-NtToken -Logon -User $env:USERNAME -Domain $env:USERDOMAIN -Password "InvalidPassword" 45 | Get-NtToken -Logon -User "NotARealUser" -Domain $env:USERDOMAIN -Password "pwd" 46 | Get-WinEvent -FilterHashtable @{logname='Security';id=@(4625)} | 47 | Select-Object -First 2 | Get-EventLogProperty | Get-AuthFailureStatus -------------------------------------------------------------------------------- /chapter_2/chapter_2_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 2-1 2 | Get-NtSid -Name "Users" 3 | 4 | # Listing 2-2 5 | Get-NtSid -Sddl "S-1-5-32-545" 6 | 7 | # Listing 2-3 8 | Get-NtType 9 | 10 | # Listing 2-4 11 | ls NtObject:\ | Sort-Object Name 12 | 13 | # Listing 2-5 14 | ls NtObject:\Dfs | Select-Object SymbolicLinkTarget 15 | Get-Item NtObject:\Device\DfsClient | Format-Table 16 | 17 | # Listing 2-10 18 | Get-NtDirectory \THISDOESNOTEXIST 19 | Get-NtStatus 0xC0000034 | Format-List 20 | 21 | # Listing 2-11 22 | Get-NtType | Select-Object Name, GenericMapping 23 | 24 | # Listing 2-12 25 | Get-NtTypeAccess -Type File 26 | 27 | # Listing 2-13 28 | Get-NtAccessMask -FileAccess ReadData, ReadAttributes, ReadControl 29 | Get-NtAccessMask -FileAccess GenericRead 30 | Get-NtAccessMask -FileAccess GenericRead -MapGenericRights 31 | Get-NtAccessMask 0x120089 -AsTypeAccess File 32 | 33 | # Listing 2-14 34 | $mut = New-NtMutant 35 | $mut.GrantedAccess 36 | $mut.GrantedAccessMask 37 | $mut.Close() 38 | 39 | # Listing 2-15 40 | Get-NtHandle -ProcessId $pid 41 | 42 | # Listing 2-16 43 | $m = New-NtMutant \BaseNamedObjects\ABC 44 | $m.IsClosed 45 | $m.Close() 46 | $m.IsClosed 47 | 48 | Use-NtObject($m = New-NtMutant \BaseNamedObjects\ABC) { 49 | $m.FullPath 50 | } 51 | $m.IsClosed 52 | 53 | # Listing 2-17 54 | $mut = New-NtMutant "\BaseNamedObjects\ABC" 55 | $mut.GrantedAccess 56 | Use-NtObject($dup = Copy-NtObject $mut) { 57 | $mut 58 | $dup 59 | Compare-NtObject $mut $dup 60 | } 61 | 62 | $mask = Get-NtAccessMask -MutantAccess ModifyState 63 | Use-NtObject($dup = Copy-NtObject $mut -DesiredAccessMask $mask) { 64 | $dup.GrantedAccess 65 | Compare-NtObject $mut $dup 66 | } 67 | 68 | $mut.Close() 69 | 70 | # Listing 2-18 71 | $mut = New-NtMutant 72 | $mut.ProtectFromClose = $true 73 | Close-NtObject -SafeHandle $mut.Handle -CurrentProcess 74 | $mut.ProtectFromClose = $false 75 | $mut.Close() 76 | 77 | # Listing 2-21 78 | Get-NtObjectInformationClass Process 79 | 80 | # Listing 2-22 and Listing 2-23 81 | $proc = Get-NtProcess -Current 82 | Get-NtObjectInformation $proc ProcessTimes 83 | Get-NtObjectInformation $proc ProcessTimes -Length 32 84 | Get-NtObjectInformation $proc ProcessTimes -AsObject 85 | $proc | Format-List 86 | $proc.CreationTime 87 | 88 | # Listing 2-24 89 | Get-NtObjectInformationClass Key 90 | Get-NtObjectInformationClass Key -Set 91 | 92 | # Listing 2-25 93 | ls NtObject:\Device 94 | 95 | # Listing 2-26 96 | Use-NtObject($f = Get-NtFile "\SystemRoot\notepad.exe") { 97 | $f | Select-Object FullPath, NtTypeName 98 | } 99 | 100 | Get-Item NtObject:\Device\HarddiskVolume3 101 | 102 | # Listing 2-27 103 | Get-NtKernelModule 104 | 105 | # Listing 2-28 106 | Get-NtProcess -InfoOnly 107 | Get-NtThread -InfoOnly 108 | 109 | # Listing 2-29 110 | $proc = Get-NtProcess -ProcessId $pid 111 | $proc.CommandLine 112 | $proc.Win32ImagePath 113 | $proc.Close() 114 | 115 | # Listing 2-30 116 | Get-NtVirtualMemory 117 | $addr = Add-NtVirtualMemory -Size 1000 -Protection ReadWrite 118 | Get-NtVirtualMemory -Address $addr 119 | Read-NtVirtualMemory -Address $addr -Size 4 | Out-HexDump 120 | Write-NtVirtualMemory -Address $addr -Data @(1,2,3,4) 121 | Read-NtVirtualMemory -Address $addr -Size 4 | Out-HexDump 122 | Set-NtVirtualMemory -Address $addr -Protection ExecuteRead -Size 4 123 | Get-NtVirtualMemory -Address $addr 124 | Remove-NtVirtualMemory -Address $addr 125 | Get-NtVirtualMemory -Address $addr 126 | 127 | # Listing 2-31 128 | $s = New-NtSection -Size 4096 -Protection ReadWrite 129 | $m = Add-NtSection -Section $s -Protection ReadWrite 130 | Get-NtVirtualMemory $m.BaseAddress 131 | Remove-NtSection -Mapping $m 132 | Get-NtVirtualMemory -Address 0x1C3DD0E0000 133 | Add-NtSection -Section $s -Protection ExecuteRead 134 | $s.Close() 135 | 136 | # Listing 2-32 137 | Get-NtVirtualMemory -Type Mapped | Where-Object Name -ne "" 138 | 139 | # Listing 2-33 140 | $sect = New-NtSectionImage -Win32Path "$env:WinDir\system32\notepad.exe" 141 | $map = Add-NtSection -Section $sect -Protection ReadOnly 142 | Get-NtVirtualMemory -Address $map.BaseAddress 143 | Get-NtVirtualMemory -Type Image -Name "notepad.exe" 144 | Out-HexDump -Buffer $map -ShowAscii -Length 128 145 | Remove-NtSection -Mapping $map 146 | $sect.Close() 147 | 148 | # Listing 2-34 149 | Get-AuthenticodeSignature "$env:WinDir\system32\notepad.exe" | Format-List 150 | 151 | # Listing 2-35 152 | ls NtObject:\REGISTRY 153 | 154 | # Listing 2-36 155 | $key = Get-NtKey \Registry\Machine\SOFTWARE\Microsoft\.NETFramework 156 | Get-NtKeyValue -Key $key 157 | $key.Close() 158 | 159 | # Listing 2-37 160 | $hs = Get-NtHandle -ObjectType File | Where-Object Name -Match Windows 161 | $hs | Select-Object ProcessId, Handle, Name 162 | 163 | # Listing 2-38 164 | $ss = Get-NtHandle -ObjectType Section -GroupByAddress | Where-Object ShareCount -eq 2 165 | $mask = Get-NtAccessMask -SectionAccess MapWrite 166 | $ss = $ss | Where-Object { Test-NtAccessMask $_.AccessIntersection $mask } 167 | foreach($s in $ss) { 168 | $count = ($s.ProcessIds | Where-Object { 169 | Test-NtProcess -ProcessId $_ -Access DupHandle 170 | }).Count 171 | if ($count -eq 1) { 172 | $s.Handles | Select ProcessId, ProcessName, Handle 173 | } 174 | } 175 | 176 | # Listing 2-39 177 | $handle = $null # Replace with a valid section object from NtObject:\. 178 | $sect = $handle.GetObject() 179 | $map = Add-NtSection -Section $sect -Protection ReadWrite 180 | $random = Get-RandomByte -Size $map.Length 181 | Write-NtVirtualMemory -Mapping $map -Data $random 182 | Out-HexDump -Buffer $map -Length 16 -ShowAddress -ShowHeader 183 | 184 | # Listing 2-40 185 | $proc = Get-NtProcess -ProcessId $pid -Access QueryLimitedInformation 186 | Get-NtVirtualMemory -Process $proc | Where-Object { 187 | $_.Protect -band "ExecuteReadWrite" 188 | } 189 | $proc.Close() -------------------------------------------------------------------------------- /chapter_3/chapter_3_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 3-1 2 | $lib = Import-Win32Module -Path "kernel32.dll" 3 | $lib 4 | Get-Win32ModuleExport -Module $lib 5 | "{0:X}" -f (Get-Win32ModuleExport -Module $lib -ProcAddress "AllocConsole") 6 | 7 | # Listing 3-2 8 | Get-Win32ModuleImport -Path "kernel32.dll" 9 | Get-Win32ModuleImport -Path "kernel32.dll" -DllName "ntdll.dll" | Where-Object Name -Match "^Nt" 10 | 11 | # Listing 3-3 12 | ls NtObject:\KnownDlls 13 | 14 | # Listing 3-4 15 | Get-NtType WindowStation,Desktop 16 | 17 | # Listing 3-5 18 | Get-NtWindowStationName 19 | Get-NtWindowStationName -Current 20 | Get-NtDesktopName 21 | Get-NtDesktopName -Current 22 | 23 | # Listing 3-6 24 | $desktop = Get-NtDesktop -Current 25 | Get-NtWindow -Desktop $desktop 26 | 27 | # Listing 3-7 28 | $ws = Get-NtWindow 29 | $char_count = 2048 30 | $buf = New-Win32MemoryBuffer -Length ($char_count*2) 31 | foreach($w in $ws) { 32 | $len = Send-NtWindowMessage -Window $w -Message 0xD -LParam $buf.DangerousGetHandle() -WParam $char_count -Wait 33 | $txt = $buf.ReadUnicodeString($len.ToInt32()) 34 | if ($txt.Length -eq 0) { 35 | continue 36 | } 37 | "PID: $($w.ProcessId) - $txt" 38 | } 39 | $buf.Dispose() 40 | 41 | # Listing 3-8 42 | Get-NtProcess -InfoOnly | Group-Object SessionId 43 | 44 | # Listing 3-9 45 | ls NtObjectSession:\ | Group-Object TypeName 46 | 47 | # Listing 3-12 48 | Get-Win32Error 5 49 | 50 | # Listing 3-13 51 | $m = New-NtMutant ABC -Win32Path 52 | $m.FullPath 53 | $m.Close() 54 | 55 | # Listing 3-15 56 | Get-Win32ModuleExport "kernel32.dll" -ProcAddress CreateMutexEx 57 | 58 | # Listing 3-16 59 | Get-Win32ModuleExport "kernel32.dll" | Where-Object Name -Match CreateMutexEx 60 | 61 | # Listing 3-17 62 | Use-NtObject($key = Get-NtKey \REGISTRY\MACHINE\SOFTWARE) { 63 | $key.Win32Path 64 | } 65 | 66 | Use-NtObject($key = Get-NtKey -Win32Path "HKCU\SOFTWARE") { 67 | $key.FullPath 68 | } 69 | 70 | # Listing 3-18 71 | $key = New-NtKey -Win32Path "HKCU\ABC`0XYZ" 72 | Get-Item "NtKeyUser:\ABC`0XYZ" 73 | Get-Item "HKCU:\ABC`0XYZ" 74 | Remove-NtKey $key 75 | $key.Close() 76 | 77 | # Listing 3-19 78 | Use-NtObject($cdrive = Get-NtSymbolicLink "\??\C:") { 79 | $cdrive | Select-Object FullPath, Target 80 | } 81 | 82 | Add-DosDevice Z: C:\Windows 83 | Use-NtObject($zdrive = Get-NtSymbolicLink "\??\Z:") { 84 | $zdrive | Select-Object FullPath, Target 85 | } 86 | Remove-DosDevice Z: 87 | 88 | # Listing 3-20 89 | Set-Location $env:SystemRoot 90 | Get-NtFilePathType "." 91 | Get-NtFilePath "." 92 | Get-NtFilePath "..\" 93 | Get-NtFilePathType "C:ABC" 94 | Get-NtFilePath "C:ABC" 95 | Get-NtFilePathType "\\?\C:\abc/..\xyz" 96 | Get-NtFilePath "\\?\C:\abc/..\xyz" 97 | 98 | # Listing 3-21 99 | $path = "C:\$('A'*256)" 100 | $path.Length 101 | Get-NtFilePath -Path $path 102 | $path += "A" 103 | $path.Length 104 | Get-NtFilePath -Path $path 105 | $path = "\\?\" + $path 106 | $path.Length 107 | Get-NtFilePath -Path $path 108 | 109 | # Listing 3-22 110 | $path = "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" 111 | Get-NtKeyValue -Win32Path $path -Name "LongPathsEnabled" 112 | (Get-Process -Id $pid).Path | Get-Win32ModuleManifest | Select-Object LongPathAware 113 | $path = "C:\$('A'*300)" 114 | $path.Length 115 | Get-NtFilePath -Path $path 116 | 117 | # Listing 3-23 118 | $base_key = "NtKey:\MACHINE\SOFTWARE\Classes" 119 | Get-Item "$base_key\.txt" | Select-Object -ExpandProperty Values 120 | Get-ChildItem "$base_key\txtfile\Shell" | Format-Table 121 | Get-Item "$base_key\txtfile\Shell\open\Command" | 122 | Select-Object -ExpandProperty Values | Format-Table 123 | 124 | # Listing 3-24 125 | Get-Win32Service 126 | 127 | # Listing 3-25 128 | $imps = ls "$env:WinDir\*.exe" | ForEach-Object { 129 | Get-Win32ModuleImport -Path $_.FullName 130 | } 131 | $imps | Where-Object Names -Contains "CreateProcessW" | Select-Object ModulePath 132 | 133 | # Listing 3-26 134 | $key = New-NtKey -Win32Path "HKCU\SOFTWARE\`0HIDDENKEY" 135 | ls NtKeyUser:\SOFTWARE -Recurse | Where-Object Name -Match "`0" 136 | Remove-NtKey $key 137 | $key.Close() 138 | 139 | # Listing 3-27 140 | $key = New-NtKey -Win32Path "HKCU\SOFTWARE\ABC" 141 | Set-NtKeyValue -Key $key -Name "`0HIDDEN" -String "HELLO" 142 | function Select-HiddenValue { 143 | [CmdletBinding()] 144 | param( 145 | [parameter(ValueFromPipeline)] 146 | $Key 147 | ) 148 | Process { 149 | foreach($val in $Key.Values) { 150 | if ($val.Name -match "`0") { 151 | [PSCustomObject]@{ 152 | RelativePath = $Key.RelativePath 153 | Name = $val.Name 154 | Value = $val.DataObject 155 | } 156 | } 157 | } 158 | } 159 | } 160 | ls -Recurse NtKeyUser:\SOFTWARE | Select-HiddenValue | Format-Table 161 | Remove-NtKey $key 162 | $key.Close() -------------------------------------------------------------------------------- /chapter_4/chapter_4_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 4-1 2 | $token = Get-NtToken 3 | $token.User 4 | $token.Close() 5 | 6 | # Listing 4-2 7 | $token = Get-NtToken 8 | Format-NtToken $token -All 9 | $token.Close() 10 | 11 | # Listing 4-3 12 | $token = Get-NtToken 13 | Invoke-NtToken $token { 14 | Get-NtDirectory -Path "\" 15 | } -ImpersonationLevel Impersonation 16 | 17 | Invoke-NtToken $token { 18 | Get-NtDirectory -Path "\" 19 | } -ImpersonationLevel Identification 20 | $token.Close() 21 | 22 | # Listing 4-4 and 4-5 23 | $token = Get-NtToken 24 | $imp_token = Copy-NtToken -Token $token -ImpersonationLevel Delegation 25 | $imp_token.ImpersonationLevel 26 | $imp_token.TokenType 27 | $pri_token = Copy-NtToken -Token $imp_token -Primary 28 | $pri_token.TokenType 29 | $pri_token.ImpersonationLevel 30 | $imp_token.Close() 31 | $pri_token.Close() 32 | $token.Close() 33 | 34 | # Listing 4-6 35 | $token = Get-NtToken 36 | $imp_token = Copy-NtToken -Token $token -ImpersonationLevel Identification 37 | $pri_token = Copy-NtToken -Token $imp_token -Primary 38 | $imp_token.Close() 39 | $token.Close() 40 | 41 | # Listing 4-7 42 | Invoke-NtToken -Anonymous {Get-NtToken -Pseudo -Primary | Get-NtTokenSid} 43 | Invoke-NtToken -Anonymous {Get-NtToken -Pseudo -Impersonation | Get-NtTokenSid} 44 | Invoke-NtToken -Anonymous {Get-NtToken -Pseudo -Effective | Get-NtTokenSid} 45 | Invoke-NtToken -Anonymous {Get-NtToken -Pseudo -Effective} | Get-NtTokenSid 46 | 47 | # Listing 4-8 48 | $token = Get-NtToken 49 | Get-NtTokenGroup $token 50 | $token.Close() 51 | 52 | # Listing 4-9 53 | $token = Get-NtToken 54 | Get-NtTokenSid $token -Owner 55 | Set-NtTokenSid -Owner -Sid "S-1-2-3-4" 56 | $token.Close() 57 | 58 | # Listing 4-10 59 | $token = Get-NtToken 60 | Get-NtTokenSid $token -Integrity 61 | $token.Close() 62 | 63 | # Listing 4-11 64 | $token = Get-NtToken -Duplicate 65 | Set-NtTokenIntegrityLevel Low -Token $token 66 | Get-NtTokenSid $token -Integrity 67 | $token.Close() 68 | 69 | # Listing 4-12 70 | $token = Get-NtToken 71 | Get-NtTokenGroup -Device -Token $token 72 | $token.Close() 73 | 74 | # Listing 4-13 75 | $token = Get-NtToken 76 | Get-NtTokenPrivilege -Token $token 77 | $token.Close() 78 | 79 | # Listing 4-14 80 | $token = Get-NtToken 81 | Get-NtTokenPrivilege $token -Privileges SeChangeNotifyPrivilege | Format-List 82 | $token.Close() 83 | 84 | # Listing 4-15 85 | $token = Get-NtToken -Duplicate 86 | Enable-NtTokenPrivilege SeTimeZonePrivilege -Token $token -PassThru 87 | Disable-NtTokenPrivilege SeTimeZonePrivilege -Token $token -PassThru 88 | $token.Close() 89 | 90 | # Listing 4-16 91 | $token = Get-NtToken -Duplicate 92 | Get-NtTokenPrivilege $token -Privileges SeTimeZonePrivilege 93 | Remove-NtTokenPrivilege SeTimeZonePrivilege -Token $token 94 | Get-NtTokenPrivilege $token -Privileges SeTimeZonePrivilege 95 | $token.Close() 96 | 97 | # Listing 4-17 98 | $token = Get-NtToken -Duplicate 99 | Enable-NtTokenPrivilege SeChangeNotifyPrivilege 100 | Disable-NtTokenPrivilege SeTimeZonePrivilege 101 | Test-NtTokenPrivilege SeChangeNotifyPrivilege 102 | Test-NtTokenPrivilege SeTimeZonePrivilege, SeChangeNotifyPrivilege -All 103 | Test-NtTokenPrivilege SeTimeZonePrivilege, SeChangeNotifyPrivilege -All -PassResult 104 | $token.Close() 105 | 106 | # Listing 4-18 107 | $token = Get-NtToken -Filtered -RestrictedSids RC -SidsToDisable WD -Flags DisableMaxPrivileges 108 | Get-NtTokenGroup $token -Attributes UseForDenyOnly 109 | Get-NtTokenGroup $token -Restricted 110 | Get-NtTokenPrivilege $token 111 | $token.Restricted 112 | $token.Close() 113 | 114 | # Listing 4-19 115 | $token = Get-NtToken -Filtered -RestrictedSids WR -Flags WriteRestricted 116 | Get-NtTokenGroup $token -Restricted 117 | $token.Restricted 118 | $token.WriteRestricted 119 | $token.Close() 120 | 121 | # Listing 4-20 122 | Get-NtSid -PackageName 'my_package' -ToSddl 123 | Get-NtSid -PackageName 'my_package' -RestrictedPackageName "CHILD" -ToSddl 124 | Get-NtSid -KnownSid CapabilityInternetClient -ToSddl 125 | Get-NtSid -CapabilityName registryRead -ToSddl 126 | Get-NtSid -CapabilityName registryRead -CapabilityGroup -ToSddl 127 | 128 | # Listing 4-21 129 | $token = Get-NtToken -LowBox -PackageSid 'my_package' -CapabilitySid "registryRead", "S-1-15-3-1" 130 | Get-NtTokenGroup $token -Capabilities | Select-Object Name 131 | $package_sid = Get-NtTokenSid $token -Package -ToSddl 132 | $package_sid 133 | Get-NtTokenIntegrityLevel $token 134 | $token.Close() 135 | 136 | # Listing 4-22 137 | $token = Get-NtToken 138 | $token.Elevated 139 | $token.Close() 140 | 141 | # Listing 4-23 142 | ls C:\Windows\System32\*.exe | Get-Win32ModuleManifest 143 | 144 | # Listing 4-24 145 | Use-NtObject($token = Get-NtToken -Linked) { 146 | Format-NtToken $token -Group -Privilege -Integrity -Information 147 | } 148 | 149 | # Listing 4-25 150 | Use-NtObject($token = Get-NtToken) { 151 | Format-NtToken $token -Group -Privilege -Integrity -Information 152 | } 153 | 154 | # Listing 4-26 155 | $process = Start-Process "osk.exe" -PassThru 156 | $token = Get-NtToken -ProcessId $process.Id 157 | $token.UIAccess 158 | $token.Close() 159 | 160 | # Listing 4-27 161 | $file = New-NtFile -Win32Path C:\Windows\hello.txt -Access GenericWrite 162 | $token = Get-NtToken 163 | $token.VirtualizationEnabled = $true 164 | $file = New-NtFile -Win32Path C:\Windows\hello.txt -Access GenericWrite 165 | $file.Win32PathName 166 | $file.Close() 167 | $token.VirtualizationEnabled = $fa 168 | $token.Close() 169 | 170 | # Listing 4-28 171 | Show-NtTokenEffective -SecurityAttributes 172 | 173 | # Listing 4-30 174 | $token = Get-NtToken -Filtered -Flags DisableMaxPrivileges 175 | Use-NtObject($proc = New-Win32Process notepad -Token $token) { 176 | $proc | Out-Host 177 | } 178 | $token2 = Get-NtToken -Filtered -Flags DisableMaxPrivileges -Token $token 179 | $proc = New-Win32Process notepad -Token $token2 180 | $token2.Close() 181 | $token.Close() 182 | 183 | # Listing 4-31 184 | $proc = Get-NtProcess -Current 185 | $token = Get-NtToken -Duplicate -TokenType Primary 186 | Set-NtToken -Process $proc -Token $token 187 | $token.Close() 188 | 189 | # Listing 4-32 190 | $token = Get-NtToken -Duplicate 191 | Test-NtTokenImpersonation $token 192 | Set-NtTokenIntegrityLevel -IntegrityLevel Low 193 | Test-NtTokenImpersonation $token 194 | Test-NtTokenImpersonation $token -ImpersonationLevel Identification 195 | 196 | # Listing 4-33 197 | $ps = Get-NtProcess -Access QueryLimitedInformation -FilterScript { 198 | Use-NtObject($token = Get-NtToken -Process $_ -Access Query) { 199 | $token.UIAccess 200 | } 201 | } 202 | $ps 203 | $ps.Close() 204 | 205 | # Listing 4-34 206 | function Get-ImpersonationTokens { 207 | $hs = Get-NtHandle -ObjectType Token 208 | foreach($h in $hs) { 209 | try { 210 | Use-NtObject($token = Copy-NtObject -Handle $h) { 211 | if (Test-NtTokenImpersonation -Token $token) { 212 | Copy-NtObject -Object $token 213 | } 214 | } 215 | } catch { 216 | } 217 | } 218 | } 219 | $tokens = Get-ImpersonationTokens 220 | $tokens | Where-Object Elevated 221 | -------------------------------------------------------------------------------- /chapter_4/listing_4_29.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | Enable-NtTokenPrivilege SeDebugPrivilege 3 | $imp = Use-NtObject($p = Get-NtProcess -Name lsass.exe) { 4 | Get-NtToken -Process $p -Duplicate 5 | } 6 | Enable-NtTokenPrivilege SeCreateTokenPrivilege -Token $imp 7 | $token = Invoke-NtToken $imp { 8 | New-NtToken -User "S-1-0-0" -Group "S-1-1-0" 9 | } 10 | Format-NtToken $token -User -Group 11 | $token.Close() -------------------------------------------------------------------------------- /chapter_4/listing_4_35.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 4-35 4 | $token = Get-NtToken -Filtered -Flags LuaToken 5 | Set-NtTokenIntegrityLevel Medium -Token $token 6 | $token.Elevated 7 | "Admin" > "$env:windir\admin.txt" 8 | Invoke-NtToken $token { 9 | "User" > "$env:windir\user.txt" 10 | } 11 | $token.Close() -------------------------------------------------------------------------------- /chapter_5/chapter_5_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 5-1 2 | $domain_sid = Get-NtSid -SecurityAuthority Nt -RelativeIdentifier 32 3 | Get-NtSidName $domain_sid 4 | 5 | # Listing 5-2 6 | $user_sid = Get-NtSid -BaseSid $domain_sid -RelativeIdentifier 545 7 | Get-NtSidName $user_sid 8 | $user_sid.Name 9 | 10 | # Listing 5-3 11 | Get-NtSid -BaseSid $domain_sid -RelativeIdentifier 544 12 | 13 | # Listing 5-4 14 | Get-NtSid -KnownSid BuiltinAdministrators 15 | 16 | # Listing 5-5 17 | ConvertFrom-NtAceCondition 'WIN://TokenId == "XYZ"' | Out-HexDump -ShowAll 18 | 19 | # Listing 5-6 20 | $world = Get-NtSid -KnownSid World 21 | $sd = New-NtSecurityDescriptor -Owner $world -Group $world -Type File 22 | $sd | Format-Table 23 | 24 | # Listing 5-7 25 | $user = Get-NtSid 26 | Add-NtSecurityDescriptorAce $sd -Sid $user -Access WriteData, ReadData 27 | Add-NtSecurityDescriptorAce $sd -KnownSid Anonymous -Access GenericAll -Type Denied 28 | Add-NtSecurityDescriptorAce $sd -Name "Everyone" -Access ReadData 29 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Access Delete -Type Audit -Flags FailedAccess 30 | Set-NtSecurityDescriptorIntegrityLevel $sd Low 31 | Set-NtSecurityDescriptorControl $sd DaclAutoInherited, SaclProtected 32 | $sd | Format-Table 33 | Get-NtSecurityDescriptorControl $sd 34 | Get-NtSecurityDescriptorDacl $sd | Format-Table 35 | Get-NtSecurityDescriptorSacl $sd | Format-Table 36 | 37 | # Listing 5-8 38 | Test-NtSecurityDescriptor $sd -DaclCanonical 39 | Edit-NtSecurityDescriptor $sd -CanonicalizeDacl 40 | Test-NtSecurityDescriptor $sd -DaclCanonical 41 | Get-NtSecurityDescriptorDacl $sd | Format-Table 42 | 43 | # Listing 5-9 44 | Format-NtSecurityDescriptor $sd -ShowAll 45 | 46 | # Listing 5-10 47 | Format-NtSecurityDescriptor $sd -ShowAll -Summary 48 | 49 | # Listing 5-11 50 | Format-NtSecurityDescriptor $sd -SDKName -SecurityInformation Dacl 51 | 52 | # Listing 5-12 53 | Format-NtSecurityDescriptor $sd -ShowAll -Summary -Container 54 | 55 | # Listing 5-13 56 | $ba = ConvertFrom-NtSecurityDescriptor $sd 57 | $ba | Out-HexDump -ShowAll 58 | 59 | # Listing 5-14 60 | $sddl = Format-NtSecurityDescriptor $sd -ToSddl -ShowAll 61 | $sddl 62 | 63 | # Listing 5-15 64 | $sddl -split "(?=O:)|(?=G:)|(?=D:)|(?=S:)|(?=\()" 65 | 66 | # Listing 5-16 67 | Get-NtSid -Sddl "WD" 68 | 69 | # Listing 5-17 70 | Get-NtSid -Sddl (Get-NtSid) -ToName 71 | 72 | # Listing 5-18 73 | ConvertFrom-NtSecurityDescriptor $sd -AsBase64 -InsertLineBreaks 74 | 75 | # Listing 5-19 76 | $sid = Get-NtSid -SecurityAuthority Nt -RelativeIdentifier 100, 200, 300 77 | $ba = ConvertFrom-NtSid -Sid $sid 78 | $ba | Out-HexDump -ShowAll 79 | $stm = [System.IO.MemoryStream]::new($ba) 80 | $reader = [System.IO.BinaryReader]::new($stm) 81 | $revision = $reader.ReadByte() 82 | if ($revision -ne 1) { 83 | throw "Invalid SID revision" 84 | } 85 | $rid_count = $reader.ReadByte() 86 | $auth = $reader.ReadBytes(6) 87 | if ($auth.Length -ne 6) { 88 | throw "Invalid security authority length" 89 | } 90 | $rids = @() 91 | while($rid_count -gt 0) { 92 | $rids += $reader.ReadUInt32() 93 | $rid_count-- 94 | } 95 | $new_sid = Get-NtSid -SecurityAuthorityByte $auth -RelativeIdentifier $rids 96 | $new_sid -eq $sid 97 | 98 | # Listing 5-20 99 | function Get-AccountSids { 100 | param( 101 | [parameter(Mandatory)] 102 | $BaseSid, 103 | [int]$MinRid = 0, 104 | [int]$MaxRid = 256 105 | ) 106 | $i = $MinRid 107 | while($i -lt $MaxRid) { 108 | $sid = Get-NtSid -BaseSid $BaseSid -RelativeIdentifier $i 109 | $name = Get-NtSidName $sid 110 | if ($name.Source -eq "Account") { 111 | [PSCustomObject]@{ 112 | Sid = $sid; 113 | Name = $name.QualifiedName; 114 | Use = $name.NameUse 115 | } 116 | } 117 | $i++ 118 | } 119 | } 120 | $sid = Get-NtSid -SecurityAuthority Nt 121 | Get-AccountSids -BaseSid $sid 122 | $sid = Get-NtSid -BaseSid $sid -RelativeIdentifier 32 123 | Get-AccountSids -BaseSid $sid -MinRid 512 -MaxRid 1024 -------------------------------------------------------------------------------- /chapter_6/chapter_6_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 6-2 2 | Use-NtObject($d = Get-NtDirectory "\BaseNamedObjects" -Access ReadControl) { 3 | Get-NtSecurityDescriptor -Object $d 4 | } 5 | 6 | # Listing 6-3 7 | Get-NtSecurityDescriptor "\BaseNamedObjects" -SecurityInformation Owner 8 | 9 | # Listing 6-4 10 | $creator = New-NtSecurityDescriptor -Type Mutant 11 | Add-NtSecurityDescriptorAce $creator -Name "Everyone" -Access GenericRead 12 | Format-NtSecurityDescriptor $creator 13 | $token = Get-NtToken -Effective -Pseudo 14 | $sd = New-NtSecurityDescriptor -Token $token -Creator $creator -Type Mutant 15 | Format-NtSecurityDescriptor $sd 16 | 17 | # Listing 6-5 18 | Format-NtToken $token -Owner -PrimaryGroup 19 | 20 | # Listing 6-6 21 | Set-NtSecurityDescriptorOwner $creator -KnownSid LocalSystem 22 | New-NtSecurityDescriptor -Token $token -Creator $creator -Type Mutant 23 | 24 | # Listing 6-7 25 | $creator = New-NtSecurityDescriptor -Type Mutant 26 | Add-NtSecurityDescriptorAce $creator -Name "Everyone" -Access GenericRead 27 | Use-NtObject($m = New-NtMutant -SecurityDescriptor $creator) { 28 | Format-NtSecurityDescriptor $m 29 | } 30 | 31 | # Listing 6-8 32 | $token = Get-NtToken -Effective -Pseudo 33 | $sd = New-NtSecurityDescriptor -Token $token -Type Mutant 34 | Format-NtSecurityDescriptor $sd -HideHeader 35 | 36 | # Listing 6-9 37 | Format-NtToken $token -DefaultDacl 38 | 39 | # Listing 6-10 40 | Use-NtObject($m = New-NtMutant) { 41 | Format-NtSecurityDescriptor $m 42 | } 43 | 44 | # Listing 6-11 45 | Get-NtType "Mutant" | Select-Object SecurityRequired 46 | 47 | # Listing 6-12 48 | Get-NtType Directory | Select-Object SecurityRequired 49 | Use-NtObject($dir = New-NtDirectory) { 50 | Format-NtSecurityDescriptor $dir -Summary 51 | } 52 | 53 | # Listing 6-13 54 | function New-ParentSD($AceFlags = 0, $Control = 0) { 55 | $owner = Get-NtSid -KnownSid BuiltinAdministrators 56 | $parent = New-NtSecurityDescriptor -Type Directory -Owner $owner -Group $owner 57 | Add-NtSecurityDescriptorAce $parent -Name "Everyone" -Access GenericAll 58 | Add-NtSecurityDescriptorAce $parent -Name "Users" -Access GenericAll -Flags $AceFlags 59 | Add-NtSecurityDescriptorControl $parent -Control $Control 60 | Edit-NtSecurityDescriptor $parent -MapGeneric 61 | return $parent 62 | } 63 | 64 | function Test-NewSD($AceFlags = 0, 65 | $Control = 0, 66 | $Creator = $null, 67 | [switch]$Container) { 68 | $parent = New-ParentSD -AceFlags $AceFlags -Control $Control 69 | Write-Output "-= Parent SD =-" 70 | Format-NtSecurityDescriptor $parent -Summary 71 | if ($Creator -ne $null) { 72 | Write-Output "`r`n-= Creator SD =-" 73 | Format-NtSecurityDescriptor $creator -Summary 74 | } 75 | $auto_inherit_flags = @() 76 | if (Test-NtSecurityDescriptor $parent -DaclAutoInherited) { 77 | $auto_inherit_flags += "DaclAutoInherit" 78 | } 79 | if (Test-NtSecurityDescriptor $parent -SaclAutoInherited) { 80 | $auto_inherit_flags += "SaclAutoInherit" 81 | } 82 | if ($auto_inherit_flags.Count -eq 0) { 83 | $auto_inherit_flags += "None" 84 | } 85 | $token = Get-NtToken -Effective -Pseudo 86 | $sd = New-NtSecurityDescriptor -Token $token -Parent $parent -Creator $creator -Type Mutant -Container:$Container -AutoInherit $auto_inherit_flags 87 | Write-Output "`r`n-= New SD =-" 88 | Format-NtSecurityDescriptor $sd -Summary 89 | } 90 | 91 | # Listing 6-14 92 | Test-NewSD 93 | 94 | # Listing 6-15 95 | Test-NewSD -AceFlags "ObjectInherit" 96 | 97 | # Listing 6-16 98 | Get-NtAccessMask (0x0001F0001 -band 0x0000F000F) -ToSpecificAccess Mutant 99 | 100 | # Listing 6-17 101 | Test-NewSD -AceFlags "ObjectInherit, InheritOnly" 102 | 103 | # Listing 6-18 104 | Test-NewSD -AceFlags "ContainerInherit, InheritOnly" -Container 105 | 106 | # Listing 6-19 107 | $ace_flags = "ContainerInherit, InheritOnly, NoPropagateInherit" 108 | Test-NewSD -AceFlags $ace_flags -Container 109 | 110 | # Listing 6-20 111 | Test-NewSD -AceFlags "ObjectInherit" -Container 112 | 113 | # Listing 6-21 114 | $ace_flags = "ObjectInherit, InheritOnly" 115 | Test-NewSD -AceFlags $ace_flags -Control "DaclAutoInherited" 116 | 117 | # Listing 6-22 118 | function New-CreatorSD($AceFlags = 0, $Control = 0, [switch]$NoDacl) { 119 | $creator = New-NtSecurityDescriptor -Type Mutant 120 | if (!$NoDacl) { 121 | Add-NtSecurityDescriptorAce $creator -Name "Network" -Access GenericAll 122 | Add-NtSecurityDescriptorAce $creator -Name "Interactive" -Access GenericAll -Flags $AceFlags 123 | } 124 | Add-NtSecurityDescriptorControl $creator -Control $Control 125 | Edit-NtSecurityDescriptor $creator -MapGeneric 126 | return $creator 127 | } 128 | 129 | # Listing 6-23 130 | $creator = New-CreatorSD -NoDacl 131 | Test-NewSD -Creator $creator -AceFlags "ObjectInherit, InheritOnly" 132 | 133 | # Listing 6-24 134 | $creator = New-CreatorSD 135 | Test-NewSD -Creator $creator -AceFlags "ObjectInherit, InheritOnly" 136 | 137 | # Listing 6-25 138 | $creator = New-CreatorSD -AceFlags "Inherited" 139 | Test-NewSD -Creator $creator -AceFlags "ObjectInherit, InheritOnly" -Control "DaclAutoInherited" 140 | 141 | # Listing 6-26 142 | $creator = New-CreatorSD -AceFlags "Inherited" -Control "DaclProtected" 143 | Test-NewSD -Creator $creator -AceFlags "ObjectInherit, InheritOnly" -Control "DaclAutoInherited" 144 | 145 | # Listing 6-27 146 | $creator = New-CreatorSD -Control "DaclDefaulted" 147 | Test-NewSD -Creator $creator -AceFlags "ObjectInherit, InheritOnly" 148 | Test-NewSD -Creator $creator 149 | 150 | # Listing 6-28 151 | $parent = New-NtSecurityDescriptor -Type Directory 152 | Add-NtSecurityDescriptorAce $parent -KnownSid CreatorOwner -Flags ContainerInherit, InheritOnly -Access GenericWrite 153 | Add-NtSecurityDescriptorAce $parent -KnownSid CreatorGroup -Flags ContainerInherit, InheritOnly -Access GenericRead 154 | Format-NtSecurityDescriptor $parent -Summary -SecurityInformation Dacl 155 | $token = Get-NtToken -Effective -Pseudo 156 | $sd = New-NtSecurityDescriptor -Token $token -Parent $parent -Type Directory -Container 157 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation Dacl 158 | 159 | # Listing 6-29 160 | $token = Get-NtToken -Duplicate -IntegrityLevel Low 161 | $sd = New-NtSecurityDescriptor -Token $token -Type Mutant 162 | Format-NtSecurityDescriptor $sd -SecurityInformation Label -Summary 163 | $token.Close() 164 | 165 | # Listing 6-30 166 | $creator = New-NtSecurityDescriptor -Type Mutant 167 | Set-NtSecurityDescriptorIntegrityLevel $creator System 168 | $token = Get-NtToken -Duplicate -IntegrityLevel Medium 169 | New-NtSecurityDescriptor -Token $token -Creator $creator -Type Mutant 170 | $sd = New-NtSecurityDescriptor -Token $token -Creator $creator -Type Mutant -AutoInherit AvoidPrivilegeCheck 171 | Format-NtSecurityDescriptor $sd -SecurityInformation Label -Summary 172 | 173 | # Listing 6-31 174 | $parent = New-NtSecurityDescriptor -Type Mutant 175 | Set-NtSecurityDescriptorIntegrityLevel $parent Low -Flags ObjectInherit 176 | $token = Get-NtToken -Effective -Pseudo 177 | $sd = New-NtSecurityDescriptor -Token $token -Parent $parent -Type Mutant 178 | Format-NtSecurityDescriptor $sd -SecurityInformation Label -Summary 179 | 180 | # Listing 6-32 181 | $token = Get-NtToken -Effective -Pseudo 182 | $sd = New-NtSecurityDescriptor -Token $token -Type Mutant 183 | -AutoInherit MaclNoReadUp, MaclNoWriteUp 184 | PS> Format-NtSecurityDescriptor $sd -SecurityInformation Label -Summary 185 | 186 | # Listing 6-33 187 | $owner = Get-NtSid -KnownSid BuiltinAdministrators 188 | $parent = New-NtSecurityDescriptor -Type Directory -Owner $owner -Group $owner 189 | $type_1 = New-Guid 190 | $type_2 = New-Guid 191 | Add-NtSecurityDescriptorAce $parent -Name "SYSTEM" -Access GenericAll -Flags ObjectInherit -Type AllowedObject -ObjectType $type_1 192 | Add-NtSecurityDescriptorAce $parent -Name "Everyone" -Access GenericAll -Flags ObjectInherit -Type AllowedObject -InheritedObjectType $type_1 193 | Add-NtSecurityDescriptorAce $parent -Name "Users" -Access GenericAll -Flags ObjectInherit -InheritedObjectType $type_2 -Type AllowedObject 194 | Format-NtSecurityDescriptor $parent -Summary -SecurityInformation Dacl 195 | $token = Get-NtToken -Effective -Pseudo 196 | $sd = New-NtSecurityDescriptor -Token $token -Parent $parent -Type Directory -ObjectType $type_2 197 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation Dacl 198 | 199 | # Listing 6-34 200 | Get-NtAccessMask -SecurityInformation AllBasic -ToGenericAcces 201 | Get-NtAccessMask -SecurityInformation AllBasic -ToGenericAccess -SetSecurity 202 | 203 | # Listing 6-35 204 | $owner = Get-NtSid -KnownSid BuiltinAdministrators 205 | $obj_sd = New-NtSecurityDescriptor -Type Mutant -Owner $owner -Group $owner 206 | Add-NtSecurityDescriptorAce $obj_sd -KnownSid World -Access GenericAll 207 | Format-NtSecurityDescriptor $obj_sd -Summary -SecurityInformation Dacl 208 | Edit-NtSecurityDescriptor $obj_sd -MapGeneric 209 | $mod_sd = New-NtSecurityDescriptor -Type Mutant 210 | Add-NtSecurityDescriptorAce $mod_sd -KnownSid Anonymous -Access GenericRead 211 | Set-NtSecurityDescriptorControl $mod_sd DaclAutoInherited, DaclAutoInheritReq 212 | Edit-NtSecurityDescriptor $obj_sd $mod_sd -SecurityInformation Dacl 213 | Format-NtSecurityDescriptor $obj_sd -Summary -SecurityInformation Dacl 214 | 215 | # Listing 6-36 216 | Get-Win32SecurityDescriptor "$env:WinDir" 217 | Format-Win32SecurityDescriptor "MACHINE\SOFTWARE" -Type RegistryKey -Summary 218 | 219 | # Listing 6-37 220 | $path = Join-Path "$env:TEMP" "TestFolder" 221 | Use-NtObject($f = New-NtFile $path -Win32Path -Options DirectoryFile -Disposition OpenIf) { 222 | Set-NtSecurityDescriptor $f "D:AIARP(A;OICI;GA;;;WD)" Dacl 223 | } 224 | $item = Join-Path $path test.txt 225 | "Hello World!" | Set-Content -Path $item 226 | Format-Win32SecurityDescriptor $item -Summary -SecurityInformation Dacl 227 | $sd = Get-Win32SecurityDescriptor $path 228 | Add-NtSecurityDescriptorAce $sd -KnownSid Anonymous -Access GenericAll -Flags ObjectInherit,ContainerInherit,InheritOnly 229 | Set-Win32SecurityDescriptor $path $sd Dacl 230 | Format-Win32SecurityDescriptor $item -Summary -SecurityInformation Dacl 231 | 232 | # Listing 6-38 233 | $path = Join-Path "$env:TEMP\TestFolder" "test.txt" 234 | $sd = New-NtSecurityDescriptor "D:(A;;GA;;;AU)" 235 | Set-Win32SecurityDescriptor $path $sd Dacl,ProtectedDacl 236 | Format-Win32SecurityDescriptor $path -Summary -SecurityInformation Dacl 237 | Set-Win32SecurityDescriptor $path $sd Dacl,UnprotectedDacl 238 | Format-Win32SecurityDescriptor $path -Summary -SecurityInformation Dacl 239 | 240 | # Listing 6-39 241 | $path = Join-Path "$env:TEMP\TestFolder" "test.txt" 242 | Reset-Win32SecurityDescriptor $path Dacl 243 | Format-Win32SecurityDescriptor $path -Summary -SecurityInformation Dacl 244 | 245 | # Listing 6-40 246 | $path = Join-Path "$env:TEMP" "TestFolder" 247 | Search-Win32SecurityDescriptor $path | Format-Table 248 | $path = Join-Path $path "new.txt" 249 | "Hello" | Set-Content $path 250 | Search-Win32SecurityDescriptor $path | Format-Table 251 | 252 | # Listing 6-41 253 | $token = Get-NtToken -Anonymous 254 | $creator = New-NtSecurityDescriptor -Type Mutant 255 | Add-NtSecurityDescriptorAce $creator -KnownSid World -Access GenericAll 256 | $sd = New-NtSecurityDescriptor -Token $token -Creator $creator 257 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation Owner,Group,Dacl 258 | Set-NtSecurityDescriptorControl $creator ServerSecurity 259 | $sd = New-NtSecurityDescriptor -Token $token -Creator $creator 260 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation Owner,Group,Dacl 261 | 262 | # Listing 6-42 263 | function Get-NameAndOwner { 264 | [CmdletBinding()] 265 | param( 266 | [parameter(Mandatory, ValueFromPipeline)] 267 | $Entry, 268 | [parameter(Mandatory)] 269 | $Root 270 | ) 271 | begin { 272 | $curr_owner = Get-NtSid -Owner 273 | } 274 | process { 275 | $sd = Get-NtSecurityDescriptor -Path $Entry.Name -Root $Root -TypeName $Entry.NtTypeName -ErrorAction SilentlyContinue 276 | if ($null -ne $sd -and $sd.Owner.Sid -ne $curr_owner) { 277 | [PSCustomObject] @{ 278 | Name = $Entry.Name 279 | NtTypeName = $Entry.NtTypeName 280 | Owner = $sd.Owner.Sid.Name 281 | SecurityDescriptor = $sd 282 | } 283 | } 284 | } 285 | } 286 | Use-NtObject($dir = Get-NtDirectory \BaseNamedObjects) { 287 | Get-NtDirectoryEntry $dir | Get-NameAndOwner -Root $dir 288 | } 289 | 290 | # Listing 6-43 291 | $entry = $null # Need to set this to a known value. 292 | Get-NtGrantedAccess -SecurityDescriptor $entry.SecurityDescriptor 293 | 294 | # Listing 6-44 295 | (Get-Acl C:\ | ConvertTo-NtSecurityDescriptor).Owner.Sid -------------------------------------------------------------------------------- /chapter_6/listing_6_1.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | $dir = Get-NtDirectory "\BaseNamedObjects" -Access AccessSystemSecurity 3 | Enable-NtTokenPrivilege SeSecurityPrivilege 4 | $dir = Get-NtDirectory "\BaseNamedObjects" -Access AccessSystemSecurity 5 | $dir.GrantedAccess -------------------------------------------------------------------------------- /chapter_6/listing_6_45.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | $new_dir = New-NtDirectory "ABC" -Win32Path 3 | Get-NtSecurityDescriptor $new_dir | Select {$_.Owner.Sid.Name} 4 | Enable-NtTokenPrivilege SeRestorePrivilege 5 | Use-NtObject($dir = Get-NtDirectory "ABC" -Win32Path -Access WriteOwner) { 6 | $sid = Get-NtSid -KnownSid World 7 | $sd = New-NtSecurityDescriptor -Owner $sid 8 | Set-NtSecurityDescriptor $dir $sd -SecurityInformation Owner 9 | } 10 | Get-NtSecurityDescriptor $new_dir | Select {$_.Owner.Sid.Name} 11 | $new_dir.Close() -------------------------------------------------------------------------------- /chapter_7/chapter_7_access_check_impl.psm1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | 3 | Import-Module NtObjectManager 4 | 5 | function Test-ProcessTrustLevel { 6 | param($context) 7 | 8 | $trust_level = Get-NtTokenSid $context.Token -TrustLevel 9 | if ($null -EQ $trust_level) { 10 | $trust_level = Get-NtSid -TrustType None -TrustLevel None 11 | } 12 | 13 | $access = Get-NtAccessMask 0xFFFFFFFF 14 | $sacl = Get-NtSecurityDescriptorSacl $context.SecurityDescriptor 15 | foreach($ace in $sacl) { 16 | if (!$ace.IsProcessTrustLabelAce -or $ace.IsInheritOnly) { 17 | continue 18 | } 19 | 20 | if (!(Compare-NtSid $trust_level $ace.Sid -Dominates)) { 21 | $access = Get-NtAccessMask $ace 22 | } 23 | break 24 | } 25 | 26 | $access = Grant-NtAccessMask $access AccessSystemSecurity 27 | return Test-NtAccessMask $access $context.RemainingAccess -All 28 | } 29 | 30 | function Test-AccessFilter { 31 | param($context) 32 | 33 | $token = $context.Token 34 | $access = Get-NtAccessMask 0xFFFFFFFF 35 | $sacl = Get-NtSecurityDescriptorSacl $context.SecurityDescriptor 36 | foreach($ace in $sacl) { 37 | if (!$ace.IsAccessFilterAce -or $ace.IsInheritOnly) { 38 | continue 39 | } 40 | if (!(Test-NtAceCondition $ace -Token $token)) { 41 | $access = $access -band $ace.Mask 42 | } 43 | } 44 | 45 | $access = Grant-NtAccessMask $access AccessSystemSecurity 46 | return Test-NtAccessMask $access $context.RemainingAccess -All 47 | } 48 | 49 | function Test-MandatoryIntegrityLevel { 50 | param($context) 51 | 52 | $token = $context.Token 53 | $sd = $context.SecurityDescriptor 54 | $mapping = $context.GenericMapping 55 | 56 | $policy = Get-NtTokenMandatoryPolicy -Token $token 57 | if (($policy -band "NoWriteUp") -eq 0) { 58 | return $true 59 | } 60 | 61 | if ($sd.HasMandatoryLabelAce) { 62 | $ace = $sd.GetMandatoryLabel() 63 | $sd_il_sid = $ace.Sid 64 | $access = Get-NtAccessMask $ace.Mask -GenericMapping $mapping 65 | } else { 66 | $sd_il_sid = Get-NtSid -IntegrityLevel Medium 67 | $access = Get-NtAccessMask -ManadatoryLabelPolicy NoWriteUp -GenericMapping $mapping 68 | } 69 | 70 | if (Test-NtTokenPrivilege -Token $token SeRelabelPrivilege) { 71 | $access = Grant-NtAccessMask $access WriteOwner 72 | } 73 | 74 | $il_sid = Get-NtTokenSid -Token $token -Integrity 75 | if (Compare-NtSid $il_sid $sd_il_sid -Dominates) { 76 | return $true 77 | } 78 | 79 | return Test-NtAccessMask $access $context.RemainingAccess -All 80 | } 81 | 82 | # Mandatory Acccess Implementation 83 | function Test-MandatoryAccess { 84 | param($context) 85 | 86 | if (!(Test-ProcessTrustLevel $context)) { 87 | return $false 88 | } 89 | 90 | if (!(Test-AccessFilter $context)) { 91 | return $false 92 | } 93 | 94 | if (!(Test-MandatoryIntegrityLevel $context)) { 95 | if (!$context.Token.AppContainer -or ` 96 | $context.SecurityDescriptor.IntegrityLevel -le "Medium") { 97 | return $false 98 | } 99 | } 100 | 101 | return $true 102 | } 103 | 104 | function Resolve-TokenPrivilegeAccess { 105 | param($context) 106 | 107 | $token = $context.Token 108 | $access = $context.RemainingAccess 109 | 110 | if ((Test-NtAccessMask $access AccessSystemSecurity) -and 111 | (Test-NtTokenPrivilege -Token $token SeSecurityPrivilege)) { 112 | $access = Revoke-NtAccessMask $access AccessSystemSecurity 113 | $context.Privileges += "SeSecurityPrivilege" 114 | } 115 | 116 | if ((Test-NtAccessMask $access WriteOwner) -and 117 | (Test-NtTokenPrivilege -Token $token SeTakeOwnershipPrivilege)) { 118 | $access = Revoke-NtAccessMask $access WriteOwner 119 | $context.Privileges += "SeTakeOwnershipPrivilege" 120 | } 121 | 122 | if ((Test-NtAccessMask $access WriteOwner) -and 123 | (Test-NtTokenPrivilege -Token $token SeRelabelPrivilege)) { 124 | $access = Revoke-NtAccessMask $access WriteOwner 125 | $context.Privileges += "SeRelabelPrivilege" 126 | } 127 | 128 | $context.RemainingAccess = $access 129 | } 130 | 131 | function Resolve-TokenOwnerAccess { 132 | param($context) 133 | 134 | $token = $context.Token 135 | $sd = $context.SecurityDescriptor 136 | $sd_owner = Get-NtSecurityDescriptorOwner $sd 137 | if (!(Test-NtTokenGroup -Token $token -Sid $sd_owner.Sid)) { 138 | return 139 | } 140 | 141 | if ($token.Restricted -and ` 142 | !(Test-NtTokenGroup -Token $token -Sid $sd_owner.Sid -Restricted)) { 143 | return 144 | } 145 | 146 | $sids = Select-NtSecurityDescriptorAce $sd -KnownSid OwnerRights -First -AclType Dacl 147 | if ($sids -ne $null -and $sids.Count -gt 0) { 148 | return 149 | } 150 | 151 | $access = $context.RemainingAccess 152 | $context.RemainingAccess = Revoke-NtAccessMask $access ReadControl, WriteDac 153 | } 154 | 155 | function Resolve-TokenAccess { 156 | param($context) 157 | 158 | Resolve-TokenPrivilegeAccess $context 159 | if (Test-NtAccessMask $context.RemainingAccess -Empty) { 160 | return 161 | } 162 | Resolve-TokenOwnerAccess $context 163 | } 164 | 165 | function Get-AceSid { 166 | param( 167 | $Sid, 168 | $Owner, 169 | $Principal 170 | ) 171 | 172 | if (Compare-NtSid $sid -KnownSid OwnerRights) { 173 | $sid = $Owner.Sid 174 | } 175 | 176 | if ((Compare-NtSid $Sid -KnownSid Self) -and ($Principal -NE $null)) { 177 | $sid = $Principal 178 | } 179 | 180 | return $sid 181 | } 182 | 183 | function Get-DiscretionaryAccess { 184 | param( 185 | $context, 186 | [switch]$Restricted 187 | ) 188 | 189 | $token = $context.Token 190 | $sd = $context.SecurityDescriptor 191 | $access = $context.RemainingAccess 192 | $ac_access = $context.DesiredAccess 193 | if (!$token.AppContainer) { 194 | $ac_access = Get-NtAccessMask 0 195 | } 196 | $effective_access = Get-NtAccessMask 0 197 | $resource_attrs = $null 198 | if ($sd.ResourceAttributes.Count -gt 0) { 199 | $resource_attrs = $sd.ResourceAttributes.ResourceAttribute 200 | } 201 | 202 | if (!$token.AppContainer) { 203 | if (!(Test-NtSecurityDescriptor $sd -DaclPresent) ` 204 | -or (Test-NtSecurityDescriptor $sd -DaclNull)) { 205 | $context.RemainingAccess = Get-NtAccessMask 0 206 | return 207 | } 208 | } 209 | 210 | $owner = Get-NtSecurityDescriptorOwner $sd 211 | $dacl = Get-NtSecurityDescriptorDacl $sd 212 | 213 | foreach($ace in $dacl) { 214 | if ($ace.IsInheritOnly) { 215 | continue 216 | } 217 | $sid = Get-AceSid -Sid $ace.Sid -Owner $owner -Principal $context.Principal 218 | $continue_check = $true 219 | switch($ace.Type) { 220 | "Allowed" { 221 | if (Test-NtTokenGroup -Token $token $sid -Restricted:$Restricted) { 222 | $access = Revoke-NtAccessMask $access $ace.Mask 223 | } else { 224 | if ($Restricted) { 225 | break 226 | } 227 | 228 | if (Test-NtTokenGroup -Token $token $sid -Capability) { 229 | $ac_access = Revoke-NtAccessMask $ac_access $ace.Mask 230 | } 231 | } 232 | } 233 | "Denied" { 234 | if (Test-NtTokenGroup -Token $token $sid -DenyOnly -Restricted:$Restricted) { 235 | if (Test-NtAccessMask $access $ace.Mask) { 236 | $continue_check = $false 237 | } 238 | } 239 | } 240 | "AllowedCompound" { 241 | $server_sid = Get-AceSid -Sid $ace.ServerSid -Owner $owner -Principal $context.Principal 242 | if ((Test-NtTokenGroup -Token $Token $sid -Restricted:$Restricted) -and (Test-NtTokenGroup -Sid $server_sid -Restricted:$Restricted)) { 243 | $access = Revoke-NtAccessMask $access $ace.Mask 244 | } 245 | } 246 | "AllowedCallback" { 247 | if (!(Test-NtAceCondition $ace -Token $token -ResourceAttribute $resource_attrs)) { 248 | break 249 | } 250 | 251 | if (Test-NtTokenGroup -Token $token $sid -Restricted:$Restricted) { 252 | $access = Revoke-NtAccessMask $access $ace.Mask 253 | } else { 254 | if ($Restricted) { 255 | break 256 | } 257 | 258 | if (Test-NtTokenGroup -Token $token $sid -Capability) { 259 | $ac_access = Revoke-NtAccessMask $ac_access $ace.Mask 260 | } 261 | } 262 | } 263 | "AllowedObject" { 264 | if (!(Test-NtTokenGroup -Token $token $sid -Restricted:$Restricted)) { 265 | break 266 | } 267 | 268 | if ($null -EQ $context.ObjectTypes -or $null -EQ $ace.ObjectType) { 269 | break 270 | } 271 | 272 | $object_type = Select-ObjectTypeTree $context.ObjectTypes 273 | if ($null -EQ $object_type) { 274 | break 275 | } 276 | 277 | Revoke-ObjectTypeTreeAccess $object_type $ace.Mask 278 | $access = Revoke-NtAccessMask $access $ace.Mask 279 | } 280 | "DeniedObject" { 281 | if (!(Test-NtTokenGroup -Token $token $sid -DenyOnly -Restricted:$Restricted)) { 282 | break 283 | } 284 | 285 | if ($null -NE $context.ObjectTypes) { 286 | if ($null -EQ $ace.ObjectType) { 287 | break; 288 | } 289 | 290 | $object_type = Select-ObjectTypeTree $context.ObjectTypes $ace.ObjectType 291 | if ($null -EQ $object_type) { 292 | break 293 | } 294 | 295 | if (Test-NtAccessMask $object_type.RemainingAccess $ace.Mask) { 296 | $continue_check = $false 297 | break 298 | } 299 | } 300 | if (Test-NtAccessMask $access $ace.Mask) { 301 | $continue_check = $false 302 | } 303 | } 304 | } 305 | 306 | $effective_access = $access -bor $ac_access 307 | 308 | if (!$continue_check -or (Test-NtAccessMask $effective_access -Empty)) { 309 | break 310 | } 311 | } 312 | 313 | $context.RemainingAccess = $effective_access 314 | } 315 | 316 | function Get-AccessResult { 317 | param( 318 | $Status, 319 | $Privileges = @(), 320 | $GrantedAccess = 0 321 | ) 322 | 323 | $props = @{ 324 | Status = Get-NtStatus -Name $Status -PassStatus 325 | GrantedAccess = $GrantedAccess 326 | Privileges = $Privileges 327 | } 328 | return New-Object –TypeName PSObject -Prop $props 329 | } 330 | 331 | function Get-PSGrantedAccess { 332 | param( 333 | $Token, 334 | [parameter(Mandatory)] 335 | $SecurityDescriptor, 336 | [parameter(Mandatory)] 337 | $GenericMapping, 338 | [parameter(Mandatory)] 339 | $DesiredAccess, 340 | $Principal, 341 | $ObjectTypes 342 | ) 343 | 344 | if ($null -EQ $Token) { 345 | $Token = Get-NtToken -Effective -Pseudo 346 | } 347 | 348 | $context = @{ 349 | Token = $Token 350 | SecurityDescriptor = $SecurityDescriptor 351 | GenericMapping = $GenericMapping 352 | RemainingAccess = Get-NtAccessMask $DesiredAccess 353 | DesiredAccess = $DesiredAccess 354 | Privileges = @() 355 | Principal = $Principal 356 | ObjectTypes = $ObjectTypes 357 | } 358 | 359 | if (!(Test-MandatoryAccess $context)) { 360 | return Get-AccessResult STATUS_ACCESS_DENIED 361 | } 362 | 363 | Resolve-TokenAccess $context 364 | if ((Test-NtAccessMask $context.RemainingAccess -Empty) -and !$Token.AppContainer) { 365 | return Get-AccessResult STATUS_SUCCESS $context.Privileges $DesiredAccess 366 | } 367 | 368 | # The only way to get AccessSystemSecurity is from the privilege check. 369 | if (Test-NtAccessMask $context.RemainingAccess AccessSystemSecurity) { 370 | return Get-AccessResult STATUS_PRIVILEGE_NOT_HELD 371 | } 372 | 373 | $RemainingAccess = $context.RemainingAccess 374 | Get-DiscretionaryAccess $context 375 | $success = Test-NtAccessMask $context.RemainingAccess -Empty 376 | 377 | $write = $Token.WriteRestricted -and (Test-NtAccessMask $RemainingAccess -WriteRestricted $GenericMapping) 378 | 379 | if ($success -and $Token.Restricted) { 380 | if (!$Token.WriteRestricted -OR (Test-NtAccessMask $RemainingAccess -WriteRestricted $GenericMapping)) { 381 | $context.RemainingAccess = $RemainingAccess 382 | Get-DiscretionaryAccess $context -Restricted 383 | $success = Test-NtAccessMask $context.RemainingAccess -Empty 384 | } 385 | } 386 | 387 | if (!$success) { 388 | return Get-AccessResult STATUS_ACCESS_DENIED 389 | } 390 | 391 | $capid = $SecurityDescriptor.ScopedPolicyId 392 | if ($null -EQ $capid) { 393 | return Get-AccessResult STATUS_SUCCESS $context.Privileges $DesiredAccess 394 | } 395 | 396 | $policy = Get-CentralAccessPolicy -CapId $capid.Sid 397 | if ($null -EQ $policy){ 398 | return Get-AccessResult STATUS_SUCCESS $context.Privileges $DesiredAccess 399 | } 400 | 401 | foreach($rule in $policy.Rules) { 402 | if ($rule.AppliesTo -NE "") { 403 | $resource_attrs = $null 404 | if ($sd.ResourceAttributes.Count -gt 0) { 405 | $resource_attrs = $sd.ResourceAttributes.ResourceAttribute 406 | } 407 | if (!(Test-NtAceCondition -Token $Token -Condition $rule.AppliesTo -ResourceAttribute $resource_attrs)) { 408 | continue 409 | } 410 | } 411 | $new_sd = Copy-NtSecurityDescriptor $SecurityDescriptor 412 | Set-NtSecurityDescriptorDacl -SecurityDescriptor $new_sd -Ace $rule.SecurityDescriptor.Dacl 413 | 414 | $context.SecurityDescriptor = $new_sd 415 | $context.RemainingAccess = $DesiredAccess 416 | 417 | Get-DiscretionaryAccess $context 418 | if (!(Test-NtAccessMask $context.RemainingAccess -Empty)) { 419 | return Get-AccessResult STATUS_ACCESS_DENIED 420 | } 421 | } 422 | 423 | return Get-AccessResult STATUS_SUCCESS $context.Privileges $DesiredAccess 424 | } 425 | 426 | Export-ModuleMember -Function Get-PSGrantedAccess 427 | -------------------------------------------------------------------------------- /chapter_7/chapter_7_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 7-1 2 | $sd = New-NtSecurityDescriptor -EffectiveToken -Type Mutant 3 | Format-NtSecurityDescriptor $sd -Summary 4 | Get-NtGrantedAccess $sd -AsString 5 | Get-NtGrantedAccess $sd -Access ModifyState -AsString 6 | Clear-NtSecurityDescriptorDacl $sd 7 | Format-NtSecurityDescriptor $sd -Summary 8 | Get-NtGrantedAccess $sd -AsString 9 | 10 | # Listing 7-6 11 | function New-BaseSD { 12 | $owner = Get-NtSid -KnownSid LocalSystem 13 | $sd = New-NtSecurityDescriptor -Owner $owner -Group $owner -Type Mutant 14 | Add-NtSecurityDescriptorAce $sd -KnownSid Anonymous -Access GenericAll 15 | $sid = Get-NtSid 16 | Add-NtSecurityDescriptorAce $sd -Sid $sid -Access GenericAll 17 | Set-NtSecurityDescriptorIntegrityLevel $sd Untrusted 18 | Edit-NtSecurityDescriptor $sd -MapGeneric 19 | return $sd 20 | } 21 | 22 | # Listing 7-7 23 | $sd = New-BaseSD 24 | $trust_sid = Get-NtSid -TrustType ProtectedLight -TrustLevel Windows 25 | Add-NtSecurityDescriptorAce $sd -Type ProcessTrustLabel -Access ModifyState -Sid $trust_sid 26 | Get-NtGrantedAccess $sd -AsString 27 | $token = Get-NtToken -Anonymous 28 | $anon_trust_sid = Get-NtTokenSid -Token $token -TrustLevel 29 | Compare-NtSid $anon_trust_sid $trust_sid -Dominates 30 | Get-NtGrantedAccess $sd -Token $token -AsString 31 | $token.Close() 32 | 33 | # Listing 7-8 34 | $sd = New-BaseSD 35 | Add-NtSecurityDescriptorAce $sd -Type AccessFilter -KnownSid World -Access ModifyState -Condition "Exists TSA://ProcUnique" -MapGeneric 36 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation AccessFilter 37 | Show-NtTokenEffective -SecurityAttributes 38 | Get-NtGrantedAccess $sd -AsString 39 | Use-NtObject($token = Get-NtToken -Anonymous) { 40 | Get-NtGrantedAccess $sd -Token $token -AsString 41 | } 42 | 43 | # Listing 7-11 44 | $sd = New-BaseSD 45 | Format-NtSecurityDescriptor $sd -SecurityInformation Label -Summary 46 | Use-NtObject($token = Get-NtToken -Anonymous) { 47 | Format-NtToken $token -Integrity 48 | Get-NtGrantedAccess $sd -Token $token -AsString 49 | } 50 | Remove-NtSecurityDescriptorIntegrityLevel $sd 51 | Use-NtObject($token = Get-NtToken -Anonymous) { 52 | Get-NtGrantedAccess $sd -Token $token -AsString 53 | } 54 | 55 | 56 | # Listing 7-16 57 | $owner = Get-NtSid -KnownSid World 58 | $sd = New-NtSecurityDescriptor -Owner $owner -Group $owner -Type Mutant -EmptyDacl 59 | Get-NtGrantedAccess $sd 60 | Add-NtSecurityDescriptorAce $sd -KnownSid OwnerRights -Access ModifyState 61 | Get-NtGrantedAccess $sd 62 | 63 | # Listing 7-23 64 | $sd = New-NtSecurityDescriptor -Owner "BA" -Group "BA" -Type Mutant 65 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Access GenericAll 66 | Add-NtSecurityDescriptorAce $sd -KnownSid AllApplicationPackages -Access GenericAll 67 | Edit-NtSecurityDescriptor $sd -MapGeneric 68 | Set-NtSecurityDescriptorIntegrityLevel $sd Medium 69 | Use-NtObject($token = Get-NtToken -Duplicate -IntegrityLevel Low) { 70 | Get-NtGrantedAccess $sd -Token $token -AsString 71 | } 72 | $sid = Get-NtSid -PackageName "mandatory_access_lowbox_check" 73 | Use-NtObject($token = Get-NtToken -LowBox -PackageSid $sid) { 74 | Get-NtGrantedAccess $sd -Token $token -AsString 75 | } 76 | 77 | # Listing 7-24 78 | $sid = Get-NtSid -PackageName 'package_sid_low_il_test' 79 | $token = Get-NtToken -LowBox -PackageSid $sid 80 | $sd = New-NtSecurityDescriptor -Token $token -Type Mutant 81 | Format-NtSecurityDescriptor $sd -Summary -SecurityInformation Dacl, Label 82 | Get-NtGrantedAccess $sd -Token $token -AsString 83 | $token.Close() 84 | $low_token = Get-NtToken -Duplicate -IntegrityLevel Low 85 | Get-NtGrantedAccess $sd -Token $low_token -AsString 86 | $low_token.Close() 87 | 88 | # Listing 7-26 89 | $owner = Get-NtSid -KnownSid LocalSystem 90 | $sd = New-NtSecurityDescriptor -Owner $owner -Group $owner -Type Mutant 91 | Add-NtSecurityDescriptorAce $sd -KnownSid Self -Access GenericAll -MapGeneric 92 | Get-NtGrantedAccess $sd -AsString 93 | $principal = Get-NtSid 94 | Get-NtGrantedAccess $sd -Principal $principal -AsString 95 | 96 | # Listing 7-29 97 | $tree = New-ObjectTypeTree (New-Guid) -Name "Object" 98 | $set_1 = Add-ObjectTypeTree $tree (New-Guid) -Name "Property Set 1" -PassThru 99 | $set_2 = Add-ObjectTypeTree $tree (New-Guid) -Name "Property Set 2" -PassThru 100 | Add-ObjectTypeTree $set_1 (New-Guid) -Name "Property X" 101 | Add-ObjectTypeTree $set_1 (New-Guid) -Name "Property Y" 102 | $prop_z = New-Guid 103 | Add-ObjectTypeTree $set_2 $prop_z -Name "Property Z" 104 | $owner = Get-NtSid -KnownSid LocalSystem 105 | $sd = New-NtSecurityDescriptor -Owner $owner -Group $owner -Type Mutant 106 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Access WriteOwner -MapGeneric -Type DeniedObject -ObjectType $prop_z 107 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Access ReadControl, WriteOwner -MapGeneric 108 | Edit-NtSecurityDescriptor $sd -CanonicalizeDacl 109 | Get-NtGrantedAccess $sd -PassResult -ObjectType $tree -Access ReadControl, WriteOwner | Format-Table Status, SpecificGrantedAccess, Name 110 | Get-NtGrantedAccess $sd -PassResult -ResultList -ObjectType $tree -Access ReadControl, WriteOwner | Format-Table Status, SpecificGrantedAccess, Name 111 | 112 | # Listing 7-30 113 | Get-CentralAccessPolicy 114 | $rules = Get-CentralAccessPolicy | Select-Object -ExpandProperty Rules 115 | $rules | Format-Table 116 | $sd = $rules[0].SecurityDescriptor 117 | Format-NtSecurityDescriptor $sd -Type File -SecurityInformation Dacl 118 | 119 | # Listing 7-33 120 | Import-Module ".\chapter_7_access_check_impl.psm1" -Force 121 | $sd = New-NtSecurityDescriptor "O:SYG:SYD:(A;;GR;;;WD)" -Type File -MapGeneric 122 | $type = Get-NtType File 123 | $desired_access = Get-NtAccessMask -FileAccess GenericRead -MapGenericRights 124 | Get-PSGrantedAccess -SecurityDescriptor $sd -GenericMapping $type.GenericMapping -DesiredAccess $desired_access 125 | $desired_access = Get-NtAccessMask -FileAccess WriteOwner 126 | Get-PSGrantedAccess -SecurityDescriptor $sd -GenericMapping $type.GenericMapping -DesiredAccess $desired_access 127 | $token = Get-NtToken -Linked 128 | Enable-NtTokenPrivilege -Token $token SeTakeOwnershipPrivilege 129 | Get-PSGrantedAccess -Token $token -SecurityDescriptor $sd -GenericMapping $type.GenericMapping -DesiredAccess $desired_access 130 | $token.Close() 131 | 132 | # Listing 7-34 133 | function Get-NameAndGrantedAccess { 134 | [CmdletBinding()] 135 | param( 136 | [parameter(Mandatory, ValueFromPipeline)] 137 | $Entry, 138 | [parameter(Mandatory)] 139 | $Root 140 | ) 141 | PROCESS { 142 | $sd = Get-NtSecurityDescriptor -Path $Entry.Name -Root $Root -TypeName $Entry.NtTypeName -ErrorAction SilentlyContinue 143 | if ($null -ne $sd) { 144 | $granted_access = Get-NtGrantedAccess -SecurityDescriptor $sd 145 | if (!(Test-NtAccessMask $granted_access -Empty)) { 146 | $props = @{ 147 | Name = $Entry.Name; 148 | NtTypeName = $Entry.NtTypeName 149 | GrantedAccess = $granted_access 150 | } 151 | New-Object -TypeName PSObject -Prop $props 152 | } 153 | } 154 | } 155 | } 156 | Use-NtObject($dir = Get-NtDirectory \BaseNamedObjects) { 157 | Get-NtDirectoryEntry $dir | Get-NameAndGrantedAccess -Root $dir 158 | } -------------------------------------------------------------------------------- /chapter_7/listing_7_14.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | $owner = Get-NtSid -KnownSid Null 3 | $sd = New-NtSecurityDescriptor -Type Mutant -Owner $owner -Group $owner -EmptyDacl 4 | Enable-NtTokenPrivilege SeTakeOwnershipPrivilege 5 | Get-NtGrantedAccess $sd -Access WriteOwner -PassResult 6 | Disable-NtTokenPrivilege SeTakeOwnershipPrivilege 7 | Get-NtGrantedAccess $sd -Access WriteOwner -PassResult -------------------------------------------------------------------------------- /chapter_7/listing_7_32.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | # Listing 7-32 3 | $sd = New-NtSecurityDescriptor 4 | $attr = New-NtSecurityAttribute "EnableSecure" -LongValue 1 5 | Add-NtSecurityDescriptorAce $sd -Type ResourceAttribute -Sid "WD" -SecurityAttribute $attr -Flags ObjectInherit, ContainerInherit 6 | $capid = "S-1-17-3260955821-1180564752-1365479606-2616254494" 7 | Add-NtSecurityDescriptorAce $sd -Type ScopedPolicyId -Sid $capid -Flags ObjectInherit, ContainerInherit 8 | Format-NtSecurityDescriptor $sd -SecurityInformation Attribute, Scope 9 | Enable-NtTokenPrivilege SeSecurityPrivilege 10 | Set-Win32SecurityDescriptor $sd MACHINE\SOFTWARE\PROTECTED -Type RegistryKey -SecurityInformation Scope, Attribute -------------------------------------------------------------------------------- /chapter_7/listing_7_33.ps1: -------------------------------------------------------------------------------- 1 | # Listing 7-33 2 | Import-Module ".\chapter_7_access_check_impl.psm1" -Force 3 | $sd = New-NtSecurityDescriptor "O:SYG:SYD:(A;;GR;;;WD)" -Type File -MapGeneric 4 | $type = Get-NtType File 5 | $desired_access = Get-NtAccessMask -FileAccess GenericRead -MapGenericRights 6 | Get-PSGrantedAccess -SecurityDescriptor $sd -GenericMapping $type.GenericMapping -DesiredAccess $desired_access 7 | $desired_access = Get-NtAccessMask -FileAccess WriteOwner 8 | Get-PSGrantedAccess -SecurityDescriptor $sd -GenericMapping $type.GenericMapping -DesiredAccess $desired_access 9 | $token = Get-NtToken -Linked 10 | Enable-NtTokenPrivilege -Token $token SeTakeOwnershipPrivilege 11 | Get-PSGrantedAccess -Token $token -SecurityDescriptor $sd -GenericMapping $type.GenericMapping -DesiredAccess 0x80000 -------------------------------------------------------------------------------- /chapter_8/chapter_8_listings.ps1: -------------------------------------------------------------------------------- 1 | # Listing 8-1 2 | $path = "\BaseNamedObjects\ABC\QRS\XYZ\OBJ" 3 | $os = New-NtMutant $path -CreateDirectories 4 | Enable-NtTokenPrivilege SeChangeNotifyPrivilege 5 | Test-NtObject $path 6 | $sd = New-NtSecurityDescriptor -EmptyDacl 7 | Set-NtSecurityDescriptor "\BaseNamedObjects\ABC\QRS" $sd Dacl 8 | Test-NtObject $path 9 | Disable-NtTokenPrivilege SeChangeNotifyPrivilege 10 | Test-NtObject $path 11 | Test-NtObject "OBJ" -Root $os[1] 12 | $os.Close() 13 | 14 | # Listing 8-2 15 | function Get-FastTraverseCheck { 16 | Param( 17 | $TokenFlags, 18 | $SecurityDescriptor, 19 | $AccessMask 20 | ) 21 | if ($SecurityDescriptor.DaclNull) { 22 | return $true 23 | } 24 | if (($TokenFlags -band "IsFiltered, IsRestricted") -ne 0) { 25 | return $false 26 | } 27 | $sid = Get-Ntsid -KnownSid World 28 | foreach($ace in $SecurityDescriptor.Dacl) { 29 | if ($ace.IsInheritedOnly -or !$ace.IsAccessGranted($AccessMask)) { 30 | continue 31 | } 32 | if ($ace.IsDeniedAce) { 33 | return $false 34 | } 35 | if ($ace.IsAllowedAce -and $ace.Sid -eq $sid) { 36 | return $true 37 | } 38 | } 39 | return $false 40 | } 41 | 42 | # Listing 8-3 43 | $token = Get-NtToken -Pseudo -Primary 44 | $token.Flags 45 | $token.ElevationType 46 | 47 | # Listing 8-4 48 | $sd = New-NtSecurityDescriptor -EmptyDacl 49 | $m = New-NtMutant -Access ModifyState, ReadControl -SecurityDescriptor $sd 50 | Use-NtObject($m2 = Copy-NtObject -Object $m) { 51 | $m2.GrantedAccess 52 | } 53 | $mask = Get-NtAccessMask -MutantAccess ModifyState 54 | Use-NtObject($m2 = Copy-NtObject -Object $m -DesiredAccessMask $mask) { 55 | $m2.GrantedAccess 56 | } 57 | Use-NtObject($m2 = Copy-NtObject -Object $m -DesiredAccess GenericAll) { 58 | $m2.GrantedAccess 59 | } 60 | $m.Close() 61 | 62 | # Listing 8-5 63 | $m = New-NtMutant -Access ModifyState 64 | Use-NtObject($m2 = Copy-NtObject -Object $m -DesiredAccess GenericAll) { 65 | $m2.GrantedAccess 66 | } 67 | Use-NtObject($m2 = Copy-NtObject -Object $m -NoRightsUpgrade) { 68 | Use-NtObject($m3 = Copy-NtObject -Object $m2 -DesiredAccess GenericAll) {} 69 | } 70 | $m.Close() 71 | 72 | # Listing 8-6 73 | $type = New-NtType -Name "Sandbox" -GenericRead 0x20000 -GenericAll 0x1F0001 74 | $sd = New-NtSecurityDescriptor -NullDacl -Owner "SY" -Group "SY" -Type $type 75 | Set-NtSecurityDescriptorIntegrityLevel $sd Medium -Policy NoReadUp 76 | Get-NtGrantedAccess -SecurityDescriptor $sd -Access 0x20000 -PassResult 77 | Use-NtObject($token = Get-NtToken -Duplicate -IntegrityLevel Low) { 78 | Get-NtGrantedAccess -SecurityDescriptor $sd -Access 0x20000 -Token $token -PassResult 79 | } 80 | 81 | # Listing 8-7 82 | Invoke-NtToken -Current -IntegrityLevel Low { 83 | Get-NtHandle -ProcessId $pid 84 | } 85 | 86 | # Listing 8-8 87 | Use-NtObject($token = Get-NtToken) { 88 | $token.IsSandbox 89 | } 90 | 91 | Use-NtObject($token = Get-NtToken -Duplicate -IntegrityLevel Low) { 92 | $token.IsSandbox 93 | } 94 | 95 | # Listing 8-9 96 | Use-NtObject($ps = Get-NtProcess -FilterScript {$_.IsSandboxToken}) { 97 | $ps | ForEach-Object { Write-Host "$($_.ProcessId) $($_.Name)" } 98 | } 99 | 100 | # Listing 8-10 101 | Get-Command Get-Accessible* | Format-Wide 102 | 103 | # Listing 8-11 104 | Get-AccessibleObject -Path "\" 105 | 106 | # Listing 8-12 107 | Get-AccessibleObject -Path \ | Format-NtSecurityDescriptor -Summary 108 | 109 | # Listing 8-13 110 | Get-AccessibleObject -Path "\" -Recurse 111 | 112 | # Listing 8-14 113 | $key = Get-NtKey HKLM\Software -Win32Path -Access ReadControl 114 | Get-NtGrantedAccess -Object $key 115 | $key.Close() 116 | 117 | # Listing 8-15 118 | $access = Get-NtAccessMask -SectionAccess MapWrite -AsGenericAccess 119 | $objs = Use-NtObject($token = Get-NtToken -Duplicate -IntegrityLevel Low) { 120 | Get-AccessibleObject -Win32Path "\" -Recurse -Token $token -TypeFilter Section -Access $access 121 | } 122 | 123 | $objs | ForEach-Object { 124 | Use-NtObject($sect = Get-NtSection -Path $_.Name) { 125 | Use-NtObject($map = Add-NtSection $sect -Protection ReadWrite -ViewSize 4096) { 126 | Write-Host "$($sect.FullPath)" 127 | Out-HexDump -ShowHeader -ShowAscii -HideRepeating -Buffer $map | Out-Host 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /chapter_9/chapter_9_listings.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | # Listing 9-1 4 | Get-NtAuditPolicy 5 | 6 | # Listing 9-2 7 | Get-NtAuditPolicy | Select-Object Name, Id 8 | 9 | # Listing 9-3 10 | Get-NtAuditPolicy -Category System -ExpandCategory 11 | 12 | # Listing 9-4 13 | Enable-NtTokenPrivilege SeSecurityPrivilege 14 | Set-NtAuditPolicy -Category ObjectAccess -Policy Success, Failure -PassThru 15 | 16 | Set-NtAuditPolicy -Category ObjectAccess -Policy None 17 | 18 | # Listing 9-5 19 | Enable-NtTokenPrivilege SeSecurityPrivilege 20 | $sid = Get-NtSid 21 | Set-NtAuditPolicy -Category ObjectAccess -User $sid -UserPolicy SuccessExclude 22 | Get-NtAuditPolicy -User $sid -Category ObjectAccess -ExpandCategory 23 | 24 | Set-NtAuditPolicy -Category ObjectAccess -User $sid -UserPolicy None 25 | 26 | # Listing 9-6 27 | Get-NtAuditPolicy -AllUser 28 | 29 | # Listing 9-7 30 | Enable-NtTokenPrivilege SeSecurityPrivilege 31 | $sd = Get-NtAuditSecurity 32 | Format-NtSecurityDescriptor $sd -Summary -MapGeneric 33 | 34 | # Listing 9-8 35 | Enable-NtTokenPrivilege SeSecurityPrivilege 36 | $sd = Get-NtAuditSecurity 37 | Add-NtSecurityDescriptorAce $sd -Sid "LA" -Access GenericAll 38 | Set-NtAuditSecurity $sd 39 | 40 | # Listing 9-9 41 | $sd = New-NtSecurityDescriptor -Type Mutant 42 | Add-NtSecurityDescriptorAce $sd -Type Audit -Access GenericAll -Flags SuccessfulAccess, FailedAccess -KnownSid World -MapGeneric 43 | Enable-NtTokenPrivilege SeSecurityPrivilege 44 | Clear-EventLog -LogName "Security" 45 | Use-NtObject($m = New-NtMutant "ABC" -Win32Path -SecurityDescriptor $sd) { 46 | Use-NtObject($m2 = Get-NtMutant "ABC" -Win32Path) { 47 | } 48 | } 49 | 50 | # Listing 9-10 51 | $filter = @{logname = 'Security'; id = @(4656)} 52 | Get-WinEvent -FilterHashtable $filter | Select-Object -ExpandProperty Message 53 | 54 | # Listing 9-11 55 | Get-WinEvent -FilterHashtable $filter | Select-Object KeywordsDisplayNames 56 | 57 | # Listing 9-12 58 | $filter = @{logname = 'Security'; id = @(4658)} 59 | Get-WinEvent -FilterHashtable $filter | Select-Object -ExpandProperty Message 60 | 61 | # Listing 9-13 62 | Enable-NtTokenPrivilege SeAuditPrivilege -WarningAction Stop 63 | $owner = Get-NtSid -KnownSid Null 64 | $sd = New-NtSecurityDescriptor -Type Mutant -Owner $owner -Group $owner 65 | Add-NtSecurityDescriptorAce $sd -KnownSid World -Access GenericAll -MapGeneric 66 | Add-NtSecurityDescriptorAce $sd -Type Audit -Access GenericAll -Flags SuccessfulAccess, FailedAccess -KnownSid World -MapGeneric 67 | $handle = 0x1234 68 | $r = Get-NtGrantedAccess $sd -Audit -SubsystemName "SuperSecurity" -ObjectTypeName "Badger" -ObjectName "ABC" -ObjectCreation -HandleId $handle -PassResult 69 | Write-NtAudit -Close -SubsystemName "SuperSecurity" -HandleId $handle -GenerateOnClose:$r.GenerateOnClose 70 | 71 | # Listing 9-14 72 | Enable-NtTokenPrivilege SeSecurityPrivilege 73 | $sd = New-NtSecurityDescriptor -Type File 74 | Add-NtSecurityDescriptorAce $sd -Type Audit -KnownSid World -Access WriteData -Flags SuccessfulAccess 75 | Set-NtAuditSecurity -GlobalSacl File -SecurityDescriptor $sd 76 | Get-NtAuditSecurity -GlobalSacl File | Format-NtSecurityDescriptor -SecurityInformation Sacl -Summary 77 | 78 | # Listing 9-15 79 | Enable-NtTokenPrivilege SeSecurityPrivilege 80 | $sd = Get-NtAuditSecurity 81 | Set-NtSecurityDescriptorOwner $sd -KnownSid LocalSystem 82 | Set-NtSecurityDescriptorGroup $sd -KnownSid LocalSystem 83 | Get-NtGrantedAccess $sd -PassResult 84 | Use-NtObject($token = Get-NtToken -Filtered -Flags LuaToken) { 85 | Get-NtGrantedAccess $sd -Token $token -PassResult 86 | } 87 | 88 | # Listing 9-16 89 | Enable-NtTokenPrivilege SeDebugPrivilege, SeSecurityPrivilege 90 | $ps = Get-NtProcess -Access QueryLimitedInformation, AccessSystemSecurity -FilterScript { 91 | $sd = Get-NtSecurityDescriptor $_ -SecurityInformation Sacl 92 | $sd.HasAuditAce 93 | } 94 | $ps | Format-NtSecurityDescriptor -SecurityInformation Sacl 95 | $ps.Close() --------------------------------------------------------------------------------