├── ADInsight.ps1 └── README.md /ADInsight.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Shahzeb Haider 2 | # All rights reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE. 21 | 22 | Write-Output "ADInsight is being loaded.." 23 | 24 | # Downloaded files original source: https://github.com/samratashok/ADModule/blob/master/Import-ActiveDirectory.ps1 25 | 26 | Invoke-WebRequest -Uri "https://raw.githubusercontent.com/alpha-08/ADEnum/master/admod.ps1" -OutFile "admod.ps1" 27 | Invoke-WebRequest -Uri "https://raw.githubusercontent.com/alpha-08/ADEnum/master/Microsoft.ActiveDirectory.Management.dll" -OutFile "Microsoft.ActiveDirectory.Management.dll" 28 | 29 | 30 | Write-Output " " 31 | Write-Output "Status: 200 OK" 32 | 33 | # Dot-source the PowerShell script if it's a script file, not a module 34 | # if you're importing a module manually, use command 'import-module -Name 35 | 36 | . .\admod.ps1 37 | 38 | # Load the DLL 39 | Add-Type -Path .\Microsoft.ActiveDirectory.Management.dll 40 | 41 | Write-Output " " 42 | Write-Output "Status: 200 OK" 43 | Write-Output "" 44 | 45 | function Write-Bold { 46 | param ( 47 | [string]$text 48 | ) 49 | Write-Host $text -ForegroundColor Yellow 50 | } 51 | 52 | 53 | # Start the while loop 54 | while ($true) { 55 | 56 | Write-Output "-------------------------------------------------------------------------------------------------------" 57 | 58 | Write-Bold "1. Forest Info" 59 | Write-Bold "2. Domain Controller Info" 60 | Write-Bold "3. Groups Info" 61 | Write-Bold "4. Group Members Info" 62 | Write-Bold "5. Kerberoastable Accounts" 63 | Write-Bold "6. ASReproastable Accounts" 64 | Write-Bold "7. All Computer Accounts Info" 65 | Write-Bold "8. All User Accounts Info" 66 | Write-Bold "9. All available Windows Servers Info" 67 | Write-Bold "10. All Users/Groups protected by AdminSDHolder" 68 | Write-Output " Ctrl+C to exit" 69 | 70 | # Prompt user for input 71 | Write-Output " " 72 | Write-Bold "Select Option" 73 | $userInput = Read-Host -Prompt ">" 74 | Write-Output " " 75 | # Process user input 76 | switch ($userInput) { 77 | 78 | 79 | '1' { 80 | 81 | Write-Bold "Enter Forest name OR press Enter to go with the default info" 82 | $condition=Read-Host -Prompt ">" 83 | if ([string]::IsNullOrEmpty($condition)){ 84 | 85 | $defaultForestInfo=Get-ADForest 86 | Write-Output $defaultForestInfo 87 | 88 | } else { 89 | 90 | # $getForestName = Read-Host -Prompt "Forest Name" 91 | 92 | try { 93 | $ForestName=Get-ADForest -Identity $condition 94 | Write-Output $ForestName 95 | } catch { 96 | Write-Host "Error: Unable to retrieve forest information for $condition" -ForegroundColor Red 97 | } 98 | } 99 | } 100 | '2' { 101 | 102 | Write-Bold "Enter Domain Controller IP address OR press Enter to go with the default info" 103 | Read-Host -Prompt ">" 104 | Write-Host " " 105 | Write-Output "Fetching Domain Controller Info..." 106 | Write-Host " " 107 | $domainControllers = Get-ADDomainController 108 | Write-Output $domainControllers 109 | } 110 | '3' { 111 | Write-Output "Fetching AD Group Info..." 112 | $adGroups = Get-ADGroup -Filter * 113 | Write-Output $adGroups > adgroups.txt 114 | Write-Output "adgroups info saved to disk as 'adgroups.txt'" 115 | } 116 | '4' { 117 | Write-Output "Fetching AD Group Members Info..." 118 | $groupName = Read-Host -Prompt "Enter the group name" 119 | $groupMembers = Get-ADGroupMember -Identity $groupName 120 | Write-Output $groupMembers 121 | } 122 | '5' { 123 | Write-Bold "For details press 'd' or press Enter to go with only account names" 124 | $condition=Read-Host -Prompt ">" 125 | 126 | Write-Output " " 127 | 128 | if ($condition -eq 'd') { 129 | Write-Output "Fetching users that're associated with any SPN" 130 | $spnAccounts=Get-ADUser -Filter {ServicePrincipalName -ne "null"} -Properties * 131 | Write-Output $spnAccounts 132 | } else { 133 | $spnAccountNames=Get-ADUser -Filter {ServicePrincipalName -ne "null"} -Properties ServicePrincipalName | select SamAccountName,Name 134 | Write-Output $spnAccountNames 135 | } 136 | 137 | Write-Output " " 138 | Write-Output "Note: Kerberoasting targets service accounts that have Service Principal Names (SPNs) associated with them and very helpful in lateral movements within the network once an attacker gets initial access. If you cannot disable SPN with any user due to work requirements, make the password long and complex so that the password cannot be break with hashcat or other cracking tools" 139 | Write-Output "Vulnerability: Service accounts with weak passwords are susceptible to Kerberoasting because their service tickets can be cracked relatively easily." 140 | Write-Output "Tools: Rubeus and Impacket can be used to perform Kerberoasting attacks" 141 | 142 | Write-Output " " 143 | } 144 | '6' { 145 | 146 | Write-Output "Note: ASREPRoasting targets user accounts that have the property 'Do not require Kerberos preauthentication' enabled. To get more info, visit: https://medium.com/@haidershahzeb08/as-rep-roasting-74a958b1bedf" 147 | Write-Output "User accounts without preauthentication enabled and with weak passwords are susceptible because their AS-REP responses can be cracked relatively easily" 148 | Write-Output "Tools: Rubeus and Impacket can be used to perform ASREPRoasting attacks." 149 | Write-Output "Fetching ASReprostable Accounts Info..." 150 | $ASreproastable = Get-ADUser -Filter * -Properties DoesNotRequirePreAuth | Where-Object { $_.DoesNotRequirePreAuth -eq $true} 151 | Write-Output $ASreproastable 152 | } 153 | '7' { 154 | Write-Bold "Press 'd' for detailed info about all computers or Enter specific computer Name" 155 | $compAccCondition=Read-Host -Prompt ">" 156 | 157 | Write-Output " " 158 | 159 | if ($compAccCondition -eq 'd') { 160 | Write-Output "Fetching detailed information about all computer accounts" 161 | $computerAccounts=Get-ADComputer -Filter * -Properties * 162 | Write-Output $computerAccounts > allCompAccounts.txt 163 | Write-Output "All computer accounts information is saved to disk as 'allCompAccounts.txt'" 164 | Write-Output " " 165 | } else { 166 | $basicInfoComps=Get-ADComputer -Filter {Name -eq $compAccCondition} -Properties * 167 | Write-Output $basicInfoComps 168 | } 169 | 170 | Write-Output " " 171 | Write-Output "Note: Put the notes here for ASReproasting" 172 | 173 | Write-Output " " 174 | } 175 | '8' { 176 | Write-Bold "For all user account details press 'd' or enter specific user name" 177 | $userAccCondition=Read-Host -Prompt ">" 178 | 179 | Write-Output " " 180 | 181 | if ($userAccCondition -eq 'd') { 182 | Write-Output "Fetching detailed information about computer accounts" 183 | $userAccounts=Get-ADUser -Filter * -Properties * 184 | Write-Output $userAccounts 185 | } else { 186 | $specificUser=Read-Host -Prompt "Enter Username" 187 | $singleUserInfo=Get-ADUser -Filter {SamAccountName -eq $specificUser} -Properties * 188 | Write-Output $singleUserInfo 189 | } 190 | 191 | Write-Output " " 192 | 193 | Write-Output " " 194 | } 195 | '9' { 196 | Write-Bold "To get a list of all Windows Servers, press 'A' or enter specific version '2008, 2012, 2016 etc" 197 | $allServers=Read-Host -Prompt ">" 198 | 199 | Write-Output " " 200 | 201 | if ($allServers -eq 'A') { 202 | Write-Bold "Fetching basic information about all available windows servers i.e., 2008, 2012, 2016 etc" 203 | $winServersList=Get-ADComputer -Filter * -Properties * | select SamAccountName, IPv4Address, OperatingSystem | Select-String "Windows Server" 204 | Write-Output $winServersList 205 | } 206 | elseif ($allServers -eq '2008') { 207 | Write-Output "Searching ... Please wait.." 208 | Write-Output " " 209 | $server2008=Get-ADComputer -Filter * -Properties * | select Name, IPv4Address, OperatingSystem | Select-String "Windows Server 2008" 210 | Write-Output $server2008 -Verbose 211 | } 212 | 213 | elseif ($allServers -eq '2012') { 214 | Write-Output "Searching ... Please wait.." 215 | Write-Output " " 216 | $server2012=Get-ADComputer -Filter * -Properties * | select Name, IPv4Address, OperatingSystem | Select-String "Windows Server 2012" 217 | Write-Output $server2012 -Verbose 218 | } 219 | 220 | elseif ($allServers -eq '2016') { 221 | Write-Output "Searching ... Please wait.." 222 | Write-Output " " 223 | $server2016=Get-ADComputer -Filter * -Properties * | select Name, IPv4Address, OperatingSystem | Select-String "Windows Server 2016" 224 | Write-Output $server2016 -Verbose 225 | } 226 | 227 | elseif ($allServers -eq '2019') { 228 | Write-Output "Searching ... Please wait.." 229 | Write-Output " " 230 | $server2019=Get-ADComputer -Filter * -Properties * | select Name, IPv4Address, OperatingSystem | Select-String "Windows Server 2019" 231 | Write-Output $server2019 -Verbose 232 | } 233 | 234 | elseif ($allServers -eq '2022') { 235 | Write-Output "Searching ... Please wait.." 236 | Write-Output " " 237 | $server2022=Get-ADComputer -Filter * -Properties * | select Name, IPv4Address, OperatingSystem | Select-String "Windows Server 2022" 238 | Write-Output $server2022 -Verbose 239 | } 240 | 241 | Write-Output " " 242 | 243 | Write-Output " " 244 | } 245 | 246 | '10' { 247 | Write-Bold "Press 'd' for detailed info or press Enter to list only user accounts/groups" 248 | $condition=Read-Host -Prompt ">" 249 | #$condition=Read-Host -Prompt "Press 'd' for detailed info or press Enter to list only user accounts/groups" 250 | 251 | Write-Output " " 252 | 253 | if ($condition -eq 'd') { 254 | Write-Output "Fetching detailed info of all Users and Groups protected by AdminSDHolder" 255 | Write-Output " " 256 | $AllAdminSDHolder=Get-ADObject -Filter { AdminCount -eq 1 } -Properties * 257 | Write-Output $AllAdminSDHolder 258 | } else { 259 | $ShortAdminSDHolder=Get-ADObject -Filter { AdminCount -eq 1 } -Properties * | select SamAccountName, ObjectClass, MemberOf 260 | Write-Output $ShortAdminSDHolder 261 | # Write-Bold "(Note: AdminSDHolder Object is used to protect high privilege accounts.\n In case of DA is compromised, an attacker can provide full privileges to any compromised user account without adding it to the domain admin group because DA accounts are often investigated/auditd and remains undetected unle)" 262 | } 263 | 264 | Write-Output " " 265 | Write-Bold "Note" 266 | Write-Output "AdminSDHolder Object is used to protect high privilege accounts.\n In case of DA is compromised, an attacker can provide full privileges to any compromised user account without adding it to the domain admin group because DA accounts are often investigated/auditd and remains undetected unless ACLs are investigated." 267 | Write-Output "Read Article here: https://adsecurity.org/?p=1906" 268 | 269 | Write-Output " " 270 | } 271 | 272 | 273 | default { 274 | Write-Output "Invalid selection. Please enter 1, 2, 3, or 4." 275 | } 276 | } 277 | 278 | Write-Output " " 279 | } 280 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ADInsight 2 | This tool/script that can gather a lot of info without any defender alerts since it leverages the built-in windows ADModule. It is useful for Penetration testers, SOC Analysts or System administrators depends how they use it. Try it on a domain joined windows client or server with the internet connectivity. 3 | 4 | Pentesters can use it for enumeration purposes, finding Kerberoastable, AsRepRoastable accounts if they've initial access to domain joined PC 5 | 6 | SOC analyst or administrators can use since they're on defending side, to identify SPN associated service accounts, accounts with the property set "do not require Kerberos pre-authentication", to get a list of their windows servers (old/new) etc., again depends how they use it. 7 | 8 | **Example Use:** 9 | .\ADInsight.ps1 10 | 11 | ![image](https://github.com/user-attachments/assets/93f089e5-7b4f-4685-b9d7-bba58b4225ca) 12 | 13 | 14 | **Note:** Running it first time, you may need to run below command for powershell execution policy bypass before you execute the scrip. Any suggesionts/queries related to its use, don't hesitate to ask me at **linkedin.com/in/rao-shahzeb-haider-ab2393182** 15 | 16 | powershell -ep bypass 17 | 18 | ------------------------------------------------------------------------------------- 19 | # If you still found difficulty to run the ADInsight, then follow this manual process and then run ./ADInsight.ps1 20 | 21 | Step 1: powershell -ep bypass 22 | 23 | Step 2: .\ADInsight.ps1 24 | 25 | **#** step 2 will download admod.ps1 and Microsoft.ActiveDirectory.Management.dll even if it runs or not. 26 | 27 | Step 3: Import-Module .\admod.ps1 28 | 29 | Step 4: Import-ActiveDirectory -ActiveDirectoryModule .\Microsoft.ActiveDirectory.Management.dll 30 | 31 | **#** now run ADInsight.ps1 again 32 | 33 | Step5: .\ADInsight.ps1 34 | --------------------------------------------------------------------------------