Open WDavid404 opened 9 months ago
AD enumeration relies on LDAP. When a domain machine searches for an object, like a printer, or when we query user or group objects, LDAP is used as the communication channel for the query. In other words, LDAP is the protocol used to communicate with Active Directory. LDAP communication with AD is not always straight-forward, but we'll leverage an Active Directory Services Interface (ADSI)(a set of interfaces built on COM) as an LDAP provider.
According to Microsoft's documentation, we need a specific LDAP ADsPath in order to communicate with the AD service. The LDAP path's prototype looks like this:
LDAP://HostName[:PortNumber][/DistinguishedName]
We need three parameters for a full LDAP path:
In fact, to make our enumeration as accurate as possible, we should look for the DC that holds the most updated information. This is known as the Primary Domain Controller (PDC).
In the Microsoft .NET classes related to AD: System.DirectoryServices.ActiveDirectory namespace.
Get domain object for the current user,
PS C:\Users\stephanie> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
Forest : corp.com
DomainControllers : {DC1.corp.com}
Children : {}
DomainMode : Unknown
DomainModeLevel : 7
Parent :
PdcRoleOwner : DC1.corp.com <---- We need it
RidRoleOwner : DC1.corp.com
InfrastructureRoleOwner : DC1.corp.com
Name : corp.com
We can use ADSI directly in PowerShell to retrieve the DN.
PS C:\Users\stephanie> ([adsi]'').distinguishedName
DC=corp,DC=com
Made a new script
$PDC = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$LDAP
$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$PDC = $domainObj.PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="samAccountType=805306368"
$result = $dirsearcher.FindAll()
Foreach($obj in $result)
{
Foreach($prop in $obj.Properties)
{
$prop
}
Write-Host "-------------------------------"
}
case2:
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="name=jeffadmin" <----!!
$result = $dirsearcher.FindAll()
Foreach($obj in $result)
{
Foreach($prop in $obj.Properties)
{
$prop.memberof <----!!
}
Write-Host "-------------------------------"
}
made a function
function LDAPSearch {
param (
[string]$LDAPQuery
)
$PDC = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DistinguishedName = ([adsi]'').distinguishedName
$DirectoryEntry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$PDC/$DistinguishedName")
$DirectorySearcher = New-Object System.DirectoryServices.DirectorySearcher($DirectoryEntry, $LDAPQuery)
return $DirectorySearcher.FindAll()
}
To use the function, let's import it to memory:
PS C:\Users\stephanie> powershell -ep bypass
PS C:\Users\stephanie> Import-Module .\function.ps1
case3. LDAPSearch command
PS C:\Users\stephanie> LDAPSearch -LDAPQuery "(samAccountType=805306368)"
PS C:\Users\stephanie> LDAPSearch -LDAPQuery "(objectclass=group)"
case4
PS C:\Users\stephanie\Desktop> foreach ($group in $(LDAPSearch -LDAPQuery "(objectCategory=group)")) {
>> $group.properties | select {$_.cn}, {$_.member}
>> }
PS C:\Users\stephanie> $group = LDAPSearch -LDAPQuery "(&(objectCategory=group)(cn=Development Department*))"
PS C:\Users\stephanie> $group.properties.member
CN=Management Department,DC=corp,DC=com
CN=pete,CN=Users,DC=corp,DC=com
CN=dave,CN=Users,DC=corp,DC=com
PS C:\Users\stephanie\Desktop> $group = LDAPSearch -LDAPQuery "(&(objectCategory=group)(cn=Management Department*))"
PS C:\Users\stephanie\Desktop> $group.properties.member
CN=jen,CN=Users,DC=corp,DC=com
PS C:\Users\stephanie> powershell -ep bypass
PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Get-NetDomain
PS C:\Tools> Get-NetUser
PS C:\Tools> Get-NetUser | select cn
PS C:\Tools> Get-NetUser | select cn,pwdlastset,lastlogon
==> if a user hasn't changed their password since a recent password policy change,
their password may be weaker than the current policy.
This might make it more vulnerable to password attacks.
PS C:\Tools> Get-NetGroup | select cn
PS C:\Tools> Get-NetGroup "Sales Department" | select member
Get-NetComputer PowerView command
PS C:\Users\stephanie> powershell -ep bypass
PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Get-NetComputer
PS C:\Tools> Get-NetComputer | select operatingsystem,dnshostname
Let's run Find-LocalAdminAccess against corp.com. While the command supports parameters such as Computername and Credentials, we will run it without parameters in this case since we are interested in enumerating all computers, and we are already logged in as stephanie.
PS C:\Users\stephanie> powershell -ep bypass
PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Find-LocalAdminAccess
client74.corp.com
This reveals that stephanie has administrative privileges on CLIENT74.
Checking logged on users with Get-NetSession
PS C:\Tools> Get-NetSession -ComputerName files04 -Verbose
PS C:\Tools> Get-NetSession -ComputerName web04 -Verbose
PS C:\Tools> Get-NetSession -ComputerName client74
CName : \\192.168.50.75
UserName : stephanie
Time : 8
IdleTime : 0
ComputerName : client74
The permissions required to enumerate sessions with NetSessionEnum are defined in the SrvsvcSessionInfo
registry key,
which is located in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity
hive.
PS C:\Tools> Get-Acl -Path HKLM:SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity\ | fl
To get the operating system versions in use
PS C:\Tools> Get-NetComputer | select dnshostname,operatingsystem,operatingsystemversion
PsLoggedOn will enumerate the registry keys under HKEY_USERS to retrieve the security identifiers (SID) of logged-in users and convert the SIDs to usernames. PsLoggedOn will also use the NetSessionEnum API to see who is logged on to the computer via resource shares. One limitation, however, is that PsLoggedOn relies on the Remote Registry service in order to scan the associated key. The Remote Registry service has not been enabled by default on Windows workstations since Windows 8, but system administrators may enable it for various administrative tasks, for backwards compatibility, or for installing monitoring/deployment tools, scripts, agents, etc.
PS C:\Tools\PSTools> .\PsLoggedon.exe \\files04
PS C:\Tools\PSTools> .\PsLoggedon.exe \\client74
PsLoggedon v1.35 - See who's logged on
Copyright (C) 2000-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
Users logged on locally:
<unknown time> CORP\jeffadmin
Users logged on via resource shares:
10/5/2022 1:33:32 AM CORP\stephanie
If a user launches an application, that user account defines the context. However, services launched by the system itself run in the context of a Service Account.
In other words, isolated applications can use a set of predefined service accounts, such as LocalSystem, LocalService, and NetworkService.
When applications like Exchange, MS SQL, or Internet Information Services (IIS) are integrated into AD, a unique service instance identifier known as Service Principal Name (SPN) associates a service to a specific service account in Active Directory.
Method1. Use setpspn.exe
c:\Tools>setspn -L iis_service
Registered ServicePrincipalNames for CN=iis_service,CN=Users,DC=corp,DC=com:
HTTP/web04.corp.com
HTTP/web04
HTTP/web04.corp.com:80
Method2. use PowerView.exe
PS C:\Tools> Get-NetUser -SPN | select samaccountname,serviceprincipalname
samaccountname serviceprincipalname
-------------- --------------------
krbtgt kadmin/changepw
iis_service {HTTP/web04.corp.com, HTTP/web04, HTTP/web04.corp.com:80}
Let's attempt to resolve web04.corp.com with nslookup:
PS C:\Tools\> nslookup.exe web04.corp.com
Server: UnKnown
Address: 192.168.50.70
Name: web04.corp.com
Address: 192.168.50.72
In short, an object in AD may have a set of permissions applied to it with multiple Access Control Entries (ACE). These ACEs make up the Access Control List (ACL). Each ACE defines whether access to the specific object is allowed or denied.
AD permission types
Use Get-ObjectAcl to enumerate ACEs with PowerView.
PS C:\Users\stephanie> powershell -ep bypass
PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Get-ObjectAcl -Identity stephanie
...
ObjectDN : CN=stephanie,CN=Users,DC=corp,DC=com
ObjectSID : S-1-5-21-1987370270-658905905-1781884369-1104 <-- Note!
ActiveDirectoryRights : ReadProperty --> The ActiveDirectoryRights property describes the type of permission applied to the object.
ObjectAceFlags : ObjectAceTypePresent
ObjectAceType : 4c164200-20c0-11d0-a768-00aa006e0529
InheritedObjectAceType : 00000000-0000-0000-0000-000000000000
BinaryLength : 56
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 16
SecurityIdentifier : S-1-5-21-1987370270-658905905-1781884369-553 <-- Note!
AceType : AccessAllowedObject
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None
...
The output lists two Security Identifiers (SID), unique values that represent an object in AD. The first (located in the highlighted ObjectSID property) contains the value "S-1-5-21-1987370270-658905905-1781884369-1104", which is rather difficult to read. In order to make sense of the SID, we can use PowerView's Convert-SidToName command to convert it to an actual domain object name:
PS C:\Tools> Convert-SidToName S-1-5-21-1987370270-658905905-1781884369-1104
CORP\stephanie
Also convert the SecurityIdentifier value.
PS C:\Tools> Convert-SidToName S-1-5-21-1987370270-658905905-1781884369-553
CORP\RAS and IAS Servers --> default AD group named RAS and IAS Servers
let's start with the Management Department group for now. We will check if any users have GenericAll permissions. We use the PowerShell -eq flag to filter the ActiveDirectoryRights property, only displaying the values that equal GenericAll.
PS C:\Tools> Get-ObjectAcl -Identity "Management Department" | ? {$_.ActiveDirectoryRights -eq "GenericAll"} | select SecurityIdentifier,ActiveDirectoryRights
SecurityIdentifier ActiveDirectoryRights
------------------ ---------------------
S-1-5-21-1987370270-658905905-1781884369-512 GenericAll
S-1-5-21-1987370270-658905905-1781884369-1104 GenericAll
S-1-5-32-548 GenericAll
S-1-5-18 GenericAll
S-1-5-21-1987370270-658905905-1781884369-519 GenericAll
let's convert all the SIDs into actual names:
PS C:\Tools> "S-1-5-21-1987370270-658905905-1781884369-512","S-1-5-21-1987370270-658905905-1781884369-1104","S-1-5-32-548","S-1-5-18","S-1-5-21-1987370270-658905905-1781884369-519" | Convert-SidToName
CORP\Domain Admins
CORP\stephanie <--- interesting!
BUILTIN\Account Operators
Local System
CORP\Enterprise Admins
Add stephanie to the Management Group
PS C:\Tools> net group "Management Department" stephanie /add /domain
PS C:\Tools> Get-NetGroup "Management Department" | select member
member
------
{CN=jen,CN=Users,DC=corp,DC=com, CN=stephanie,CN=Users,DC=corp,DC=com}
remove from the group
PS C:\Tools> net group "Management Department" stephanie /del /domain
The request will be processed at a domain controller for domain corp.com.
The command completed successfully.
net view \\web04
获得web04的共享目录一览(前提是当前user拥有访问web04的权限)use PowerView's Find-DomainShare function to find the shares in the domain.
PS C:\Users\stephanie> powershell -ep bypass
PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Find-DomainShare
By default, the SYSVOL folder is mapped to %SystemRoot%\SYSVOL\Sysvol\domain-name on the domain controller and every domain user has access to it.
PS C:\Tools> ls \\dc1.corp.com\sysvol\corp.com\
Directory: \\dc1.corp.com\sysvol\corp.com
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/21/2022 1:11 AM Policies
d----- 9/2/2022 4:08 PM scripts
PS C:\Tools> ls \\FILES04\docshare
Directory: \\FILES04\docshare
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/21/2022 2:02 AM docs
在Policies和ShareDoc目录下可以找到一些有用的信息
Historically, system administrators often changed local workstation passwords through Group Policy Preferences (GPP). However, even though GPP-stored passwords are encrypted with AES-256, the private key for the encryption has been posted on MSDN.We can use this key to decrypt these encrypted passwords. In this case, we'll use the gpp-decrypt ruby script in Kali Linux that decrypts a given GPP encrypted string:
kali@kali:~$ gpp-decrypt "+bsY0V3d4/KgX3VJdO/vyepPfAN1zMFTiQDApgR92JE"
P@$$w0rd
https://github.com/WDavid404/Note_tryhackme/issues/1#issuecomment-1742077725
net user robert Password123! /domain
runas /user:robert@corp.com cmd
Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Users\robert\Desktop\ -OutputPrefix "audit2"
Get-ObjectAcl | ? {$_.ActiveDirectoryRights -contains 'GenericAll' -and $_.SecurityIdentifier -eq 'S-1-5-21-1987370270-658905905-1781884369-1104'}
net user robert Password1@
//for local user
net user robert Password123! /domain
//for domain user
麻烦问下您使用的sharphound和bloodhound是哪个版本的,我这导出来一直缺一些路径。
Sharphound用的是offsec lab里自带的, Bloodhound在Kali里用的是4.3.1
21.2. Active Directory - Manual Enumeration
21.2.1. Active Directory - Enumeration Using Legacy Windows Tools
Login
kali@kali:~$ xfreerdp /u:stephanie /d:corp.com /v:192.168.50.75
Legacy enumeration tool