Horizon3.ai
Horizon3.ai

Lexmark Command Injection Vulnerability ZDI-CAN-19470 Pwn2Own Toronto 2022

by | Aug 10, 2023 | Attack Blogs

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

wanna buy some printers?

wanna buy some printers?

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.

Better Call Saul

Better Call Saul

When our first printer finally arrived it looked like it had seem better days. The second one we found was in better shape.

Broken Printer

Broken Printer

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.

programRipCode

programRipCode

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.

RSA imports

RSA imports

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.

RSA Keys

RSA 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.

fax_change_faxtrace_settings in a browser

fax_change_faxtrace_settings in a browser

Next, we can send the following request in Burp, notice we changed the value of the first parameter to $(echo 3).

Burp request

Burp request

Now, we can view the page in a browser again and see that the value for FT_Custom_Lbtrace has changed to “High”.

Updated value

This example demonstrates that the $(echo 3) payload was executed.

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.

Printer Setup Screen

Printer Setup Screen

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.

How can NodeZero help you?

Let our experts walk you through a demonstration of NodeZero, so you can see how to put it to work for your company.