Citrus is a ransomware operation that Kaspersky's researchers published on 11 November. The victims so far are Russian companies, so it isn't a direct threat to UK organisations. We're writing about it anyway because almost every step is a technique that works against any Active Directory estate: a contractor's low-privilege login, a certificate trick to become a domain controller, and ransomware pushed to every machine by a Group Policy Object disguised as a security agent. Each step leaves something you can hunt for in Microsoft Defender and Sentinel.
What happened
Kaspersky's report, Citrus ransomware, describes a Russian-speaking group that breaks in through contractors. The main points:
- Initial access through contractors. The attackers use credentials stolen from contractor employees to connect to corporate VPNs or internet-facing RDP terminal servers. In every case the researchers saw, the contractor's domain account had very limited privileges.
- Escalation through AD CS. They tried CVE-2026-54121, which the report calls "Certighost". They create new machine accounts named
GHOSTfollowed by eight random letters, then request a certificate from theMachinetemplate with the domain controller's DNS name in the subject alternative name. That certificate lets them authenticate as the domain controller. - Ordinary tools. Discovery with SharpHound, ADRecon, Snaffler and a scanner called fscan; credential theft with Mimikatz and a modified keylogger; tunnels built with Xray; AnyDesk installed silently for remote access; and Impacket's
atexecfor remote commands. - AI-written scripts. Many of the PowerShell and batch scripts carry the kind of explanatory comments a language model writes. It didn't make the attack new, just faster to assemble.
- Deployment by GPO. The ransomware, which the report says is built on a platform called Sn00py, is copied into SYSVOL and pushed by a malicious Group Policy Object named after a well-known security vendor's agent. The GPO enables WinRM, disables Volume Shadow Copy and Microsoft Defender, and sets a ransom wallpaper. Encrypted files get the
.citrusextension and aCITRUS_README.txtnote. Hosts namedDC01toDC04are excluded so that Group Policy keeps working while everything else is encrypted.
Why it matters outside Russia
Contractor access is one of the most common ways into mid-market organisations, and contractor accounts are often the least watched. AD CS misconfigurations and unpatched certificate flaws are widespread. And GPO deployment is the fastest way to hit every Windows machine at once: if the attacker controls Group Policy, they don't need to touch each machine themselves. We explain how that works in What Is Group Policy?
Hunting in Defender and Sentinel
The indicators below come from Kaspersky's report. Check them against the original before blocking. The queries are starting points to tune for your estate.
1. Contractor accounts on VPN and RDP
let Contractors = (IdentityInfo
| where TimeGenerated > ago(7d)
| where JobTitle has_any ("contractor", "consultant", "supplier") or Department has_any ("Third Party", "External")
| distinct AccountName);
IdentityLogonEvents
| where Timestamp > ago(30d)
| where AccountName in~ (Contractors)
| where LogonType has "RemoteInteractive" or Protocol == "Rdp"
| summarize Logons = count(), Targets = make_set(DestinationDeviceName, 20), IPs = make_set(IPAddress, 20),
FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by AccountName
| order by Logons desc
Adjust the filter to however you mark contractors (a naming convention, a group or an attribute). Look for logons outside the contractor's normal hours, from new IP addresses, or to servers their work doesn't need.
2. GHOST machine accounts and certificates for a domain controller
SecurityEvent
| where TimeGenerated > ago(30d)
| where EventID == 4741 // computer account created
| extend NewComputer = tostring(TargetUserName)
| where NewComputer matches regex @"^GHOST[A-Z]{8}\$?$"
or SubjectUserName !endswith "$" // review all user-created machine accounts
| project TimeGenerated, Computer, NewComputer, SubjectUserName, SubjectDomainName
On your certificate authorities, look for certificate requests (events 4886 and 4887) where the requester is a recently created machine account and the subject alternative name is a domain controller. Defender for Identity's AD CS sensors can raise alerts on suspicious certificate requests, so check they are deployed on your CA servers. Confirm the fix for CVE-2026-54121 is applied using Microsoft's guidance for that CVE.
3. Impacket atexec scheduled tasks
DeviceEvents
| where Timestamp > ago(30d)
| where ActionType == "ScheduledTaskCreated"
| extend TaskName = tostring(parse_json(AdditionalFields).TaskName)
| where TaskName matches regex @"^\\?[A-Za-z]{8}$"
or TaskName has_any ("sIErKswD", "PpMBCCSR", "QwZtLmNp")
| project Timestamp, DeviceName, InitiatingProcessAccountName, TaskName, AdditionalFields
Impacket's atexec creates a task with a random eight-letter name that runs cmd.exe and writes output to a temporary file. Kaspersky saw it run cmd.exe through odd paths such as C:\Windows\System32\..\System32\cmd.exe, which is worth a rule of its own.
4. Tools dropped in ProgramData
let CitrusFiles = dynamic(["xray.exe", "mst.exe", "sabycenter.exe", "rpchost.exe", "webex.exe", "jhost.exe",
"fscan.exe", "Snaffler.exe", "SharpHound.exe", "steal_tgs.ps1", "2341.exe", "3777.exe", "pve.exe", "build_64.exe"]);
let CitrusMD5 = dynamic(["d631627131b90d576d77f4bf530e1abe", "7107fb029e7c63523e3aca5fc8e56b38", "e251df2d0b7c3682965efb4d2009a2f4",
"17b29b6c9de80402a45e321bbe1168fa", "9eee984b187423c46c10a63d080da15d", "cf903e4a1629aa0582fd0363b5786676"]);
DeviceFileEvents
| where Timestamp > ago(90d)
| where (FileName in~ (CitrusFiles) and FolderPath has_any (@"C:\ProgramData", @"C:\Windows\SYSVOL", @"C:\Windows\Temp"))
or MD5 in (CitrusMD5)
| project Timestamp, DeviceName, ActionType, FolderPath, FileName, MD5, InitiatingProcessAccountName
Kaspersky also lists two IP addresses, 91.210.109[.]118 and 91.210.108[.]180, and Xray tunnels disguised as traffic to a well-known Russian software mirror over port 443.
5. A new GPO that runs software everywhere
SecurityEvent
| where TimeGenerated > ago(30d)
| where EventID in (5136, 5137)
| where ObjectClass == "groupPolicyContainer" or EventData has "gPLink"
| project TimeGenerated, Computer, EventID, SubjectUserName, ObjectDN, AttributeLDAPDisplayName, AttributeValue
| order by TimeGenerated desc
Events 5136 and 5137 need directory service change auditing on your domain controllers. Any new GPO, or new link at the domain root, outside a change window deserves a ticket number. Pair it with a check for executables, .ico or .bmp files written to SYSVOL, and for scheduled tasks named KasperskyAgentInstallTask, Sysvc or Java rpchost agent. The vendor name is borrowed: an attacker's GPO can be named after anything you'd expect to see.
6. Defender, shadow copies and logs being switched off
DeviceProcessEvents
| where Timestamp > ago(30d)
| where (FileName =~ "wevtutil.exe" and ProcessCommandLine has_any (" cl ", "clear-log"))
or (FileName in~ ("sc.exe", "net.exe") and ProcessCommandLine has_any ("VSS", "WinDefend"))
or (ProcessCommandLine has "Set-MpPreference" and ProcessCommandLine has_any ("Exclusion", "DisableRealtime"))
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
| order by Timestamp desc
Clearing the Security log also produces event 1102, which is one of the most valuable events to collect centrally: once it's in Sentinel, the attacker can't clear it.
Mitigation
- Treat contractor access as its own risk. Give contractors named accounts with expiry dates, require phishing-resistant MFA on VPN and RDP, and limit what they can reach to the systems their work needs. Our third-party risk work covers how to keep that list honest.
- Don't expose RDP to the internet. Put terminal servers behind the VPN or a gateway with MFA.
- Fix AD CS. Apply the patch for CVE-2026-54121, set
ms-DS-MachineAccountQuotato 0 so ordinary users can't create computer accounts, and audit your certificate templates. Our AD CS explainer covers the common misconfigurations. - Lock down Group Policy. Limit who can create and link GPOs, alert on every change, and keep SYSVOL changes in your logs.
- Protect Defender from being turned off. Turn on tamper protection so policy and registry changes can't disable it.
How a managed SOC helps
Citrus is a reminder that most ransomware runs on ordinary admin tools, and the attackers' advantage is that nobody connects the contractor logon at 2am to the new machine account and the GPO an hour later. Wizard Cyber's SOCs are staffed 24/7 and investigate those signals together. If you think a contractor account may already have been misused, a compromise assessment will tell you what happened, and our incident response team can help if it's already happening.
Want to know what your contractor accounts can reach? Talk to our team.