S5PIVOT – A Python Backconnect Proxy Hidden Inside a Qilin Ransomware Intrusion

Executive Summary

During the response to a Qilin ransomware attack on a mid-sized German company, Hexastrike found a previously unknown remote-access tool that the attackers installed alongside the ransomware, which we track as S5PIVOT. It hides inside an ordinary copy of the Python runtime and gives the attackers a quiet way back into the network that does not depend on the account they first broke in with. No security vendor detected it at the time, and its code is very likely derived from an earlier tool known as VIPERTUNNEL.

The attackers did not need an exploit. They most likely logged on to the company’s VPN with a valid employee password, because the VPN asked for nothing more than a password. From there, the attackers relied on weaknesses that had existed for years. A backup service account and more than 60 other accounts held full domain administrator rights, the forest administrator’s password was left readable on member servers because a backup agent ran under that account, local administrator passwords were reused across servers, and there was no endpoint detection and no central logging to notice any of it. Within four days the attackers had taken over the domain and copied business data to cloud storage they controlled, and over the following three days they encrypted the servers.

The attackers erased the Windows event logs on most of the servers they encrypted, as Qilin affiliates routinely do, so the investigation had to be rebuilt from records that survive such a cleanup. A crash dump preserved the data theft, the file system’s change journal recorded the deletion of the tools, and parts of the erased logs could be recovered from unused space in the log files. Some servers were left unbootable because the ransomware was told to encrypt system folders as well. This post explains what happened, what the surviving records showed, and the controls and detections that would have stopped or exposed each step.

Key Findings

  • The intrusion relied on valid credentials from start to finish. Initial access most likely came through the SonicWall SSL-VPN, which enforced no multi-factor authentication, and the operator’s first actions inside the estate were to check which of the passwords it already held still worked, consistent with credentials exposed earlier through an infostealer infection and a sign-in campaign against the Entra tenant.
  • Privilege escalation required no exploit, because a backup account that was already a Domain Admin, more than 60 further accounts with the same rights, Tier-0 credentials stored as service passwords on member servers and reused local administrator passwords meant that one valid password already carried control of the estate, and a flat network without endpoint detection or central logging ensured nobody saw it being used.
  • Alongside the encryptor, the operator deployed S5PIVOT, a previously undocumented Python backconnect proxy that no antivirus engine detected at the time. A SYSTEM scheduled task launches an embeddable CPython runtime without a script argument, a sitecustomize.py startup hook loads a seven-layer encrypted payload, and the resulting SOCKS5 client holds a single outbound TLS session on port 443, while related builds point to further command-and-control infrastructure and the loader and crypter overlap with VIPERTUNNEL.
  • The operator cleared the event logs on ten servers and deleted its tooling, yet the intrusion was reconstructed from what survived, including a Windows Error Reporting dump of the WinRM host process that preserved the AzCopy exfiltration to an attacker-controlled Azure blob container, and registry values, the USN journal, SRUM and log slack that dated the remaining steps.
  • The Qilin/Agenda encryptor ran on most servers with its exclusion filters disabled, which encrypted system directories, left several servers unbootable and, in our assessment, terminated lsass.exe as collateral damage, and its never-removed Run value relaunched the encryptor when administrators logged on days later to collect evidence, which was initially mistaken for a returning attacker.

Initial Access

The operator held access for four days before encryption began, and the surviving evidence places the entry on the SonicWall SSL-VPN with valid domain credentials. The appliance itself retained almost nothing, but the member servers the account reached afterwards kept enough to establish the account, the source, and the order in which the operator acquired privileges.

VPN Logon

The earliest activity we attribute to the operator is a network logon by a domain user account, four days before the encryption, recorded on the one member server whose Security log was never cleared. The logon came from the inside interface of the SonicWall appliance, used NTLMv2, and carried the client-supplied workstation name WORKSTATION, the default that tools like Metasploit send unless the operator sets another. That log covers about a month, and within it the account authenticated exclusively with NTLM, exclusively from the VPN interface, and left no other activity at all. A domain-joined Windows client would have used Kerberos, and an employee working through the VPN would have produced interactive logons, file access and the other ordinary traces of a working day. Each of these details has an innocent explanation on its own, but together they describe a scripted tool on a non-domain machine, operated by someone who already held the password.

