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.