Last year we wrote about a Windows 11 vulnerability that allowed a regular user to gain administrative privileges (see 300 Milliseconds to Admin: Mastering DLL Hijacking and Hooking to Win the Race (CVE-2025-24076 and CVE-2025-24994)). Not long after, Manuel Kiesel from Cyllective AG reached out to us after stumbling across a seemingly similar issue while investigating the Lenovo Vantage application. He asked for some Windows related help, which proved to be trickier than expected. It turns out that the exploit primitive for arbitrary file deletion to gain SYSTEM privileges no longer works on current Windows machines. However, adapting the code provided by Trend Micro’s ZDI still allowed us to use folders to exploit the vulnerability.

Discovery & Contact

Lenovo Vantage is an application provided by Lenovo that helps to manage computer hardware, including system updates and drivers. It offers various add-ons, such as a system cleanup task that removes unnecessary files. The application is available on the Windows Store and can be downloaded by any regular user.

By the time Manuel contacted us, most of the analysis of Lenovo Vantage had already been completed, and he had identified a potential vulnerability in the software’s file cleanup functionality. You can read about this on Cyllective’s blog. It boils down to the fact that the application, which runs as SYSTEM, deletes a directory that can be modified by a regular user:

private static bool CleanFiles() {
...
    DeleteDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Temp"), false);
...

In 2021, Abdelhamid Naceri demonstrated a technique showing how the deletion of user writable folder contents by an elevated account can lead to code execution with elevated privileges. We have abused this issue in the past, including in this case where we used the primitive to gain administrative privileges through a Lenovo vulnerability, tracked as CVE-2022-4569 and described in the Compass’ blog – Lenovo Update Your Privileges.

However, when we tried to use the tool provided by ZDI, we were unable to leverage the recursive file deletion primitive to gain SYSTEM privileges. After some investigation, it became clear that the INDEX_ALLOCATION trick no longer works on a fully up to date Windows 11 system, as also noted by Filip Dragovic:

Technical Background – Exploit Primitive

As ZDI explained in their well written blog post, it was possible to abuse the MSI install rollback feature to turn an arbitrary folder deletion into a privilege escalation. Since this approach only works when a directory can be deleted, they expanded the attack surface and showed how the same idea can also be exploited when only arbitrary file deletion is available. The key insight was to transform a file deletion (DeleteFileA) into a folder deletion by redirecting the call to the directory metadata attribute ($INDEX_ALLOCATION).

As you can see here, when we run the following snippet in PowerShell on a fully up to date Windows 11 system such as 24H2, the INDEX_ALLOCATION trick no longer appears to work:

# From https://x.com/filip_dragovic/status/1881091708039131441

function Invoke-DeleteFileA {
    param (
        [Parameter(Mandatory)]
        [string]$FilePath
    )

    $signature = @"
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    public static extern bool DeleteFileA(string lpFileName);
"@

    $type = Add-Type -MemberDefinition $signature -Name "Win32Api" -Namespace "Kernel32" -PassThru
    $result = $type::DeleteFileA($FilePath)

    if ($result) {
        Write-Output "File deleted successfully"
    } else {
        $errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
        Write-Output "Failed to delete file. Error code: $errorCode"
    }
}

# Then run the script. The deletion fails.
PS > Invoke-DeleteFileA -FilePath 'C:\test\folder::$INDEX_ALLOCATION'
Failed to delete file. Error code: 2

As a result, using FolderContentsDeleteToFolderDelete.exe no longer works for arbitrary file deletes, which left us security analysts a bit disappointed (ehm … I mean relieved that this can no longer be abused).

But then shortly after, we realized that we already had an arbitrary folder deletion primitive and did not need to depend on the INDEX_ALLOCATION trick in the first place. With that insight, we adapted the ZDI tool and brought the tool back to life.

In FolderContentsDeleteToFolderDelete.cpp we remove the reference to the INDEX_ALLOCATION on line 27, and on line 118 we open the handle to the directory instead of the file:

Line: FolderContentsDeleteToFolderDelete.cpp
27:   symlinkTarget = std::wstring(L"\\??\\") + symlinkTarget;
118:  hf = op.OpenDirectory(exploitFilePath.c_str(), MAXIMUM_ALLOWED, FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_ALWAYS);

After hours of trial and error, we found that the fix was surprisingly small!

PoC

After figuring this out, Manuel quickly wrapped the vulnerability trigger into a clean and easy to use proof of concept (PoC) executable. Once the Lenovo Vantage application was installed on the system, we were able to demonstrate that a regular user on Windows 11 could reliably exploit the vulnerability and gain administrative privileges.

Shout out to Lenovo’s PSIRT team for handling the responsible disclosure of the vulnerability well and responding in a timely manner. You can read the Lenovo vulnerability advisory here. This vulnerability has since been mitigated and cannot be exploited anymore.

We especially want to thank Manuel Kiesel from Cyllective AG for reaching out and allowing us to collaborate on a vulnerability! It was a pleasure!

Make sure to also check out the first part on Cyllective’s blog, as it covers the initial discovery and most of the technical details.

Disclosure Timeline

  • 23.11.2025: First contact to Lenovo via [email protected]
  • 24.11.2025: Got a response on how to send the report
  • 25.11.2025: Sent report
  • 25.11.2025: Lenovo confirmed they received the report
  • 04.12.2025: Lenovo acknowledges the vulnerability and reserves CVE-2025-13154
  • 13.01.2026: The patch is released