{
	"id": "a6be36c2-a7d2-4f9b-b91a-9580c46ec918",
	"created_at": "2026-04-06T00:09:18.098803Z",
	"updated_at": "2026-04-10T03:21:52.349021Z",
	"deleted_at": null,
	"sha1_hash": "a93660644bce10b06a2fedd095ec6522eef676c1",
	"title": "Advanced CyberChef Techniques For Malware Analysis - Detailed Walkthrough and Examples",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 7224815,
	"plain_text": "Advanced CyberChef Techniques For Malware Analysis - Detailed\r\nWalkthrough and Examples\r\nBy Matthew\r\nPublished: 2024-02-26 · Archived: 2026-04-05 15:55:22 UTC\r\nWe're all used to the regular CyberChef operations like \"From Base64\", From Decimal and the occasional magic\r\ndecode or xor. But what happens when we need to do something more advanced?\r\nCyberchef contains many advanced operations that are often ignored in favour of Python scripting. Few are aware\r\nof the more complex operations of which Cyberchef is capable. These include things like Flow Control, Registers\r\nand various Regular Expression capabilities.\r\nIn this post. We will break down some of the more advanced CyberChef operations and how these can be applied\r\nto develop a configuration extractor for a multi-stage malware loader.\r\nExamples of Advanced Operations in CyberChef\r\nBefore we dive in, let's look at a quick summary of the operations we will demonstrate.\r\nRegisters\r\nRegular Expressions and Capture Groups\r\nFlow Control Via Forking and Merging\r\nMerging\r\nSubtraction\r\nAES Decryption\r\nAfter demonstrating these individually to show the concepts, we will combine them all to develop a\r\nconfiguration extractor for a multi-stage malware sample.\r\nObtaining the Sample\r\nThe sample demonstrated can be found on Malware Bazaar with\r\nSHA256:befc7ebbea2d04c14e45bd52b1db9427afce022d7e2df331779dae3dfe85bfab\r\nAdvanced Operation 1 - Registers\r\nRegisters allow us to create variables within the CyberChef session and later reference them when needed.\r\nRegisters are defined via a regular expression capture group and allow us to create a variable with an unknown\r\nvalue that fits a known pattern within the code.\r\nHow To Use Registers in CyberChef\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 1 of 30\n\nBelow we have a Powershell script utilising AES decryption.\r\nTraditionally, this is easy to decode using CyberChef by manually copying out the key value and pasting it into an\r\n\"AES Decrypt\" Operation.\r\nWe can see the key copied into an AES Decrypt operation.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 2 of 30\n\nThis method of manually copying out the key works effectively, however this means that the key is \"hardcoded\"\r\nand the recipe will not apply to similar samples using the same technique.\r\nIf another sample utilises a different key, then this new key will need to be manually updated for the CyberChef\r\nrecipe to work.\r\nRegisters Example 1\r\nBy utilising a \"Register\" operation, we can develop a regular expression to match the structure of the AES key and\r\nlater access this via a register variable like $R0 to\r\nThe AES key, in this case, is a 44-character base64 string, hence we can use a base64 regular expression of 44-46\r\ncharacters to extract the AES Key.\r\nWe can later access this via the $R0 variable inside of the AES Decrypt operation.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 3 of 30\n\nRegisters Example 2\r\nIn a previous stage of the same sample, the malware utilises a basic subtract operation to create ASCII char codes\r\nfrom an array of large integers.\r\nTraditionally, this would be decoded by manually copying out the 787 value and applying this to a subtract\r\noperation.\r\nHowever, again, this causes issues if another sample utilises the same technique but with a different value.\r\nA better method is to create another register with a regular expression that matches the 787 value.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 4 of 30\n\nHere we can see an example of this, where a Register has been used to locate and store the 787 value inside of\r\n$R0. This can later be referenced in a subtract operation by referencing $R0.\r\nRegular Expressions\r\nRegular expressions are frustrating, tedious and difficult to learn. But they are extremely powerful and you should\r\nabsolutely learn them in order to improve your Cyberchef and malware analysis capability.\r\nIn the development of this configuration extractor, regular expressions are applied in 10 separate operations.\r\nRegular Expressions - Use Case 1 (Registers)\r\nThe first use of regular expressions is inside of the initial register operation.\r\nHere, we have applied a regex to extract a key value used later as part of the deobfuscation process.\r\nThe key use of regex here is to generically capture keys related to the decoding process, avoiding the need to\r\nhardcode values and allowing the recipe to work across multiple samples.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 5 of 30\n\nHow To Use Regular Expressions to Isolate Text\r\nThe second use of regular expressions in this recipe is to isolate the main array of integers containing the second\r\nstage of the malware.\r\nThe second stage is stored inside a large array of decimal values separated by commas and contained in round\r\nbrackets.\r\nBy specifying this inside of a regex, we can extract and isolate the large array and effectively ignore the rest of the\r\ncode. This is in contrast to manually copying out the array and starting a new recipe.\r\nA key benefit here is the ability to isolate portions of the code without needing to copy and paste. This\r\nenables you to continue working inside of the same recipe\r\nRegular Expressions - Use Case 3 (Appending Values)\r\nOccasionally you will need to append values to individual lines of output.\r\nIn these cases, a regular expression can be utilised to capture an entire line (.*) and then replace it with the\r\nsame value (via capture group referenced in $1) followed by another value (our initial register).\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 6 of 30\n\nThe key use case is the ability to easily capture and append data, which is essential for operations like the subtract\r\noperator which will be later used in this recipe.\r\nWe can utilise regular expressions inside of register operations to extract encryption keys and store these inside of\r\nvariables.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 7 of 30\n\nHere, we can see the 44-character AES key stored inside of the $R1 register.\r\nThis is effective as the key is stored in a particular format across samples. Leveraging regex allows us to capture\r\nthis format (44 char base64 inside single quotes) without needing to worry about the exact value.\r\nRegular expressions can be used to isolate base64 text containing content of interest.\r\nThis particular sample stores the final malware stage inside of a large AES Encrypted and Base64 encoded blob.\r\nSince we have already extracted the AES key via registers, we can apply the regex to isolate the primary base64\r\nblob and later perform the AES Decryption.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 8 of 30\n\nThis sample utilises the first 16 bytes of the base64 decoded content to create an IV for the AES decryption.\r\nWe can leverage regular expressions and registers to extract out the first 16 bytes of the decoded content using .\r\n{16} .\r\nThis enables us to capture the IV and later reference it via a register to perform the AES Decryption.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 9 of 30\n\nUsing Regular Expressions To Remove Trailing Null-Bytes\r\nRegular expressions can be used to remove trailing null bytes from the end of data.\r\nThis is particularly useful as sometimes we only want to remove null bytes at the \"end\" of data. Whereas a\r\ntraditional \"remove null bytes\" will remove null bytes everywhere in the code.\r\nIn the sample here, there are trailing null bytes that are breaking a portion of the decryption process.\r\nBy applying a null byte search \\0+$ we can use a find/replace to remove these trailing null bytes.\r\nIn this case, the \\0+ looks for one or more null bytes, and the $ specifies that this must be at the end of the\r\ndata.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 10 of 30\n\nAfter applying this operation, the trailing null bytes are now removed from the end of the data.\r\nHow To Use a Fork in CyberChef\r\nForking allows us to separate values and act on each independently as if they were a separate recipe.\r\nIn the use case below, we have a large array of decimal values, and we need to subtract 787 from every single one.\r\nA major issue here is that in order to subtract 787, we need to append 787 after every single decimal value in the\r\nscreenshot below. This would be a nightmare to do by hand.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 11 of 30\n\nAs the data is structured and separated by commas, we can apply a forking operation with a split delimiter of\r\ncommas and a merge delimiter of newlines.\r\nThe split delimiter is whatever separates the values in your data, but the merge delimiter is how you want your\r\nnew data structured.\r\nAt this point, every new line represents a new input data, and all future operations will act on each line\r\nindependently.\r\nIf we now apply a find-replace operation, we can see that the operation has affected each line individually.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 12 of 30\n\nIf we had applied the same concept without a fork, only a single 787 would have been added to the end of the\r\nentire blob of decimal data.\r\nAfter applying the find/replace, we can continue to apply a subtraction operation and a \"From Decimal\".\r\nThis reveals the decoded text and the next stage of the malware.\r\nNote that the \"Merge Delimiter\" mentioned previously is purely a matter of formatting.\r\nOnce you have decoded your content, as in the screenshot above, you will want to remove the merge delimiter to\r\nensure that all the decoded content is together.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 13 of 30\n\nWe can see the full script after removing the merge delimiter.\r\nHow To Apply a Merge Operation in CyberChef\r\nA merge operation is essentially an \"undo\" for fork operations.\r\nAfter successfully decoding content using a fork, you should apply a merge to ensure that the new content can be\r\nanalysed appropriately.\r\nWithout a merge, all future operations would affect only a single character and not the entire script.\r\nCyberchef is capable of AES Decryption via the AES Decrypt operation.\r\nTo utilise AES decryption, look for the key indicators of AES inside of malware code and align all the variables\r\nwith the AES operation.\r\nFor example, align the Key, Mode, and IV. Then, plug these values into CyberChef.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 14 of 30\n\nEventually, you can effectively automate this using Regular Expressions and Registers, as previously shown.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 15 of 30\n\nUtilising all of these techniques, we can develop a configuration extractor for a NetSupport Loader with 3 separate\r\nscripts that can all be decoded within the same recipe.\r\nThis requires a total of 22 operations which will be demonstrated below.\r\nThe initial script is obfuscated using a large array of decimal integers.\r\nFor each of these decimal values, the number 787 is subtracted and then the result is used as an ASCII charcode.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 16 of 30\n\nTo decode this component, we must\r\nUse a Register to extract the subtraction value\r\nUse a Regular Expression to extract the decimal array\r\nUse Forking to Separate each of the decimal values\r\nUse a regular expression to append the 787 value stored in our register.\r\nApply a Subtract operation to produce ASCII char codes\r\nApply a \"From Decimal\" to produce the 2nd stage\r\nUse a Merge operation to enable analysis of the 2nd stage script.\r\nThe initial subtraction value can be extracted with a register operation and regular expression.\r\nThis must be done prior to additional analysis and decoding to ensure that the subtraction value is stored inside of\r\na register.\r\nThe second step is to extract out the main decimal array using a regular expression and a capture group.\r\nThe capture group ensures that we are isolating the decimal values and ignoring any script content surrounding it.\r\nThis regex looks for decimals or commas [\\d,] of length 1000 or more {1000,} . That are surrounded by\r\nround brackets \\( and \\) .\r\nThe inner brackets without escapes form the capture group.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 17 of 30\n\nOperation 3 - Separating the Decimal Values\r\nThe third operation leverages a Fork to separate the decimal values and act on each of them independently.\r\nThe Fork defines a delimiter at the commas present in the original code, and specifies a Merge Delimiter of \\n\r\nto improve readability.\r\nOperation 4 - Appending the Subtraction Value\r\nThe fourth operation uses a regex find/replace to append the 787 value to the end of each line created by the\r\nforking operation.\r\nNote that we have used (.*) to capture the original decimal value, and have then used $1 to access it again.\r\nThe $R0 is used to access the register that can created in Operation 1.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 18 of 30\n\nOperation 5 - Subtracting the Values\r\nWe can now perform the subtraction operation after appending the 787 value in Operation 4.\r\nThis produces the original ASCII char codes that form the second stage script.\r\nNote that we have specified a space delimiter, as this is what separates our decimal values from our subtraction\r\nvalues in operation 4.\r\nOperation 6 - Decoding ASCII Code In CyberChef\r\nWe can now decode the ASCII codes using a \"From Decimal\" operation.\r\nThis produces the original script. However, the values are separated via a newline due to our previous Fork\r\noperation.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 19 of 30\n\nOperation 7 - Merging the Result\r\nWe now want to act on the new script in it's entirety, we do not want to act on each character independently.\r\nHence, we will undo our forking operation by applying a Merge Operation and modifying the \"Merge Delimiter\"\r\nof our previous fork to an empty space.\r\nStage 2 - Powershell Script With AES Encryption (8 Operations)\r\nAfter 7 operations, we have now uncovered a 2nd stage Powershell script that utilises AES Encryption to unravel\r\nan additional stage.\r\nThe key points in this script that are needed for decrypting are highlighted below.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 20 of 30\n\nTo Decode this stage, we must be able to\r\nUse Registers to Extract the AES Key\r\nUse Regex to extract the Base64 blob\r\nDecode the Base64 blob\r\nUse Registers to extract an Initialization Vector\r\nRemove the IV from the output\r\nPerform the AES Decryption, referencing our registers\r\nUse Regex to Remove Trailing NullBytes\r\nPerform a GZIP Decompression to unlock stage 3\r\nWe must now extract the AES Key and store it using a Register operation.\r\nWe can do this by applying a Register and creating a regex for base64 characters that are exactly 44 characters in\r\nlength and surrounded by single quotes. (We could also adjust this to be a range from 42 to 46)\r\nWe now have the AES key stored inside of the $R1 specifying register.\r\nNow that we have the AES key, we can isolate the primary base64 blob that contains the next stage of the\r\nMalware.\r\nWe can do this with a regular expression for Base64 text that is 100 or more characters in length.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 21 of 30\n\nWe're also making sure to change the output format to \"List Matches\", as we only want the text that matches our\r\nregular expression.\r\nOperation 10 - Decoding The Base64\r\nThis is a straightforward operation to decode the Base64 blob prior to the main AES Decryption.\r\nThe first 16 bytes of the current data form the initialization vector for the AES decryption.\r\nWe can extract this using another Register operation and specifying .{16} to grab the first 16 characters from\r\nthe current blob of data.\r\nWe know that these bytes are the IV due to this code in the original script.\r\nNote how the first 16 bytes are taken after base64 decoding, and then this is set to the IV.\r\nOperation 12 - Dropping the Initial 16 Bytes\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 22 of 30\n\nThe initial 16 bytes are ignored when the actual AES decryption process takes place.\r\nHence, we need to remove them by using a drop bytes operation with a length of 16 ,.\r\nWe know this is the case because the script begins the decryption from an offset of 16 from the data.\r\nThis can be confirmed with the official documentation for TransformFinalBlock.\r\nOperation 13 - AES Decryption\r\nNow that the Key and IV for the AES Decryption have been extracted and stored in registers, we can go ahead and\r\napply an AES Decrypt operation.\r\nNote how we can access our key and IV via the $R1 and $R2 registers that were previously created. We do not\r\nneed to specify a key here.\r\nAlso note that we do need to specify base64 and utf8 for the key and IV, respectively, as these were\r\ntheir formats at the time when we extracted them\r\nWe can also note that ECB mode was chosen, as this is the mode specified in the script.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 23 of 30\n\nOperation 14 - Removing Trailing Null Bytes\r\nThe current data after AES Decryption is compressed using GZIP.\r\nHowever, Gunzip fails to execute due to some random null bytes that are present at the end of the data after AES\r\nDecryption.\r\nOperation 14 involves removing these trailing null bytes using a Regular expression for \"one or more null bytes\r\n\\0+ at the end of the data $\"\r\nWe will leave the \"Replace\" value empty as we want to remove the trailing null bytes.\r\nOperation 15 - GZIP Decompression\r\nWe can now apply a Gunzip operation to perform the GZIP Decompression.\r\nThis will reveal stage 3 of the malicious content, which is another Powershell script.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 24 of 30\n\nNote that we know Gzip was used as it is referenced in stage 2 after the AES Decryption process.\r\nStage 3 - Powershell Script (7 Operations)\r\nWe now have a stage 3 PowerShell script that leverages a very similar technique to stage 1.\r\nThe obfuscated data is again stored in large decimal arrays, with the number 4274 subtracted from each value.\r\nNote that in this case, there are 4 total arrays of integers.\r\nTo Decode stage 3, we must perform the following actions\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 25 of 30\n\nUse Registers to Extract The Subtraction Value\r\nUse Regex to extract the decimal arrays\r\nUse Forking to Separate the arrays\r\nUse another Fork to Separate the individual decimal values\r\nUse a find/replace to append the subtraction value\r\nPerform the Subtraction\r\nRestore the text from the resulting ASCII codes\r\nOur first step of stage 3 is to extract the subtraction value and store it inside a register.\r\nWe can do this by creating another register and implementing a regular expression to capture the value\r\n$SHY=4274 . We can specify a dollar sign, followed by characters, followed by equals, followed by integers,\r\nfollowed by a semicolon.\r\nApply a capture group (round brackets) to the decimal component, as we want to store and use this later.\r\nOperation 17 - Extracting and Isolating the Decimal Arrays\r\nNow that we have the subtraction key, we can go ahead and use a regular expression to isolate the decimal arrays.\r\nWe have chosen a regex that looks for round brackets containing long sequences of integers and commas (at least\r\n30). The inside of the brackets has been converted to a capture group by adding round brackets without escapes.\r\nWe have also selected List Capture Groups new line to list only the captured decimal values and commas.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 26 of 30\n\nOperation 18 - Separating the Arrays With Forking\r\nWe can now separate the decimal arrays by applying a fork operation.\r\nThe current arrays are separated by a new line, so we can specify this as our split delimiter.\r\nIn the interests of readability, we can specify our merge delimiter as a double newline. The double newline does\r\nnothing except make the output easier to read.\r\nOperation 19 - Separating the Decimal Values With another Fork\r\nNow that we've isolated the arrays, we need to isolate the individual integer values so that we can append the\r\nsubtraction value.\r\nWe can do this with another Fork operation, specifying a comma delimiter (as this is what separates our decimal\r\nvalues) and a merge delimiter of newline. Again, this new line does nothing but improve readability.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 27 of 30\n\nOperation 20 - Appending Subtraction Values\r\nWith the decimal values isolated, we can use a previous technique to capture each line and append the subtraction\r\nkey currently stored in $R3 .\r\nWe can see the subtraction key appended to each line containing a decimal value.\r\nOperation 21 - Applying the Subtraction Operation\r\nWe can now apply a subtract operation to subtract the value appended in the previous step.\r\nThis restores the original ASCII char codes so we can decode them in the next step.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 28 of 30\n\nOperation 22 - Decoding the ASCII Codes\r\nWith the ASCII codes restored in their original decimal form, we can apply a from decimal operation to restore the\r\noriginal text.\r\nWe can see the Net.Webclient string, albeit it is spaced out over newlines due to our forking operation.\r\nNow that the content is decoded, we can remove the readability step we added in Operation 19.\r\nThat is, we can remove the Merge Delimiter that was added to improve the readability of steps 20 and 21.\r\nWith the Merge Delimiter removed, The output of the four decimal arrays will now be displayed.\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 29 of 30\n\nVideo Walkthrough\r\nEtt fel inträffade.\r\nDet går inte att köra\r\nJavaScript.\r\nSign up for Embee Research\r\nMalware Analysis, Detection Engineering and Threat Intelligence\r\nNo spam. Unsubscribe anytime.\r\nSource: https://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nhttps://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/\r\nPage 30 of 30",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://embee-research.ghost.io/advanced-cyberchef-operations-netsupport/"
	],
	"report_names": [
		"advanced-cyberchef-operations-netsupport"
	],
	"threat_actors": [],
	"ts_created_at": 1775434158,
	"ts_updated_at": 1775791312,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a93660644bce10b06a2fedd095ec6522eef676c1.pdf",
		"text": "https://archive.orkl.eu/a93660644bce10b06a2fedd095ec6522eef676c1.txt",
		"img": "https://archive.orkl.eu/a93660644bce10b06a2fedd095ec6522eef676c1.jpg"
	}
}