WDavid404 / OSCP

0 stars 0 forks source link

21. Active Directory Introduction and Enumeration #22

Open WDavid404 opened 9 months ago

WDavid404 commented 9 months ago

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

C:\Users\stephanie>net user /domain

C:\Users\stephanie>net user jeffadmin /domain

C:\Users\stephanie>net group /domain

PS C:\Tools> net group "Sales Department" /domain
WDavid404 commented 9 months ago

21.2.2. Enumerating Active Directory using PowerShell and .NET Classes

LDAP

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
WDavid404 commented 9 months ago

21.2.3. Adding Search Functionality to our Script

$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
WDavid404 commented 9 months ago

21.2.4. AD Enumeration with PowerView

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
WDavid404 commented 9 months ago

21.3. Manual Enumeration - Expanding our Repertoire

21.3.1. Enumerating Operating Systems

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

21.3.2. Getting an Overview - Permissions and Logged on Users

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 tool

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
WDavid404 commented 9 months ago

21.3.3. Enumeration Through Service Principal Names

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.

Listing SPN linked to a certain user account

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
WDavid404 commented 9 months ago

21.3.4. Enumerating Object Permissions

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.
WDavid404 commented 9 months ago

21.3.5. Enumerating Domain Shares

补充info:可以用 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目录下可以找到一些有用的信息

关于GPP密码的破解

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
WDavid404 commented 9 months ago

21.4. Active Directory - Automated Enumeration

https://github.com/WDavid404/Note_tryhackme/issues/1#issuecomment-1742077725

WDavid404 commented 9 months ago

21.4.2 q3

  1. login client75 as stephanie and run sharphount.
  2. Ran bloodhount and found the stephanie has gericAll to Robert.
  3. change robert password net user robert Password123! /domain
  4. runas /user:robert@corp.com cmd
  5. run sharphount as robert Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Users\robert\Desktop\ -OutputPrefix "audit2"
  6. run bloodhount (clear DB and then update a new zip file)
  7. you can find that rebort has admin to client74 image
  8. RDP login to client74 as robert and find the proof file

Find any object with a GenericAll given to our current user SID

Get-ObjectAcl | ? {$_.ActiveDirectoryRights -contains 'GenericAll' -and $_.SecurityIdentifier -eq 'S-1-5-21-1987370270-658905905-1781884369-1104'}

change password for a user

net user robert Password1@ //for local user net user robert Password123! /domain //for domain user

zzx134196 commented 8 months ago

麻烦问下您使用的sharphound和bloodhound是哪个版本的,我这导出来一直缺一些路径。

WDavid404 commented 8 months ago

Sharphound用的是offsec lab里自带的, Bloodhound在Kali里用的是4.3.1