Headline
CVE-2023-4504: CUPS Heap-based buffer overflow
Due to failure in validating the length provided by an attacker-crafted PostScript document, CUPS and libppd are susceptible to a heap-based buffer overflow and possibly code execution. This issue has been fixed in CUPS version 2.4.7, released in September of 2023.
Copying the same vulnerability from CUPS to cover the fix in libppd, reported by @todb
Description
Hello – below is a draft advisory that we plan to publish in about 60 days (around October 22, 2023), or sooner if you choose to disclose before then. Also, thanks for the incredibly easy mechanism to report security issues!
We are a CNA, so no need to involve MITRE - we can take care of publishing and credit and all that.
CVE-2023-4504: OpenPrinting CUPS Postscript Parsing Heap Overflow
AHA! has discovered an issue with CUPS from OpenPrinting, and is publishing
this disclosure in accordance with AHA!’s standard disclosure policy today,
on $DATE. CVE-2023-4504 has been assigned to this issue.
Any questions about this disclosure should be directed to
[email protected].
Executive Summary
Due to failure in validating the length provided by an attacker-crafted CUPS document, CUPS version v2.5b1 and prior, by default, is susceptible to a heap-based buffer overflow, and possibly code execution. CVE-2023-4504 appears to be an instance of CWE-122, a heap-based buffer overflow.
Technical Details
The scan_ps function in the CUPS codebase provides functionality that scans through a string looking for the next Postscript object. When iterating through a string which contains an open parenthesis and ends with a single backslash (0x5c) character, the code incorrectly iterates forward a character without properly checking the bounds of the string resulting in a 1 byte read beyond the allocated heap buffer.
libppd took scan_ps code and renamed it to ppd_scan_ps().
Snippet of the vulnerable code:
libppd/ppd/raster-interpret.c
1039 static _ppd_ps_obj_t * /* O - New object or NULL on EOF */
1040 ppd_scan_ps(_ppd_ps_stack_t *st, /* I - Stack */
1041 char **ptr) /* IO - String pointer */
1042 {
...
1085 switch (*cur)
1086 {
1087 case '(' : /* (string) */
1088 obj.type = CUPS_PS_STRING;
1089 start = cur;
1090
1091 for (cur ++, parens = 1, valptr = obj.value.string,
1092 valend = obj.value.string + sizeof(obj.value.string) - 1;
1093 *cur;
1094 cur ++)
1095 {
1096 if (*cur == ')' && parens == 1)
1097 break;
1098
1099 if (*cur == '(')
1100 parens ++;
1101 else if (*cur == ')')
1102 parens --;
1103
1104 if (valptr >= valend)
1105 {
1106 *ptr = start;
1107
1108 return (NULL);
1109 }
1110
1111 if (*cur == '\\')
1112 {
1113 /*
1114 * Decode escaped character...
1115 */
1116
1117 cur ++;
1118
1119 if (*cur == 'b')
1120 *valptr++ = '\b';
1121 else if (*cur == 'f')
1122 *valptr++ = '\f';
1123 else if (*cur == 'n')
1124 *valptr++ = '\n';
1125 else if (*cur == 'r')
1126 *valptr++ = '\r';
1127 else if (*cur == 't')
1128 *valptr++ = '\t';
1129 else if (*cur >= '0' && *cur <= '7')
1130 {
1131 int ch = *cur - '0';
1132
1133 if (cur[1] >= '0' && cur[1] <= '7')
1134 {
1135 cur ++;
1136 ch = (ch << 3) + *cur - '0';
1137 }
1138
1139 if (cur[1] >= '0' && cur[1] <= '7')
1140 {
1141 cur ++;
1142 ch = (ch << 3) + *cur - '0';
1143 }
1144
1145 *valptr++ = (char)ch;
1146 }
1147 else if (*cur == '\r')
1148 {
1149 if (cur[1] == '\n')
1150 cur ++;
1151 }
1152 else if (*cur != '\n')
1153 *valptr++ = *cur;
1154 }
1155 else
1156 *valptr++ = *cur;
1157 }
Line 1085 contains the case statement which provides the logic used to iterate through the given string.
On line 1091, the for loop within the case statement is used to iterate through each character after encountering an open paranthesis character (0x28), storing the pointer to the current character in cur.
On line 1111, the code checks if the current character is a backslash and finally, in line 1117, the character index is incremented without checking the length, now pointing to the null byte terminating the string.
Upon the next iteration of the loop, on line 1094, the loop now begins iterating through unallocated memory resulting in undefined behaviour.
A Base64 encoded blob of an example PostScript document that can trigger the issue is below.
Attacker Value
By providing this malformed PostScript document, an attacker could compromise the machine running the software. Once compromised, this can provide an attacker a unique, privileged position in the targeted network.
Credit
This issue is being disclosed through the AHA! CNA and is credited to: zenofex and WanderingGlitch
Timeline
2023-07-27 (Thu): Initial findings presented at AHA! Meeting 0xffff
2023-08-21 (Monday): PoC validated and this disclosure drafted.
2023-08-23 (Day): Disclosed to the vendor per [their GitHub repo's instructions](https://github.com/OpenPrinting/cups/security).
YYYY-MM-DD (Day): Vendor acknowledged the vulnerability.
YYYY-MM-DD (Day): Vendor released fixed version [X.Y.Z](https://example.com/).
YYYY-MM-DD (Day): Public disclosure of [CVE-2023-4504](https://takeonme.org/cves/CVE-2023-4504.html).
Related news
Gentoo Linux Security Advisory 202402-17 - Multiple vulnerabilities have been discovered in CUPS, the worst of which can lead to arbitrary code execution. Versions greater than or equal to 2.4.7 are affected.
Dell vApp Manger, versions prior to 9.2.4.x contain an arbitrary file read vulnerability. A remote attacker could potentially exploit this vulnerability to read arbitrary files from the target system.
Ubuntu Security Notice 6391-2 - USN-6391-1 fixed a vulnerability in CUPS. This update provides the corresponding update for Ubuntu 16.04 LTS and Ubuntu 18.04 LTS. It was discovered that CUPS incorrectly parsed certain Postscript objects. If a user or automated system were tricked into printing a specially crafted document, a remote attacker could use this issue to cause CUPS to crash, resulting in a denial of service, or possibly execute arbitrary code.
Ubuntu Security Notice 6392-1 - It was discovered that libppd incorrectly parsed certain Postscript objects. If a user or automated system were tricked into printing a specially crafted document, a remote attacker could use this issue to cause libppd to crash, resulting in a denial of service, or possibly execute arbitrary code.
Ubuntu Security Notice 6391-1 - It was discovered that CUPS incorrectly parsed certain Postscript objects. If a user or automated system were tricked into printing a specially crafted document, a remote attacker could use this issue to cause CUPS to crash, resulting in a denial of service, or possibly execute arbitrary code.