//MZ header //PE signature //The malware family seems to share many exports //but this is the new kid on the block.
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 200KB and pe.exports("cfsUpdate")
}
rule new_keyboy_header_codes
{
meta:
author = "Matt Brooks, @cmatthewbrooks"
desc = "Matches the 2016 sample's header codes"
...
...
@@ -96,17 +89,8 @@ rule new_keyboy_header_codes
$s7 = "*h*" wide fullword
condition:
//MZ header
uint16(0) == 0x5A4D and
//PE signature
uint32(uint32(0x3C)) == 0x00004550 and
filesize < 200KB and
all of them
//MZ header //PE signature
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 200KB and all of them
}
...
...
@@ -120,6 +104,7 @@ rule new_keyboy_header_codes
rule keyboy_commands
{
meta:
author = "Matt Brooks, @cmatthewbrooks"
desc = "Matches the 2016 sample's sent and received commands"
...
...
@@ -141,21 +126,13 @@ rule keyboy_commands
$s12 = "FileManager" wide fullword
condition:
//MZ header
uint16(0) == 0x5A4D and
//PE signature
uint32(uint32(0x3C)) == 0x00004550 and
filesize < 200KB and
6 of them
//MZ header //PE signature
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 200KB and 6 of them
}
rule keyboy_errors
{
meta:
author = "Matt Brooks, @cmatthewbrooks"
desc = "Matches the sample's shell error2 log statements"
...
...
@@ -191,22 +168,14 @@ rule keyboy_errors
$s22 = "WriteFile [%s} Error(%d)..." ascii wide
condition:
//MZ header
uint16(0) == 0x5A4D and
//PE signature
uint32(uint32(0x3C)) == 0x00004550 and
filesize < 200KB and
$error and 3 of ($s*)
//MZ header //PE signature
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 200KB and $error and 3 of ($s*)
}
rule keyboy_systeminfo
{
meta:
author = "Matt Brooks, @cmatthewbrooks"
desc = "Matches the system information format before sending to C2"
...
...
@@ -230,25 +199,15 @@ rule keyboy_systeminfo
$s13 = "DisplayMode: %d x %d, %dHz, %dbit" ascii wide
$s14 = "Uptime: %d Days %02u:%02u:%02u" ascii wide
condition:
//MZ header
uint16(0) == 0x5A4D and
//PE signature
uint32(uint32(0x3C)) == 0x00004550 and
filesize < 200KB and
7 of them
//MZ header //PE signature
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 200KB and 7 of them
}
rule keyboy_related_exports
{
meta:
author = "Matt Brooks, @cmatthewbrooks"
desc = "Matches the new 2016 sample's export"
...
...
@@ -256,52 +215,24 @@ rule keyboy_related_exports
md5 = "495adb1b9777002ecfe22aaf52fcee93"
condition:
//MZ header
uint16(0) == 0x5A4D and
//PE signature
uint32(uint32(0x3C)) == 0x00004550 and
filesize < 200KB and
//The malware family seems to share many exports
//but this is the new kid on the block.
pe.exports("Embedding") or
pe.exports("SSSS") or
pe.exports("GetUP")
//MZ header //PE signature //The malware family seems to share many exports //but this is the new kid on the block.
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 200KB and pe.exports("Embedding") or pe.exports("SSSS") or pe.exports("GetUP")
}
// Note: The use of the .Init section has been observed in nearly
// all samples with the exception of the 2013 VN dropper from the
// Rapid7 blog. The config data was stored in that sample's .data
// section.
rule keyboy_init_config_section
{
meta:
author = "Matt Brooks, @cmatthewbrooks"
desc = "Matches the Init section where the config is stored"
date = "2016-08-28"
condition:
//MZ header
uint16(0) == 0x5A4D and
//PE signature
uint32(uint32(0x3C)) == 0x00004550 and
//Payloads are normally smaller but the new dropper we spotted
//is a bit larger.
filesize < 300KB and
//Observed virtual sizes of the .Init section vary but they've
//always been 1024, 2048, or 4096 bytes.
for any i in (0..pe.number_of_sections - 1):
(
pe.sections[i].name == ".Init" and
pe.sections[i].virtual_size % 1024 == 0
)
//MZ header //PE signature //Payloads are normally smaller but the new dropper we spotted //is a bit larger. //Observed virtual sizes of the .Init section vary but they've //always been 1024, 2048, or 4096 bytes.
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and filesize < 300KB and for any i in (0..pe.number_of_sections - 1): (pe.sections[i].name == ".Init" and pe.sections[i].virtual_size % 1024 == 0)