The first network logon attributed to the operator, from the VPN appliance's inside interface, NTLMv2, workstation name WORKSTATION.
The first network logon attributed to the operator, from the VPN appliance’s inside interface, NTLMv2, workstation name WORKSTATION.

The SSL-VPN did not enforce MFA, and the appliance retained about twelve hours of logs with no syslog copy, so the external session, the public source address, and any record of whether a second factor was requested were gone before the investigation began. What remains is the account itself, which reappears three days later.

Protecting and monitoring the VPN. In this case the VPN required nothing beyond a valid password. We recommend phishing-resistant MFA, such as FIDO2 security keys or platform passkeys, on every remote-access path, combined with policies that limit VPN access to managed devices or expected locations and raise an alert for connections from outside them. Password spraying against the appliance typically appears as many accounts failing from one source or one account failing from many sources, and both patterns can be detected once the appliance logs are forwarded to central storage with a retention period of several months. On internal servers, NTLM logons that originate from the VPN appliance or its address pool with a default client name such as WORKSTATION, by accounts that do not normally use the VPN, are a further detection worth implementing.

Credential Validation

Three days after that first logon the account authenticated across the estate within minutes, and shortly afterwards the operator began testing a list of further domain accounts against a single server, first from the VPN address and then from a rogue host with a default WIN- computer name that appeared in no asset inventory. The record that gives this away is event 4776, which a member server writes only when its own local account database is asked to validate a credential. Status 0xC0000064 means the user name does not exist locally, so a run of these for domain accounts on a member server shows a tool offering domain accounts as local ones, interleaved seconds apart with successful domain logons for the same accounts, which is how credential-testing tools behave.

4776 events from the rogue WIN- host, local validation failures with status 0xC0000064, each followed within a fraction of a second by a successful domain logon for the same account.
4776 events from the rogue WIN- host, local validation failures with status 0xC0000064, each followed within a fraction of a second by a successful domain logon for the same account.

Whether the operator was guessing or checking is settled by a second status code. A wrong password produces 0xC000006A. For several accounts the server instead returned 0xC0000224, which means the password must change, and Windows returns this status only after it has verified that the submitted password is correct and then found the account flagged for a password change. The operator therefore supplied the correct passwords for those accounts and was stopped only by the flag. The run was a check of credentials obtained elsewhere, made to find out which of them still worked.

Unknown hosts and credential testing. Most organizations follow a naming convention for their systems, which makes computer names outside that convention an inexpensive detection signal. Authentication from default or tool-typical names, such as WIN- followed by random characters, DESKTOP-, WORKSTATION or kali, or from any name that does not appear in the asset inventory should therefore raise an alert. On member servers, event 4776 for domain accounts with status 0xC0000064 is uncommon in normal operation, and a burst of these events from a single source, interleaved with successful logons for the same accounts, is characteristic of a credential-testing tool. Event 4625 with status 0xC0000224 from the same source deserves priority, because it indicates that the submitted password was correct.

Where those credentials came from is less certain, and three leads predate the intrusion. A distributed sign-in campaign ran against the Entra tenant for almost three months, into the encryption week, with repeated successful sign-ins to one account and neither MFA nor Conditional Access to stop it. Employee credentials appeared in infostealer logs, and a commodity stealer had run on one server months earlier from a source that could not be reconstructed. We found no exploit, no phishing, and no unauthorized remote-support session, so a valid VPN credential remains the best-supported entry, and the rest of the intrusion followed from what that account was permitted to do.

From Local Administrator to Domain Admin

The compromised VPN account held only ordinary domain user rights. A password spray against the built-in Administrator account, still datable from the last-failed-logon timestamps in the SAM hives after the logs were cleared, was followed the next morning by a successful local Administrator logon on one server, and at least two file servers shared the same built-in Administrator password. That evening the operator reset the built-in Administrator on eight servers to a single campaign password, which the identical password verifiers in their SAM hives confirm.

