Hi, today @ViriBack tweeted botnet echida and here I wrote a rule.
alert http any any -> any any (msg: "ET MALWARE [ANY.RUN] Echida Botnet Check-In";flow: established, to_server; http.method; content: "POST"; http.uri; content: "/connect_bot.php"; endswith; http.header; content: "Content-Type: application/x-www-form-urlencoded"; depth: 47; http.header_names; content:!"Referer|0d 0a|"; content:!"User-Agent|0d 0a|";http.request_body;content: "data="; depth: 5;base64_decode: bytes 120, offset 5; base64_data;content: "(*)Microsoft"; classtype: command-and-control;reference: md5,68e3359674ee7d49550b09e7ff69dcce;reference: url,twitter.com/ViriBack/status/1698693553168236869?s=20;sid: 1; rev: 1;)
Perhaps in the future we will have to go back and make the rule wider in the URI buffer ¯\(°_o)/¯
Best regards, Jane.
2 Likes
Greetings Jane,
As always we’re thankful to have your eyes on the community and your rule writing expertise helping the community at large. I made a couple of slight changes to your initial rule:
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"ET MALWARE [ANY.RUN] Echida Botnet Check-In M1"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"/connect_bot.php"; fast_pattern; endswith; http.content_type; content:"application/x-www-form-urlencoded"; http.header_names; content:!"Referer|0d 0a|"; content:!"User-Agent|0d 0a|"; http.request_body; content:"data="; startswith; base64_decode:bytes 120, relative; base64_data; content:"|28 2a 29|Microsoft"; classtype:command-and-control; reference:md5,68e3359674ee7d49550b09e7ff69dcce; reference:url,twitter.com/ViriBack/status/1698693553168236869; sid:1; rev:1;)
-
Added fast_pattern
to /connect_bot
. Can’t say I like it, but you can’t fast_pattern on base64 data, and if we left it with no fast_pattern, it would’ve chosen the URL encoding string as the fast pattern, which would’ve been considerably worse.
-
Used the http.content_type
buffer instead of having to hop around the HTTP header to search for the urlencoding string.
-
Used startswith
on the data=
content match in the http.request_body
buffer.
-
Changed base64_decode
to: bytes: 120, relative;
, because the base64 data begins relative to that data=
content match.
-
Changed the base64_data
content match to|28 2f 29|Microsoft
(hex codes for (*)). This is mainly just an ET style change.
Finally, I saw the /command_bot
GET request in the same TCP stream, and figured it was unique enough to make a signature, so I made the following:
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"ET MALWARE [ANY.RUN] Echida Botnet Check-In M2"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"/command_bot.php?hwid="; fast_pattern; pcre:"/^[A-F0-9]{32}/R"; http.accept; content:"application/x-www-form-urlencoded"; http.content_type; content:"application/x-www-form-urlencoded"; http.header_names; content:!"Referer|0d 0a|"; content:!"User-Agent|0d 0a|"; classtype:command-and-control; reference:md5,68e3359674ee7d49550b09e7ff69dcce; reference:url,twitter.com/ViriBack/status/1698693553168236869; sid:2; rev:1;)
Once again, we are always appreciative of your help and assistance, and these rules will be made part of the ETOPEN ruleset today with the daily rule update.
Cheers,
Tony Robinson
2 Likes
Thanks for the edits, I’m always interested in learning best practices from you.
Jane (✿◠‿◠)
1 Like
Thanks @Jane0sint @trobinson667!
- 2047921 - ET MALWARE [ANY.RUN] Echida Botnet Check-In M1 (malware.rules)
- 2047922 - ET MALWARE [ANY.RUN] Echida Botnet Check-In M2 (malware.rules)
1 Like