SIGS: APT28 HATVIBE.loader & CHERRYSPY.Backdoor

Page 4 of reference
alert tcp $HOME_NET any → $EXTERNAL_NET $HTTP_PORTS (msg:“ET MALWARE HATVIBE.loader Russia APT28 HTTP PUT Request”; flow:established,to_server; content:“PUT”; http_method; nocase; urilen:11; content:“/verify-php”; http_uri; depth:11; fast_pattern; content:“Content-Type|3A| application/json”; http_header; content:“{|22|”; http_client_body; depth:2; content:“|22 3A 22|”; http_client_body; distance:0; content:“|22 27|, |22|”; http_client_body; distance:0; content:“|22| |3A 22|”; http_client_body; distance:0; content:“|22|,|22|”; http_client_body; distance:0; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151001; rev:1;)

Page 6 of reference. Initial KAF part, then CRC is SHA256 before next field hence 32 distance for PUB. HTTPS encrypted.
alert tcp $HOME_NET any → $EXTERNAL_NET $HTTP_PORTS (msg:“ET MALWARE CHERRYSPY.Backdoor Russia APT28 Initial Key Exchange”; flow:established,to_server; content:“POST”; http_method; nocase; content:|22|{|22|USR_KAF|22 3A|“; http_client_body; depth:12; content:”|22|USR_CRC|22 3A| |22|“; http_client_body; distance:0; content:”|22|, |22|USR_PUB|22 3A|"; http_client_body; distance:32; within:13; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151002; rev:1;)

Page 7 of reference
alert tcp $EXTERNAL_NET $HTTP_PORTS → $HOME_NET any (msg:“ET MALWARE CHERRYSPY.Backdoor Russia APT28 Key Exchange Response; flow:established,to_client; file_data; content:”{|22|TSK_KEY|22 3A|“; within:11; content:”|22|TSK_IV|22 3A|“; distance:0; content:”|22|TSK_BODY|22 3A|"; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151003; rev:1;)

Kind Regards,
Kevin

Thank you for submitting these rules. I’ve included them for the daily ruleset update today. As with the other rules, I’ve made a handful of slight changes here and there:

snort:
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"ET MALWARE HATVIBE.loader Russia APT28 HTTP PUT Request"; flow:established,to_server; content:"PUT"; http_method; nocase; urilen:11; content:"/verify-php"; http_uri; depth:11; fast_pattern; content:"Content-Type|3A| application/json"; http_header; content:"|7b 22|"; http_client_body; depth:2; content:"|22 3a|1|7d|"; http_client_body; distance:0; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151001; rev:1;)

suricata:
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"ET MALWARE HATVIBE.loader Russia APT28 HTTP PUT Request"; flow:established,to_server; http.method; content:"PUT"; http.uri; bsize:11; content:"/verify-php"; fast_pattern; http.content_type; content:"application/json"; http.request_body; content:"|7b 22|"; startswith; content:"|22 3a|1|7d|"; endswith; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151001; rev:1;)

Focused on the HTTP uri as a fast_pattern, and that the HTTP PUT body is JSON, looking for the initial |7b 22| at the start, and |22 3a|1|7d| at the very end.

snort:
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"ET MALWARE CHERRYSPY.Backdoor Russia APT28 Initial Key Exchange"; flow:established,to_server; flowbits:set,ET.CherrySpy.Backdoor.KeyExchange; content:"POST"; http_method; nocase; content:"|7b|"; http_client_body; depth:1; content:"|22|USR_KAF|22 3A|; http_client_body; fast_pattern; content:"|22|USR_CRC|22 3A|"; http_client_body; content:"|22|USR_PUB|22 3A|"; http_client_body; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151002; rev:1;)

suricata:
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"ET MALWARE CHERRYSPY.Backdoor Russia APT28 Initial Key Exchange"; flow:established,to_server; flowbits:set,ET.CherrySpy.Backdoor.KeyExchange; http.method; content:"POST"; http.request_body; content:"|7b|"; startswith; content:"|22|USR_KAF|22 3A|"; fast_pattern; content:"|22|USR_CRC|22 3A|"; content:"|22|USR_PUB|22 3A|"; content:"|7d|"; endswith; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151002; rev:1;)

Again, focused on this being JSON data in the http request body. Added a content match for |7b| at the start, and |7d| at the end.

added the flowbit ET.CherrySpy.Backdoor.KeyExchange

removed distance:0 between parameters in order to catch network traffic in which the JSON parameters are arbitrarily moved.

snort:
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"ET MALWARE CHERRYSPY.Backdoor Russia APT28 Key Exchange Response"; flow:established,to_client; flowbits:isset,ET.CherrySpy.Backdoor.KeyExchange; file_data; content:"{|22|TSK_KEY|22 3A|"; within:11; content:"|22|TSK_IV|22 3A|"; distance:0; content:"|22|TSK_BODY|22 3A|"; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151003; rev:1;)

suricata:
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"ET MALWARE CHERRYSPY.Backdoor Russia APT28 Key Exchange Response"; flow:established,to_client; flowbits:isset,ET.CherrySpy.Backdoor.KeyExchange; http.response_body; content:"|22|TSK_KEY|22 3A|"; fast_pattern; content:"|22|TSK_IV|22 3A|"; content:"|22|TSK_BODY|22 3A|"; classtype:trojan-activity; reference:url,go.recordedfuture.com/hubfs/reports/CTA-RU-2024-1121.pdf; reference:url,cert.gov.ua/article/4697016; sid:151003; rev:1;)

removed distance:0; in the http response body parameters. in order to account for the parameters having the order changed.

added a check to see if the flowbit ET.CherrySpy.Backdoor.KeyExchange has been set.

thanks,

-Tony

I had a bit of a mixup. The distance should be 64 characters for SHA256 as 32 bytes so distance should be 64 on the CHERRYSPY.