On three member servers, one of them a file server, the Acronis Managed Machine Service ran under the forest administrator account, a member of Domain Admins and Enterprise Admins. Windows stores the password of a service account in the LSA secrets in a form any local administrator can read, so a single local administrator logon on any of those servers was enough to obtain a Domain Admin credential. We found no record of the operator reading that secret, and the surviving evidence does not show how it obtained the backup account, which was itself a Domain Admin. On the morning of the fifth day the backup account authenticated to dozens of hosts within minutes, and the exfiltration and the S5PIVOT deployment both ran under it. Those logons also left a record the operator did not clear, because WinRM, RDP and service logons load the user’s registry hive and create a profile directory under C:\Users, whereas a plain file-share logon does not, so the backup account’s profile directories that appeared across the estate that day identify the hosts the operator worked on directly.

The Acronis Managed Machine Service on a member server running under the forest administrator account, with its password stored as the LSA secret _SC_MMS.
The Acronis Managed Machine Service on a member server running under the forest administrator account, with its password stored as the LSA secret _SC_MMS.

The exposure was not limited to one account. More than 60 accounts held Domain Admin rights, several of them running services on member servers in the same way, and a Group Policy Preference last changed before the intrusion had made a documentation tool’s service account a local administrator on most systems, so the path from a member server to the domain existed long before the operator used it.

Service accounts and local administrator passwords. Any local administrator of a server can recover the passwords of the services that run there, so a privileged service account extends its rights to everyone who controls that server. Services such as backup agents should therefore run under group managed service accounts, whose passwords are long, random and rotated automatically, and with only the rights the service requires, because an administrator of a server that is permitted to use such an account can still act as it. Membership in Domain Admins or Enterprise Admins is not appropriate for a service account. Privileged group membership should be limited to the few administrators who need it, those accounts should not log on to member servers, and local administrator grants distributed through Group Policy Preferences should be reviewed and removed. Windows LAPS gives every machine a unique, automatically rotated local administrator password, so that a single recovered password no longer grants access across the estate.

The S5PIVOT Backconnect Proxy

Beside the ransomware the operator installed a second, quieter foothold: a backconnect proxy that gave it a route back into the network independent of the VPN account. The hosts retained the scheduled task that launched it, the PowerShell command that registered the task, and the toolkit directory it ran from.

Scheduled Task and Startup Hook

On multiple collected servers a scheduled task runs as SYSTEM under a random numeric name and launches pythonw.exe every minute, with no script argument, from a randomly named directory under C:\ProgramData. The task definition names neither a script nor a payload, so anyone reading it sees a Python interpreter starting with nothing to run. All tasks were registered on the evening of the fifth day inside WinRM sessions of the backup account, and on one server the Windows PowerShell log preserved the registration command.

powershell.exe -c Register-ScheduledTask (Get-Random) -Ac (New-ScheduledTaskAction -W C:\programdata\REDACTED -E pythonw.exe) -Tr (New-ScheduledTaskTrigger -Once -At (date) -RepetitionI (New-TimeSpan -Mi 1)) -Set (New-ScheduledTaskSettingsSet -DontStopIfG -Ex (New-TimeSpan) -Al) -User System

Get-Random returns a 32-bit integer, which accounts for the nine- and ten-digit task names, and the same session had loaded PowerShell’s archive module and the .NET compression assemblies shortly before, which we read as the operator unpacking the toolkit on the host. Under the scheduler’s default IgnoreNew policy a new instance is skipped while one is still running, so the task never stacks interpreters, and if the proxy crashes or the host reboots the task restores it within a minute.

The scheduled task action running pythonw.exe with no script argument and a one-minute repetition trigger.
The scheduled task action running pythonw.exe with no script argument and a one-minute repetition trigger.

