Three vulnerabilities in Avira Internet Security, from an arbitrary file delete primitive to two distinct paths to SYSTEM privileges.
Avira Internet Security ships with a handful of modules that quietly handle privileged operations in the background: software updates, performance monitoring and system cleanup. Each one runs parts of its workflow as SYSTEM. Three of them don't bother checking what they are actually operating on.
This writeup covers three issues: an arbitrary file delete (CVE-2026-27748) in the Software Updater, an insecure deserialization (CVE-2026-27749) in System Speedup, and an arbitrary folder delete over TOCTOU (CVE-2026-27748) in the Optimizer. The file delete primitive is useful on its own. The other two both result in Local Privilege Escalation to SYSTEM.
ℹ️ Impacted versions of Avira
Vulnerable: 1.1.109.1990 and below.
Fixed in: 1.1.114.3113.
The modules involved are:
C:\ProgramData\OPSWAT\MDES SDK\, some of which get deleted as part of the update cycle.Avira.SystemSpeedup.RealTimeOptimizer.exe starts running as SYSTEM when "Performance Booster" is enabled via the UI.SYSTEM.config.msi trickTwo of the three vulnerabilities below rely on the well-documented Config.msi deletion primitive. In short: abuse a SYSTEM-level delete to remove C:\Config.msi, recreate it with .rbs and .rbf rollback files, trigger an MSI install failure. Windows Installer processes your rollback scripts as SYSTEM and plants a DLL in C:\Program Files\Common Files\microsoft shared\ink\HID.DLL. Press CTRL+ALT+DEL, run osk.exe, SYSTEM shell.
Read ZDI and Mandiant posts for the full details.
ℹ️ Folder delete vs. File delete
This trick abuses a folder delete redirection, which still works today. However, the file delete makes use of the deletion of the alternate data stream
::$INDEX_ALLOCATION, which is no longer possible since24H2because Microsoft patched it.

Microsoft patch information about $INDEX_ALLOCATION.
The Software Updater deletes C:\ProgramData\OPSWAT\MDES SDK\wa_3rd_party_host_32.exe during its update process. There is no check on whether the path resolves to a symlink. Create one and get arbitrary file delete as SYSTEM. Before Windows 24H2: it's LPE via the config.msi trick. After 24H2, it's a denial of service or system integrity compromise depending on target.
The target file exists and cannot be deleted by our limited user:

Target file - not deletable as limited user.
Prepare the directory and plant the symlink:
# Create the directory
PS C:\temp> mkdir "C:\ProgramData\OPSWAT\MDES SDK"
Répertoire : C:\ProgramData\OPSWAT
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 06/08/2025 13:53 MDES SDK
# Create the mountpoint to RPC Control
PS C:\temp> .\CreateMountPoint.exe "C:\ProgramData\OPSWAT\MDES SDK" "\RPC Control"
# Create the symlink to our target
PS C:\temp> .\CreateSymlink.exe "\RPC Control\wa_3rd_party_host_32.exe" "C:\windows\system32\foobar.txt"
Opened Link \RPC Control\wa_3rd_party_host_32.exe -> \??\C:\windows\system32\foobar.txt: 00000158
Press ENTER to exit and delete the symlink
Run the Software Updater and wait for it to finish:

Software Updater - start the update.

Update in progress.

Update complete.
Procmon shows the symlink was followed and the target file is deleted:

