#100DaysofYARA 2024 – Day 47 – Abyss Locker Ransomware (Linux)

According to analysis published by SentinelOne, Abyss Locker has been operating a Linux variant targeting ESXi environments since March 2023. This rule matches strings based on their analysis.

rule MAL_AbyssLocker_Lin_strings {
	meta:
		description = "Matches strings found in SentinelOne analysis of Linux variant of the Abyss Locker ransomware."
		last_modified = "2024-02-16"
		author = "@petermstewart"
		DaysofYara = "47/100"
		ref = "https://www.sentinelone.com/anthology/abyss-locker/"

	strings:
		$a1 = "Usage:%s [-m (5-10-20-25-33-50) -v -d] Start Path"
		$b1 = "esxcli vm process list"
		$b2 = "esxcli vm process kill -t=force -w=%d"
		$b3 = "esxcli vm process kill -t=hard -w=%d"
		$b4 = "esxcli vm process kill -t=soft -w=%d"
		$c1 = ".crypt" fullword
		$c2 = "README_TO_RESTORE"

	condition:
		uint32(0) == 0x464c457f and
		all of them
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 45 – XMRig

XMRig is an open-source cross-platform cryptominer, available on Github and often on compromised webservers following mass-exploitation campaigns. Today’s rule matches strings found in a Windows XMRig sample, which was also flagged up by my generic cryptominer string rule from Day 32.

rule MAL_XMRig_strings {
	meta:
		description = "Matches strings found in XMRig cryptominer samples."
		last_modified = "2024-02-14"
		author = "@petermstewart"
		DaysofYara = "45/100"
		sha256 = "3c54646213638e7bd8d0538c28e414824f5eaf31faf19a40eec608179b1074f1"

	strings:
		$a1 = "Usage: xmrig [OPTIONS]"
		$a2 = "mining algorithm https://xmrig.com/docs/algorithms"
		$a3 = "username:password pair for mining server"
		$a4 = "--rig-id=ID"
		$a5 = "control donate over xmrig-proxy feature"
		$a6 = "https://xmrig.com/benchmark/%s"
		$a7 = "\\xmrig\\.cache\\"
		$a8 = "XMRIG_INCLUDE_RANDOM_MATH"
		$a9 = "XMRIG_INCLUDE_PROGPOW_RANDOM_MATH"
		$a10 = "'h' hashrate, 'p' pause, 'r' resume, 's' results, 'c' connection"

	condition:
		7 of them
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 42 – CobaltStrike HTA Loader

One other aspect of CobaltStrike I hadn’t seen many public YARA rules for is the HTA Beacon loader, so that’s what today’s rule tries to match.

Again, this rule uses YARA’s base64 modifier and so may not work on older versions.

rule MAL_CobaltStrike_HTA_loader {
    meta:
        description = "Matches strings found in CobaltStrike HTA loader samples."
        last_modified = "2024-02-11"
        author = "@petermstewart"
        DaysofYara = "42/100"
        sha256 = "2c683d112d528b63dfaa7ee0140eebc4960fe4fad6292c9456f2fbb4d2364680"
        ref = "https://embee-research.ghost.io/malware-analysis-decoding-a-simple-hta-loader/"

    strings:
        $header = "<script>"
        $a1 = "%windir%\\\\System32\\\\"
        $a2 = "/c powershell -w 1 -C"
        $b1 = "-namespace Win32Functions" base64 wide
        $b2 = "[Byte[]];[Byte[]]$" base64 wide
        $b3 = "{Start-Sleep 60};" base64 wide
        $b4 = "[System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes(" base64 wide
        $b5 = "\\syswow64\\WindowsPowerShell\\v1.0\\powershell\";iex" base64 wide
        $b6 = "else{;iex \"& powershell" base64 wide

    condition:
        $header at 0 and
        all of them
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 41 – Base64-Encoded CobaltStrike PowerShell Loader

In my day job I most commonly find CobaltStrike Beacon payloads executed via base64-encoded PowerShell following an initial compromise; maybe phishing or a web application vulnerability leading to command execution. Encoding the command means the threat actor doesn’t need to worry about matching quotes, brackets, etc when passing the command over the channel.

This rule uses YARA’s base64 modifier to match encoded variants of the loader command.

rule MAL_CobaltStrike_Powershell_loader_base64 {
    meta:
        description = "Matches base64-encoded strings found in CobaltStrike PowerShell loader commands."
        last_modified = "2024-02-10"
        author = "@petermstewart"
        DaysofYara = "41/100"

    strings:
        $a1 = "=New-Object IO.MemoryStream(" base64 wide
        $a2 = "[Convert]::FromBase64String(" base64 wide
        $a3 = "IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()" base64 wide

    condition:
        all of them
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 40 – CobaltStrike PowerShell Loader

I deal with CobaltStrike pretty much every day in my job and in my experience it is by far the most commonly abused C2 framework. CobaltStrike isn’t new and there is already a huge collection of public research and detections available; Google, for example, published an extensive collection of YARA rules in 2022. One aspect that I did not find a public rule for though was the PowerShell Beacon loader:

rule MAL_CobaltStrike_Powershell_loader {
    meta:
        description = "Matches strings found in CobaltStrike PowerShell loader samples."
        last_modified = "2024-02-09"
        author = "@petermstewart"
        DaysofYara = "40/100"
        sha256 = "9c9e8841d706406bc23d05589f77eec6f8df6d5e4076bc6a762fdb423bfe8c24"
        sha256 = "6881531ab756d62bdb0c3279040a5cbe92f9adfeccb201cca85b7d3cff7158d3"
        ref = "https://medium.com/@cybenfolland/deobfuscating-a-powershell-cobalt-strike-beacon-loader-c650df862c34"
        ref = "https://forensicitguy.github.io/inspecting-powershell-cobalt-strike-beacon/"

    strings:
        $a1 = "=New-Object IO.MemoryStream("
        $a2 = "[Convert]::FromBase64String("
        $a3 = "IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()"
        $b1 = "Set-StrictMode -Version 2"
        $b2 = "$DoIt = @'"
        $b3 = "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($DoIt))"
        $b4 = "start-job { param($a) IEX $a }"

    condition:
        all of ($a*) or
        all of ($b*)
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 39 – Mythic Athena Agent

Mythic is an open-source C2 framework designed to be modular and compatible with multiple agents and C2 profiles.

Today’s rule matches strings found in the cross-platform .NET Athena agent:

rule MAL_Mythic_Athena_strings {
    meta:
        description = "Matches strings found in samples of the Athena agent used by the open-source Mythic framework."
        last_modified = "2024-02-08"
        author = "@petermstewart"
        DaysofYara = "39/100"
        sha256 = "8075738035ac361d50db2c2112a539acc3f1ad4d4ed5f971b2e18c687fc029da"
        sha256 = "ce66c7487e56722f34e5fd0fea167f9c562a0bbb0d13128b0313e4d3eabff697"
        ref = "https://github.com/MythicAgents/athena"

    strings:
        $a = "Athena"
        $b1 = "\"Athena.Commands\":"
        $b2 = "\"Athena.Forwarders.SMB\":"
        $c1 = "\"cat\":"
        $c2 = "\"drives\":"
        $c3 = "\"get-clipboard\":"
        $c4 = "\"get-localgroup\":"
        $c5 = "\"get-sessions\":"
        $c6 = "\"get-shares\":"
        $c7 = "\"hostname\":"
        $c8 = "\"ifconfig\":"
        $c9 = "\"ls\":"
        $c10 = "\"mkdir\":"
        $c11 = "\"mv\":"
        $c12 = "\"ps\":"
        $c13 = "\"pwd\":"
        $c14 = "\"rm\":"
        $c15 = "\"shell\":"
        $c16 = "\"shellcode\":"
        $c17 = "\"whoami\":"

    condition:
        uint16(0) == 0x5a4d and
        #a > 100 and
        all of ($b*) and
        8 of ($c*)
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 38 – Mythic Apfell Agent

Mythic is an open-source C2 framework designed to be modular and compatible with multiple agents and C2 profiles.

Today’s rule matches strings found in the macOS Apfell agent:

rule MAL_Mythic_Apfell_strings {
    meta:
        description = "Matches strings found in samples of the macOS Apfell Javascript agent used by the open-source Mythic framework."
        last_modified = "2024-02-07"
        author = "@petermstewart"
        DaysofYara = "38/100"
        sha256 = "8962ad7c608962c637637b9d3aef101a87cfb71873210046d5a49cfa6f47a712"
        ref = "https://github.com/MythicAgents/apfell"

    strings:
        $a1 = "C2.checkin(ip,apfell.pid,apfell.user,ObjC.unwrap(apfell.procInfo.hostName),apfell.osVersion,"
        $a2 = "return this.interval + (this.interval * (this.get_random_int(this.jitter)/100));"
        $a3 = "let info = {'ip':ip,'pid':pid,'user':user,'host':host,'uuid':apfell.uuid, \"os\":os, \"architecture\": arch, \"domain\": domain, \"action\": \"checkin\"};"
        $b1 = "\"user\": apfell.user,"
        $b2 = "\"fullName\": apfell.fullName,"
        $b3 = "\"ips\": apfell.ip,"
        $b4 = "\"hosts\": apfell.host,"
        $b5 = "\"environment\": apfell.environment,"
        $b6 = "\"uptime\": apfell.uptime,"
        $b7 = "\"args\": apfell.args,"
        $b8 = "\"pid\": apfell.pid,"
        $b9 = "\"apfell_id\": apfell.id,"
        $b10 = "\"payload_id\": apfell.uuid"
        $c1 = "-IMPLANT INFORMATION-"
        $c2 = "-Base C2 INFORMATION-"
        $c3 = "-RESTFUL C2 mechanisms -"
        $c4 = "- INSTANTIATE OUR C2 CLASS BELOW HERE IN MAIN CODE-"
        $c5 = "-SHARED COMMAND CODE -"
        $c6 = "-GET IP AND CHECKIN -"
        $c7 = "-MAIN LOOP -"
        $c8 = "//To create your own C2, extend this class and implement the required functions"
        $c9 = "//gets a file from the apfell server in some way"
        $c10 = "//there is a 3rd slash, so we need to splice in the port"
        $c11 = "//generate a time that's this.interval += (this.interval * 1/this.jitter)"
        $c12 = "// now we need to prepend the IV to the encrypted data before we base64 encode and return it"
        $c13 = "// Encrypt our initial message with sessionID and Public key with the initial AES key"
        $c14 = "//depending on the amount of data we're sending, we might need to chunk it"
        $c15 = "//if we do need to decrypt the response though, do that"
        $c16 = "// don't spin out crazy if the connection fails"
        $c17 = "// always round up to account for chunks that are < chunksize;"
        $c18 = "//simply run a shell command via doShellScript and return the response"
        $c19 = "//  so I'll just automatically fix this so it's not weird for the operator"
        $c20 = "//  params should be {\"cmds\": \"cmd1 cmd2 cmd3\", \"file_id\": #}"

    condition:
        (all of ($a*) and 8 of ($b*)) or
        (15 of ($c*))
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 37 – Mythic Apollo Agent

Mythic is an open-source C2 framework designed to be modular and compatible with multiple agents and C2 profiles.

Today’s rule matches strings found in the Windows Apollo agent:

rule MAL_Mythic_Apollo_strings {
    meta:
        description = "Matches strings found in samples of the Windows Apollo agent used by the open-source Mythic framework."
        last_modified = "2024-02-06"
        author = "@petermstewart"
        DaysofYara = "37/100"
        sha256 = "bf3d47335b7c10f655987cfdefecdb2856c0ac90f2f1cedcd67067760a80aa98"
        sha256 = "67b2c1c5d96a7c70b2bc111ace08b35e0db63bef40534dc50a692d46f832d61a"
        ref = "https://github.com/MythicAgents/apollo"

    strings:
        $pdb = "Apollo.pdb"
        $a = "ApolloInterop"
        $b1 = "ApolloTrackerUUID"
        $b2 = "Apollo.Peers.SMB"
        $b3 = "Apollo.Peers.TCP"
        $b4 = "C2ProfileData"
        $b5 = "mythicFileId"
        $b6 = "IMythicMessage"
        $b7 = ".MythicStructs"
        $b8 = ".ApolloStructs"
        $b9 = "Apollo.Api"
        $b10 = "ApolloLogonInformation"

    condition:
        uint16(0) == 0x5a4d and
        ($pdb and #a > 15) or
        ($a and (6 of ($b*)))
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 36 – Nimplant

Nimplant is an open-source, lightweight, first-stage implant initially developed by Cas van Cooten and available for download on Github.

rule MAL_Nimplant_strings {
    meta:
        description = "Matches strings found in open-source Nimplant samples."
        last_modified = "2024-02-05"
        author = "@petermstewart"
        DaysofYara = "36/100"
        sha256 = "4d7eb09c35a644118af702dd402fd9f5a75e490d33e86b6746e6eb6112c5caa7"
        sha256 = "90a5e330d411d84a09ef4af07d2b9c808acc028a91fa7e1d57c4f063e91fad49"
        ref = "https://github.com/chvancooten/NimPlant"

    strings:
        $ver = "NimPlant v"
        $header1 = "@Content-Type"
        $header2 = "@X-Identifier"
        $header3 = "@User-Agent"
        $cmd1 = "getLocalAdm"
        $cmd2 = "getAv"

    condition:
        uint16(0) == 0x5a4d and
        filesize > 300KB and filesize < 1MB and
        all of them
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.

#100DaysofYARA 2024 – Day 35 – Sliver C2 Framework

Sliver is an open-source, cross-platform C2 framework developed by Bishop Fox. This rule matches strings found in the Windows, Linux, and macOS variants of the Sliver implant.

rule MAL_Sliver_implant_strings {
	meta:
		description = "Matches strings found in open-source Sliver beacon samples."
		last_modified = "2024-02-04"
		author = "@petermstewart"
		DaysofYara = "35/100"
		sha256 = "6037eaaa80348d44a51950b45b98077b3aeb16c66a983a8cc360d079daaaf53e"
		sha256 = "98df535576faab0405a2eabcd1aac2c827a750d6d4c3d76a716c24353bedf0b5"
		sha256 = "789e5fcb242ee1fab8ed39e677d1bf26c7ce275ae38de5a63b4d902c58e512ec"

	strings:
		$a1 = "bishopfox/sliver"
		$a2 = "sliver/protobuf"
		$a3 = "protobuf/commonpbb"
		$b1 = "ActiveC2Fprotobuf:\"bytes,11,opt,name="
		$b2 = "ProxyURLFprotobuf:\"bytes,14,opt,name="
		$b3 = "BeaconJitterNprotobuf:\"varint,3,opt,name="
		$b4 = "BeaconIntervalRprotobuf:\"varint,2,opt,name="
		$b5 = "BeaconIDEprotobuf:\"bytes,8,opt,name="
		$b6 = "BeaconID"
		$b7 = "GetBeaconJitter"
		$b8 = "BeaconRegister"

	condition:
		(filesize > 5MB and filesize < 20MB) and
		(uint16(0) == 0x5a4d or 		//PE
		uint32(0) == 0x464c457f or 		//ELF
		uint32(0) == 0xfeedface or  	//MH_MAGIC
		uint32(0) == 0xcefaedfe or  	//MH_CIGAM
		uint32(0) == 0xfeedfacf or  	//MH_MAGIC_64
		uint32(0) == 0xcffaedfe or 	 	//MH_CIGAM_64
		uint32(0) == 0xcafebabe or  	//FAT_MAGIC
		uint32(0) == 0xbebafeca) and	//FAT_CIGAM
		2 of ($a*) or
		6 of ($b*)
}

Find the rest of my 100DaysofYARA posts here, and the rules themselves on my Github repository.