The directory contained the official CPython 3.13.3 embeddable runtime and three files the operator added: a sitecustomize.py hook, a .bin payload, and a debug launcher. CPython imports sitecustomize automatically at interpreter startup, so the hook runs on every launch without appearing anywhere in the task or on a command line. It reads the interpreter’s real argument vector through ctypes, acts only when the interpreter started without a script argument, which is precisely how the task starts it, and then hands the .bin file to runpy.run_path. Between the task and the hook, a payload is started on every boot without its name being recorded in any process command line, which defeats the command-line-based detections most environments rely on for scripted persistence.

Interpreters as persistence. A Python runtime in ProgramData that a SYSTEM task starts every minute is highly unusual on a server. Application control that applies to all accounts, such as App Control for Business with rules that do not permit execution from writable locations like ProgramData, can prevent such a runtime from starting at all. Where application control is not in place, we recommend alerting on scheduled tasks whose action starts an interpreter such as python.exe, pythonw.exe or node.exe without a script argument, on purely numeric task names, and on Register-ScheduledTask command lines that generate the task name with Get-Random or set the working directory to ProgramData, particularly when they run inside a WinRM session. On disk, a sitecustomize.py that reads the argument vector through ctypes or passes a non-Python file to runpy.run_path should be examined, as legitimate deployments rarely require either.

Crypter and Client

The payload’s outer layer is control-flow-flattened Python that rebuilds its identifiers through character-code arithmetic, and beneath it sit seven nested crypter layers, each a block of Base85 text decrypted with AES-CTR, a BLAKE3-keyed XOR, ChaCha20 and AES-GCM in turn, then decompressed with zlib. The innermost layer is a SOCKS5 backconnect client. It opens an outbound TLS connection to its command-and-control server on port 443 with certificate verification disabled, authenticates with an HMAC-SHA256 challenge-response over a pre-shared key, and then speaks length-framed JSON whose first marker is S5BC. The victim host never opens a listening port, and the operator reaches internal systems through the session the client has already established, so any perimeter that permits outbound 443 carries the entire transport.

Egress from servers. A backconnect proxy requires only an outbound connection, so the decisive control is which destinations servers are permitted to reach. Routing server traffic through a categorizing proxy that denies uncategorized and newly registered domains considerably narrows this channel, and long-lived TLS sessions from a server to a destination it has not contacted before are worth alerting on. Segmenting the network by function and tier, and restricting SMB and remote management between segments, limits how far an established proxy session can reach.

Exfiltration

The transfer is the step the operator cleaned up by hand, and a single unplanned crash undid that cleanup. Windows had already written a dump of the failing process hours before the operator deleted the binary, and that dump outlived the deletion. The data left over WinRM, the same channel the backup account used to register the S5PIVOT tasks. SRUM attributes the WinRM host process to that account across several hourly records on the fifth day. That evening the process crashed on a file server, and Windows Error Reporting wrote a heap dump of its private memory. Because the dump caught the process as it ran, it held two AzCopy command lines copying to an attacker-controlled Azure blob container, a complete shared access signature, and the transfer progress at the moment of the crash. It carries no exception record, so we could not say why the process failed.

Windows Error Reporting dump of the WinRM host process, with the AzCopy command lines and the shared access signature redacted.
Windows Error Reporting dump of the WinRM host process, with the AzCopy command lines and the shared access signature redacted.

The two command lines show what the operator was after. Both upload a business data share from the server’s data volume, folder by folder, to the same container, authorized by the shared access signature appended to the destination URL. A shared access signature is a signed token that grants access to the container on its own, so the operator needed no Azure account on the victim’s side, and the traffic went to a Microsoft storage endpoint that outbound filtering rarely blocks. The filters narrow the haul to documents. One switch skips video, audio, images, disk images, executables, libraries, backups, temporary files and logs, and another takes only files changed after a cutoff date, about five years back in one command line and three in the other. A third tells AzCopy never to overwrite what is already in the container, so a repeated run continues where an earlier one stopped, and the memory also holds the error of a launch that failed to start, which fits the operator trying more than once. At the moment of the crash the running job had uploaded 145 of roughly 4,300 files, which AzCopy reported as under one percent of the job, at about 31 megabits per second.

