Introduction
In December 2022, we competed at our first pwn2own. We were able to successfully exploit the Lexmark MC3224i using a command injection 0-day. This post will detail the process we used to discover, weaponize, and have some fun with this vulnerability. You can find our POC here.
Printer Acquisition
It was rather difficult to acquire the Lexmark MC3224adwe. So much so that ZDI removed it from the competition and replaced it with the Lexmark MC3224i. We were able to find two printers for sale on the internet from some interesting characters.
When our first printer finally arrived it looked like it had seem better days. The second one we found was in better shape.
We sacrificed our first printer to desolder the flash chip and dump the firmware and used the second one to test against. Unfortunately, both of our printers had toner issues which disabled large parts of the functionality of the printer including PJL.
Firmware Extraction
The firmware files downloaded from Lexmark’s website are encrypted. When these encrypted firmwares are uploaded to the printer, the printer uses keys stored in the previous firmware in order to decrypt the new firmware. Our strategy was to extract the firmware from a sacrificial printer and hope that the keys contained within were able to decrypt the most recent firmware.
In order to dump the decrypted firmware from flash, we followed this excellent blog post by nccgroup. To get us started finding the keys to decrypt new firmware we followed another series of great blog posts by Team82. The printer model and firmware version were slightly different in the blogs compared to the model and version we had, but it was enough to get us started. We’ll start by covering the difference we found in our version of the firmware compared to the blog posts listed above. The firmware version we started with was CXLBL.074.038.
ProgramRipCode in Hydra
In our case, the function responsible for kicking off the firmware update was contained in a binary named hydra
. We could not find any direct access to RSA keys in this binary. Based on some error strings we found in programRipCode
, we found that hydra
instead shuttles the work off to a binary called flashSrv
.
FlashSrv
flasSrv
is a fairly straight forward binary. We were on the hunt for RSA decryption keys and in the table of imports, we found a handful of RSA related functions. We were on the right track.
Tracking the callers of these functions we found a function called decryptSection
which called a function we named LoadSecurityKey
which loads a RSA key from an in-memory array of keys.
Now that we had the RSA keys, we could decrypt the latest firmware, CXLBL.081.215.
The Vulnerability
Once we had the latest decrypted firmware, we searched through many subsystems in the printer for vulnerabilities. We were ultimately inspired by this Crowdstrike blog to search for command injection vulnerabilities. We found the cgi-bin
directory and were pleasantly surprised to find a command injection using a bash eval
statement in fax_change_faxtrace_settings
.
$ rgrep eval fax_change_faxtrace_settings: eval "$cmd" > /dev/null fax_change_faxtrace_settings: eval "$cmd" > /dev/null fax_change_faxtrace_settings: eval "$cmd" > /dev/null
fax_change_faxtrace_settings
is a bash script that gets executed when an HTTP POST request is made to the http://{target}/cgi-bin/fax_change_faxtrace_settings
. This script reads a set variables of the form FT_*
from the body of the POST request and uses them to construct a command to run with eval
. In our POC we set the value of the variable FT_Custom_lbtrace
to $({payload})
where {payload}
is the command we would like to run.
We can illustrate the exploit using Burp. First notice the default configuration of the /fax_change_faxtrace_settings
page.
Next, we can send the following request in Burp, notice we changed the value of the first parameter to $(echo 3)
.
Now, we can view the page in a browser again and see that the value for FT_Custom_Lbtrace
has changed to “High”.
Vulnerable Configurations
When a user first powers on their Lexmark printer, they are presented with an initial Setup Wizard. This wizard directs the user to choose system settings like language, but also optionally to configure an admin user.
If the user chooses “Set Up Later”, the printer will allow access to all functionality and pages on the printer’s web interface by “Guest” users. If the user chooses “Set up Now”, the printer will restrict much of the available functionality until users authenticate.
If the user elects to “Set Up Later”, the user can still configure a credential via the web interface if they choose. However, a credential setup in this manner, by default, does not place any restrictions on the “Guest” account. This means that many sensitive functions are still exposed – including access to the vulnerable endpoint /cgi-bin/fax_change_faxtrace_settings
.
When investigating what configuration was most commonly deployed in the real world, we investigated devices listed on Shodan and devices in our client base. On Shodan, searching “Lexmark 3224” shows all printers that have the web interface exposed. Majority of these exposed printers were in a vulnerable configuration. Extending that search to more Lexmark printers on Shodan, revealed similar vulnerable configurations. This trend was the same for our clients who deploy Lexmark printers in their corporate networks.
ShowmanShip
We wanted to have something to show that was a bit flashier than a root shell. As part of our reverse engineering, we dove deep into the rob
ecosystem on the printer and discovered that we could make the printer beep with a command like the following: rob call applications.beeper customBeep "{({iii})}" song frequency 195 duration 180 offDuration 70
We used this to create a script to output a custom rob
command to play Taylor Swift or a song from Super Mario Brothers.
Summary
Competing in Pwn2own was a great experience and we cannot wait to do it again. Thanks to all of the researchers who publish their work that helped us get up to speed on reverse engineering Lexmark printers. Hopefully this post will help future researchers do the same.