Twas a month before Haxmas and notice was sent.
“We’re looking for topics we think will accent
Our security message, or maybe some hacking.”
Surely writing blog posts is better than slacking.
A young hacker named Matthew, who just joined the team
Said “What’s my first target?” and started to beam.
Oh printers sound fun, and Tod thinks they’re neat.
So we found a nice PoC and an HP for cheap.
We tried out CVE-twenty-seven-four-one
The bind shell worked well; now we’re practically done!
But PTYs are scarce, and job control is no fun.
Somehow we must make Meterpreter run.
First we tried an ELF stager, which fit with the season,
But it just wouldn’t run, noexec was the reason!
The devs did a thing, and no one’s sure why,
Path traversal gave us a cake but no PIE.
Back to the shop, to find alternate payload.
Will Vu said he’d look, he's not one to be slowed.
BusyBox telnetd was the trick—forget netcat.
Great idea, I sighed, and we continued to chat.
With noexec mount, you must stay in memory;
Simply remember the arch command family.
Payloads! Singles! *nix, CMD!
Bind and reverse but grep no telnetd.
Bind telnetd; thus I started to hack.
Use, configure, and exploit—then wait to hear back.
Upon printer reboot, I saw a profile-sourced script.
Then a shell session opened. "Get it," I quipped.
Don't assist others by leaving a snack.
This shell is your present, let no others hack.
Will Vu's words rang as I gathered shells round
To send all my commands ‘fore the sessions unbound.
Making the Module (Minus the Meter)
Brent Cook and I made a cheerful attempt to share the story of the HP printer hack in rhymed verse and Caitlin Condon saved us. This story takes us back to the end of October 2017 when I walked into Brent’s office and noticed a brand new HP OfficeJet Pro 8210 printer sitting on the edge his desk. Brent said there was a Python PoC that had been published and that he currently had a netcat bind shell on the device. I offered to work on a Metasploit exploit module, as I have enjoyed numerous conversations about hacking printers with Deral Heiland over the past few years.
Later that afternoon and into the evening I started to identify the modules and mixins that would be needed to bring the exploit module together. Rex::Proto::PJL would provide the functionality to write the shell script that would ultimately load from /etc/profile.d on startup giving us arbitrary code execution, and Exploit::Remote::SNMPClient would provide the functionality to set the Printer MIB prtGeneralReset object to the powerCycleReset(4) value, causing the printer to restart.
I quickly assembled the crude code, a rough draft to simply test the PoC as a Metasploit module. I changed the name of the script being written to the printer not once, but twice while also using the PJL module to list the directory contents to verify that the module was successfully writing data to the printer. I would soon discover the impact of this bleary-eyed mistake as I removed my debug stops. Excited to execute the first complete test of the module and allow it to restart the printer. I typed exploit, pressed the enter key, and waited a few moments before unsuccessfully connecting to the netcat bind shell a few times. When I checked on the printer, it greeted me with a neverending progress bar. Power cycle after power cycle the printer attempted what once was simple, but multiple scripts attempting to create a netcat bind shell on the same port had turned into a Sisyphean task. The printer was bricked, which halted further testing.
A few days later Brent arrived at the office with a new printer in hand, ready to be networked and allow module development to continue—that is, until the ELF command stager provided the next hurdle. All the mounted filesystems on the printer had been mounted with the noexec option, thus preventing direct execution of the stager binary, and all subsequent attempts to remount filesystems with the exec option failed. Will Vu offered his expertise; connecting to the shell on the printer, he confirmed my findings and began to explore. He pointed out that the printer was using BusyBox and that telnetd would be preferable to the netcat bind shell. He suggested I explore development of an ARCH_CMD payload using telnetd, but he stressed that we would need to ensure the payload terminated telnetd when the user was finished with the command shell session; otherwise, the exploit would leave a persistent command shell that does not require authentication.
I ended up shelving the exploit development until the final week of the year, when I was at last able to finish development and testing. Brent offered his time and knowledge of the Metasploit codebase, and we paired up to address the command shell post-session cleanup method. The enhancement added the CommandShellCleanupCommand advanced option, which provides a method for a payload module to register a command that is run after a command shell session has ended, but before the connection is closed. The BusyBox telnetd bind TCP command shell payload
cmd/unix/bind_busybox_telnetd leverages this enhancement to send a
pkill telnetd command when the user aborts the session to successfully clean up after itself. Both the new payload and the HP Jetdirect path traversal arbitrary code execution exploit module are introduced in PR #9364.
Perhaps you were not lucky enough to receive one of the vulnerable printer models in CVE-2017-2741 as a gift this HaXmas and you do not otherwise have legitimate access to one. However, if you have a printer that accepts PJL on port 9100 and you want to send some data in its direction, I’ve included a little HaXmas surprise for you (assuming you are daring enough to pipe the output of my script through netcat to your printer). Clone my HaXmas 2017 PJL Bonus repository and run the following command:
./create_pjl_job.py | nc -v -v <hostname> 9100, where
hostname is the address of your printer.