AzCopy left traces on three file servers, always under the backup account. On the crash-dump server and on a second file server it ran from the public profile. On the third, ShimCache records it in the backup account’s download folder next to wa.exe, a file that was gone before collection, so we could neither hash nor examine it. The two files carry the same last-modified time to the microsecond, a time they inherited from the package they were unpacked from rather than the moment they reached the server, so they arrived together. ShimCache flags wa.exe as executed but not azcopy.exe, and SRUM records wa.exe running under the backup account in two hourly records that evening, together a little over an hour of activity. The likeliest reading is that wa.exe is AzCopy under a shorter name, run while the original sat unused beside it. A different tool shipped in the same package would leave the same records, so the indicator table lists wa.exe by name only.

The operator deleted AzCopy and its job folder later that night through the Recycle Bin. The USN journal on the crash-dump server records the binary’s creation in the evening and, a minute and a half later, the .azcopy folder in which AzCopy keeps a plan and a log for every job. About three hours later both went to the Recycle Bin under new names, and seconds after that the bin was emptied. Those job logs would have listed every transferred file, so their deletion is the main reason the volume cannot be measured. The crash dump, ShimCache, SRUM and the journal all outlived it.

The USN journal dating AzCopy's creation, job folder, recycling and purge after the binary was gone.
The USN journal dating AzCopy’s creation, job folder, recycling and purge after the binary was gone.

How much was taken lies beyond those records. The transferred volume, the complete object list, and a second destination cannot be recovered, and the reachable payroll and bookkeeping directories describe exposure we could not confirm as a transfer.

Bulk uploads to cloud storage. Exfiltration through a legitimate cloud service resembles ordinary HTTPS traffic, so volume and context are the most useful signals. We recommend alerting when the outbound volume of a file server substantially exceeds its baseline within a short period, particularly toward *.blob.core.windows.net or other storage endpoints the organization does not use. On the host, a first-seen azcopy.exe, including renamed copies with a matching hash, running from a public profile or a download folder warrants investigation, as does the creation of an .azcopy folder in the profile of an account that does not administer Azure. Where feasible, uploads should be restricted to the organization’s own storage accounts.

Recovery Inhibition and the Encryptor

The same night, the operator moved to prevent recovery and to make the run itself hard to see. Both steps left traces, the first in a copy of the registry that neither the operator nor the encryptor touched, the second in the slack of the logs it emptied.

Recovery Inhibition

The operator prepared each host in the hours before launch, and the encryptor disabled what remained in the first seconds of its run. Most of this can be read only because of RegBack. Windows can keep a second copy of the registry hives in System32\config\RegBack, written by a scheduled maintenance task. Microsoft stopped filling that folder by default in Windows 10 version 1803, but these servers had periodic registry backup switched on, and their copies dated from a few days to about a week before the attack. The copies therefore show each server as it stood before the intrusion, a baseline against which every later change can be read.

On two servers the operator set DisableAntiSpyware to 1 under the Defender policy key, the value behind the Group Policy setting “Turn off Microsoft Defender Antivirus”. Neither server’s RegBack copy contains that policy key at all, so it was created on the night of the attack. Microsoft has deprecated the setting, current Defender platforms ignore it on devices onboarded to Defender for Endpoint, and Tamper Protection blocks it outright. These were Windows Server 2019 hosts with neither Tamper Protection configured nor onboarding to Defender for Endpoint, a configuration for which Microsoft’s documentation still describes the value as turning Defender Antivirus off, so it most likely took effect, although no surviving log or central alert history confirms it. The operator also went after the backup agent. On one server SRUM records the Acronis Cyber Protect uninstaller running four times from the backup account’s temporary folders, and each host was cleanly restarted shortly before its run.

A Defender policy value disabling antispyware, set to 1 during the intrusion in a policy key that the RegBack copy does not contain.
A Defender policy value disabling antispyware, set to 1 during the intrusion in a policy key that the RegBack copy does not contain.

