astr.al

blog / research notes | code | music | recipes | zv.is network research lab

CVE-2025-26684 "pop-mdatp"

CVE-2025-26684: unprivileged local attackers can execute code as root by tricking mdatp into executing arbitrary binaries.
This affects Microsoft Defender ATP (mdatp) / Defender for Endpoint / whatever they're calling it this week, on Linux (and possibly macOS, untested).
Versions between 101.52.57 (December 2021) through 101.25032.0008 (May 2025) are affected.
The vulnerability is rather similar to CVE-2024-48991 in needrestart, disclosed by Qualys just a week prior. At least needrestart made an attempt to validate what it was executing.

Background

On 2024-11-25 while investigating an unrelated exploit attempt, I noticed mdatp executing java --version on multiple JREs located in non-standard paths.

We tracked down this behavior to a python script /opt/microsoft/mdatp/conf/scripts/open_files.py. It's part of mdatp’s detection logic for CVE-2021-44228, aka Log4Shell. open_files.py is executed as root, as it relies on running lsof -ac java,javaw to check for java processes with open fds containing log4j or spring-core in the filename. If there are any positive matches, the script attempts to get the JRE's version number by running /proc/$pid/exe --version.

Since open_files.py executes any arbitrary binary that just happens to be named java, I whipped up a quick proof of concept:
About 30 minutes later, after mdatp started its next process scan, I had a lovely root prompt:
snoclogost01:/tmp nobody$ gcc elevate.c -o elevate snoclogost01:/tmp nobody$ gcc pop-mdatp.c -o java snoclogost01:/tmp nobody$ id uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) snoclogost01:/tmp nobody$ ./java [.] creating fake fd to catch mdatp's attention [.] waiting for next open_files.py scan (~ hourly) [+] bingo # id uid=0(root) gid=0(root) groups=0(root),65534(nogroup)

Mitigations

Modify open_files.py and remove the unsafe _run_cmd() call in grab_java_version. This will break java version reporting in the MDE timeline.
A proper fix would be to identify the JRE version without executing the binary, but this method may vary depending on JRE vendor and version. The version number is only used for reporting purposes and does not appear to have any bearing on actual log4shell vulnerability detection, so it may be entirely elided.

Exploit

The proof of concept and original writeup sent to MSRC is available here.

Timeline