Variant.Kazy.53640: Lessons in Camouflage Using Clear Plastic Tarps and Air Horns
My day started off today like most here at ET Pro. I grabbed my morning cup of coffee, checked email, handled some community-related items and began to look at a sample (md5:a01d75158cf4618677f494f9626b1c4c) one community member found “interesting.” Right away we could tell that the sample was trying to evade detection by attempting to camouflage itself as normal SSL traffic. As you can see from the screen shot below, it fails miserably. The Session ID and Cipher Suite lengths are way longer than Client Hello length specified.
Additionally after running the sample through multiple sandboxes and on various zombies, it seems that this piece of badness always uses a static SSL record length of 55 and a Client Hello length of 51. Using Snort 2.9.x or Suricata, we can use byte_extract to validate that the SessionID length and Cipher Suite length are not longer than the Client Hello length (rules below). It will be interesting to see if this hits anywhere else, because this behavior should never be seen in a normal Client Hello. Perhaps this is an attempt by the malware authors to evade NIDS that auto-ignore SSL. Why take the trouble to try to hide in something that sort of looks like SSL when you can just use SSL? Weird…
alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ETPRO TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Session_Id length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”;
depth:3; content:”|01|”; distance:2; within:1; byte_extract:3,0,SSL.Client_Hello.length,relative; byte_test:1,>,SSL.Client_Hello.length,34,relative; reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014634; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ETPRO TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Cipher_Suite length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”; depth:3; content:”|01|”; distance:2; within:1; byte_extract:3,0,SSL.Client_Hello.length,relative; byte_jump:1,34,relative; byte_test:2,>,SSL.Client_Hello.length,0,relative;reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014635; rev:1;)
For older Snort we went ahead and just used byte_test/byte_jump to check against the static value used in the Client Hello(51).
alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ET TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Session_Id length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”; depth:3; content:”|01 00 00 33 03 00|”; distance:2; within:6; byte_test:1,>,51,32,relative; reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014634; rev:3;)
alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ET TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Cipher_Suite length greater than Client_Hello Length)”; Cipher_Suite length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”; depth:3; content:”|01 00 00 33 03 00|”; distance:2; within:6; byte_jump:1,32,relative; byte_test:2,>,51,0,relative; reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014635; rev:2;)