The encryptor then went after local recovery, and on the file server shown below every change landed within about ten seconds of the encryptor writing its Run value. It deletes every shadow copy, and afterward the volume shadow copy service stood at disabled where RegBack still holds its default manual start. The same happened, from automatic start, to both Acronis services, the SQL Server instance with its Browser and VSS Writer, and two MySQL instances, which stops the backup agent and releases the database files for encryption. Two fsutil behavior set SymlinkEvaluation commands switched remote-to-local and remote-to-remote symbolic-link evaluation from 0 to 1, so links reached over a share are followed instead of refused. The encryptor also created MaxMpxCt under the SMB server parameters with the value 65535, the maximum number of requests a client may have outstanding against the server, a change security vendors tie to faster encryption across network shares. All of it was in place before the first file was encrypted.

Backup and database services set to disabled, and the symbolic-link and SMB settings written seconds after the encryptor's Run value.
Backup and database services set to disabled, and the symbolic-link and SMB settings written seconds after the encryptor’s Run value.

The run also left a visible mark. The encryptor writes an embedded image to a temporary file, sets it as the desktop wallpaper of every loaded user profile, and sets the machine lock screen through the PersonalizationCSP registry key. On one file server that key still points to an image in the temporary folder of the local Administrator profile the run came from, which identifies both the account and the session that launched the encryptor there.

Recovery inhibition as a signal. The encryptor’s changes occur in the first seconds of a run, too late to protect the affected host but early enough to contain the encryptor before it reaches further systems. Useful detections are shadow copy deletion, the volume shadow copy service together with backup and database services being set to disabled within a short interval, fsutil behavior set SymlinkEvaluation enabling remote-to-remote or remote-to-local evaluation, MaxMpxCt being written under the SMB server parameters, and LockScreenImagePath under PersonalizationCSP pointing to a user’s temporary folder. Changes to Defender policy on servers should originate only from change management, so an unplanned DisableAntiSpyware value warrants an immediate alert, and Tamper Protection, which on Windows Server 2019 requires onboarding to Defender for Endpoint, prevents the setting from taking effect. Recovery itself depends on backups protected by separate credentials, at least one immutable or offline copy, and regularly tested restores, and the backups that survived in this case did so by chance.

Encryptor Build and Persistence

The encryptor win.exe is a 32-bit Rust Qilin/Agenda build. It carries embedded process and service blacklists, the Microsoft-signed PsExec for distribution, and a vCenter and ESXi spreader. The blacklists matter further down this chain, because the same list decides which processes the encryptor spares when it frees a locked file.

The encryptor's embedded JSON configuration with its process and service blacklists.
The encryptor’s embedded JSON configuration with its process and service blacklists.

It persists through a Run value under the machine hive whose name is an asterisk followed by six random letters, and that asterisk points back to an older technique. Microsoft documents name prefixes only for RunOnce values, where an asterisk forces the command to run even in Safe Mode, in which Windows otherwise skips both Run and RunOnce. Earlier Agenda builds, as Trend Micro documented in 2022, wrote an asterisk-prefixed RunOnce value and restarted the host into Safe Mode before encrypting, because most security software does not load there. This build still contains an optional Safe Mode switch but writes its autostart to Run, and none of the recorded command lines used that switch, so whether Windows honors the asterisk on a Run value is undocumented and we did not test it. On every start the binary replaces its startup command and appends one more --no-admin, which turns the Run value into a counter of how often the encryptor has started on that host.

The encryptor's asterisk-prefixed Run value under the machine hive.
The encryptor’s asterisk-prefixed Run value under the machine hive.

Autostart entries. Run and RunOnce values whose names begin with an asterisk or an exclamation mark are uncommon in legitimate software and are worth alerting on, as are autostart values that point to an executable stored directly in ProgramData. Because such entries execute at the next interactive logon, neutralizing them on every affected host before anyone logs on interactively belongs among the first containment steps of an incident.

Command-Line Flags and the lsass Restarts

That same Run value also preserves the switches each host was launched with, and they explain the damage. On nine of the ten servers that ran the encryptor locally, the recorded command line carried --no-ef --no-ff --no-df. Those switches disabled the encryptor’s exclusion filters, which is consistent with Windows and program directories being encrypted alongside the business data and with several servers no longer booting. One file server held hundreds of thousands of encrypted files.