Procmon - target file deleted as SYSTEM.
Avira.SystemSpeedup.RealTimeOptimizer.exe runs as SYSTEM and deserializes C:\ProgramData\Avira\SystemSpeedup\temp_rto.dat using .NET's BinaryFormatter. No filter, no validation. The file is in ProgramData, which by default allows local users to create files. If temp_rto.dat already exists and can't be overwritten, CVE-2026-27748 gives us the delete we need to recreate it. This vulnerability has been quickly identified using CerealKiller, thanks to two06 from TrustedSec.
C:\Program Files (x86)\Avira\System Speedup\Avira.SystemSpeedup.RealTimeOptimizer.exeThree deserialization calls exist in RealTimeOptimizer.exe: LoadDBFromFile, LoadCrashRestoreKnowledge, and LoadProcessExceptionKnowledge. We focus on LoadCrashRestoreKnowledge:
private void LoadCrashRestoreKnowledge()
{
if (File.Exists(this.CrashRestoreKnowledgeBasePath))
{
try
{
FileStream fileStream = new FileStream(this.CrashRestoreKnowledgeBasePath, FileMode.OpenOrCreate);
BinaryFormatter binaryFormatter = new BinaryFormatter();
Dictionary<int, ProcInfo> crashRestoreKnowledge = this._crashRestoreKnowledge;
lock (crashRestoreKnowledge)
{
this._crashRestoreKnowledge = (Dictionary<int, ProcInfo>)binaryFormatter.Deserialize(fileStream);
}
fileStream.Close();
}
catch (Exception ex)
{
Log.Warning(LogModule.General, "LoadCrashRestoreKnowledge exception: " + ex.Message);
}
}
}
Straight BinaryFormatter.Deserialize() on a FileStream created from the CrashRestoreKnowledgeBasePath attribute. The attribute value is defined in the class:
public string CrashRestoreKnowledgeBasePath { get; private set; } =
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +
"\\Avira\\SystemSpeedup\\temp_rto.dat";
CommonApplicationData resolves to C:\ProgramData. On a fresh install, temp_rto.dat does not exist yet:

ProgramData\Avira\SystemSpeedup - no temp_rto.dat.
The RealTimeOptimizer runs when "Performance Booster" is enabled. Open it from the main Avira UI via Advanced Tools:

Avira Spotlight - Advanced Tools.

System Speedup UI.
The UI process runs as our limited user:

Process Explorer - SystemSpeedup UI as limited user.
Enable Performance Booster:

Checking "Enable Performance Booster".
Procmon shows the Optimizer process, running as SYSTEM, accessing temp_rto.dat:

Procmon - temp_rto.dat read as SYSTEM.
Generate the payload:
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "whoami > c:\pwned.txt" -o raw > c:\temp\pwned.bin
Disable the checkbox, drop the payload, re-enable:
C:\temp>copy c:\temp\pwned.bin C:\ProgramData\Avira\SystemSpeedup\temp_rto.dat
1 fichier(s) copié(s).
Procmon confirms deserialization as SYSTEM and successful command execution:

Procmon - BinaryFormatter.Deserialize as SYSTEM. Command executed.
The Optimizer scans for junk and temporary files, then deletes them as SYSTEM. Between the scan and the cleanup, we swap our controlled directory for a junction to C:\config.msi. The Optimizer trusts the path it verified at scan time, and never re-checks it at deletion time: we have a TOCTOU (Time-of-check to time-of-use).
Create a directory in C:\temp and wait. The Optimizer needs it to be at least 10 minutes old to classify it as junk:

Directory structure in C:\temp.
Open Performance -> Optimizer:

Optimizer module.
Run a scan:

Scan.

Waiting for scan to finish.
Procmon confirms the Optimizer parsed our directory:

Procmon - Optimizer reads our directory.
Go to Review Results -> System Junk -> Temporary System Files. Confirm our directory is listed:

Review Results.

System Junk.

Temporary System Files.

Our directory confirmed in the list.
Before clicking Optimize, set up the payload by running FolderOrFileDeleteToSystem.exe, then replace our directory with a junction to C:\config.msi:

config.msi junction in place.
Click Optimize. Procmon confirms the junction is followed and C:\config.msi is deleted:

Procmon - config.msi deleted as SYSTEM.
MSI rollback does the rest: the DLL is dropped.

HID.DLL dropped successfully.
Press CTRL+ALT+DEL and start the virtual keyboard (osk.exe) to spawn you SYSTEM shell:

SYSTEM shell.
Three modules, three bugs, all running as SYSTEM. The arbitrary file delete is the most versatile primitive: useful standalone, and can be used as a setup step for the deserialization. The deserialization is the cleanest LPE: no race condition, no timing window, just drop a file and click a checkbox. The TOCTOU is the most constrained of the three, but still a straightforward path to SYSTEM.
Below we include a timeline of all the relevant events during the coordinated vulnerability disclosure process with the intent of providing transparency to the whole process and our actions.
If you would like to learn more about our security audits and explore how we can help you, get in touch with us!