Eight servers encrypted on the first night shared a command line that also carried --no-destruct --no-domain --no-network and -password <redacted>. The two remaining file servers, whose recorded command lines are later, sat at opposite extremes, one keeping its filters and the other limited to a single data drive. Because the Run value holds only the most recent command line, earlier flags on a host are gone.

With the directory filter off, the encryptor walked system folders where critical processes hold files open, and on six servers lsass.exe died and the host forced a restart. For every file it cannot lock, the file-release routine asks the Restart Manager which processes hold it and terminates every holder except itself and the processes named on its blacklist. lsass is not on that list, so if it held a handle on a file in one of those folders, the routine would have ended it like any other holder. Windows treats the loss of a critical process as unrecoverable and restarts the host.

The restarts survive only as System records carved from log slack, each naming lsass.exe and a forced restart, because the System logs themselves were cleared within the same minute. The one server that kept its filters shows no such restart, which fits the mechanism. We found no known vulnerable driver in the estate’s driver inventory, no staging for process or credential dumping, and no killer binary in any collection, and the string lsass appears in none of the builds examined.

A carved System record naming lsass.exe and a forced restart, recovered from log slack.
A carved System record naming lsass.exe and a forced restart, recovered from log slack.

Critical-process restarts. An unexpected termination of lsass.exe forces Windows to restart and is rare in normal operation. System event 1074 in which wininit.exe initiates the restart and names lsass.exe is therefore a useful alert condition, and several such restarts across servers within one night more likely indicate an encryption run than a stability problem. The records are infrequent and can be collected without an endpoint agent, but they are only useful if they reach central storage before the local logs are cleared.

Hexastrike assesses that the terminations were collateral damage from the file-release routine, the reading that fits both the code and the surviving records. Because the System logs were cleared, the surviving records support this reading without proving it. Logging the restarts as credential access or defense evasion would misdirect the hunt toward a tool we have no evidence of.

Log Clearing and Relaunch

Right after encryption the encryptor cleared the logs on ten servers through a one-line PowerShell command run in repeated passes, which is why most of the chain above had to be read from records other than the logs. On several servers the purge went well past Security and System and emptied nearly every channel, and on one host three clears landed within milliseconds from a single process instance. Where a channel was wiped completely, the attacker’s records survive only in the slack of the log files.

Logs that survive a clear. The log clearing was scripted and thorough, so only copies already stored outside the hosts would have survived it intact, and there were none. We recommend forwarding Security, System, PowerShell and Sysmon events to a central platform as they are written, retaining them for at least 90 days, and alerting on event 1102 and on bursts of event 104. PowerShell script-block logging and a larger NTFS change journal add further coverage, and in this case the journal outlived the clear and dated the deletion of the attacker’s tools. Endpoint detection and response on every host, with alerts triaged by an analyst, would very likely have exposed most of this chain while it was in progress.

Five and ten days after the encryption, the never-removed Run value fired at the interactive logons administrators made to collect evidence, relaunched the encryptor, and deleted shadow copies again. On the first of those hosts the --no-admin counter had grown by one, which proved the launches were new executions, and the S5PIVOT task was still live. This was initially read as an attacker still inside the network.

The Run value relaunching the encryptor during evidence collection, the --no-admin count one higher than the first run.
The Run value relaunching the encryptor during evidence collection, the –no-admin count one higher than the first run.

Handling an active incident. The encryptor relaunches resulted from well-intended actions during the response. We recommend a standing rule that no one logs on interactively to an affected host until its autostart entries and scheduled tasks have been neutralized. Suspicious files should be handed to the incident responders rather than uploaded to public multiscanners, where uploaded content and its metadata can be accessible to third parties, and external parties should receive hashes rather than files.

Conclusion

Entry and movement ran on the neglected basics named at the start, each a known and unaddressed weakness. The other half of the case concerns everything the operator failed to erase. The logs were cleared on ten servers and the reachable tools deleted, yet a crash dump held the exfiltration, a registry value had counted the encryptor’s runs, and the file-system journal recorded the binary’s deletion along with everything before it. Even the forced restarts of lsass, whose channel was wiped within the minute, came back out of the slack.

S5PIVOT, a backconnect proxy that no engine detected at the time of the intrusion and whose crypter leads to further command-and-control domains, matters beyond this victim. Its hashes and domains will rotate, while the shapes recorded here will not, so the durable signal for defenders is structural. An interpreter that runs with no script, a recovery-inhibition registry state, an asterisk-prefixed Run value, a critical-process restart inside an encryption window, and a log-clear burst from one process all outlived the operator’s cleanup. That same durability also worked against the defenders, because the persistence nobody removed fired at the first administrator to log on and looked, for a while, like a second intrusion.

Indicators of Compromise

Note: First Seen and Last Seen values reflect Hexastrike’s observation window for each indicator and do not necessarily represent creation date, registration date, first malicious use, or the full period of operator control.

CategoryTypeValueCommentFirst SeenLast Seen
NetworkDomainsdf557hht5[.]blob[.]core[.]windows[.]netAzCopy exfiltration destination
NetworkDomainsports-chamber[.]comS5PIVOT backconnect endpoint
NetworkDomainkyowa-spring[.]comS5PIVOT backconnect endpoint
NetworkDomainzeroseum[.]comS5PIVOT backconnect endpoint
HostHostnameWIN-HAQ7CEKSGCBRogue host
HostHostnameVPS-362873Rogue host
FileSHA-256a59b1da93649db7f802c81be575034fa4e8def0e298c44aebcbd215027110160S5PIVOT
FileSHA-256228c7ac798b4ffe26fb8439a53fbcfe2453b3a7d6f606f7116e319063f5a9c05S5PIVOT
FileSHA-256f8681f691d1177dd3be9ada794b475d96c3514259cd8e68905101cac19130834S5PIVOT
FileSHA-25681cc9db1c0a1a979fdc9cb351f6e401f4d48fea7bcf69ad2d0ee601c8141832aS5PIVOT
FileSHA-256675e7aeac1e1a95c2a2608319ffd6a197130d17f58639724e28b9ee3cdc974f2S5PIVOT
FileSHA-2569fa892212460b6670fad23f702d12e18a2405ccb8845b20d59615141b9d3b2baS5PIVOT
FileSHA-256709a5116d5634236a3d69db61261ee334d5f61a6537f299eb2114d91cf694399S5PIVOT
FileSHA-256cd578333a4be96988080597063b8e35a46452b578f5f70abf2f81374924bc45eS5PIVOT
FileSHA-256936bed238410aee76f4ad4ff385fdb8dbfbb88a4ba540923e42fdd14c698a5d1S5PIVOT
FileSHA-256c7effa4b730275ccb9df54a468ecda1b59b214d1f73f008bdfb2def53adcca08S5PIVOT
FileSHA-256f138753c6fd62f18317a7455d71dd1f45d0e9cb1edab7d0a0bbe21513c29a088S5PIVOT
FileSHA-2565eac10e0ff9e39597749b54b46400f1f0e5b217117a9be84a61ee1301ef467a4S5PIVOT
FileSHA-2568ab791f083e47086d8286f3ac20fb3d3c5640d3b7a2a68e2cad5e497aa49f31eS5PIVOT
FileSHA-256d651b5d26bcd0979bd85415664ddd73c18458f6fdbb1d3803dc8ae8050181fe9S5PIVOT
FileSHA-2563aabad36c1502b866410c7784c313f47b25d57d3403cb8380bffab9688a1d966S5PIVOT

Table of Contents

About the author
Maurice Fielenbach

Maurice has spent over 10 years in cybersecurity, leading digital forensics and incident response, threat intelligence, and threat hunting. He has managed major security incidents across industries and works more than 100 cases per year. He trains security teams in digital forensics, malware analysis, and threat hunting, and is a regular speaker at industry events. His research has been featured in The Hacker News, Cybersecurity News, and Cryptika.

Training built from real incidents. Sharpening the defenders who matter.