← Back to SOC feed Coverage →

Code and strings of plugins from the Tetris framework loaded by Swid

yara LOW signature-base
florian-roth
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at signature-base →
Retrieved: 2026-08-03T11:00:00Z · Confidence: medium

Hunt Hypothesis

This detection identifies adversaries leveraging the Tetris framework to load plugin code via SWID tags, a technique often used for stealthy lateral movement or persistent execution within Azure environments. Proactive hunting is essential because these low-severity events may indicate early-stage reconnaissance or supply chain compromise that could escalate into significant threats if not identified before broader impact occurs.

YARA Rule

rule apt_CN_Tetrisplugins_JS {
   meta:
      author = "@imp0rtp3"
      description = "Code and strings of plugins from the Tetris framework loaded by Swid"
      reference = "https://imp0rtp3.wordpress.com/2021/08/12/tetris"
      date = "2020-09-06"

      id = "83e6fbad-55d6-5229-a17d-8929e0e658f8"
   strings:
      // Really unique strings
      $a3 = "(0xbb8);this['socketWatcher'](0xbb9);this["
      $a4 = "a2869674571f77b5a0867c3d71db5856"
      $a5 = "\\x0a\\x20\\x20var\\x20data\\x20=\\x20{}\\x0a\\x20\\x20window.c\\x20=\\x200\\x0a\\x20\\x20script2\\x20=\\x20document.createElement(\\x22script\\x22)\\x0a\\x20\\x20script2.async\\x20=\\x20true\\x0a\\x20\\x20script2.src\\x20=\\x20\\x22"
      $a6 = "{isPluginCallback:\\x20true,\\x20data,\\x20plugin:\\x20'"
      $a7 = "\\x20\\x22*\\x22)\\x0a\\x20\\x20}\\x0a\\x20\\x20document.documentElement.appendChild("

      // Still quite unique, but FP possible
      $b1 = "String(str).match(/red\">(.*?)<\\/font>/)"
      $b2 = "['data']);}};}},{'key':'run','value':function _0x"
      $b3 = "},{'plugin':this['plugin'],'save':!![],'type':_typeof("
      $b4 = "Cannot\\x20call\\x20a\\x20class\\x20as\\x20a\\x20function"
      $b5 = "The\\x20command\\x20is\\x20sent\\x20successfully,\\x20wait\\x20for\\x20the\\x20result\\x20to\\x20return"
      $b6 = "getUserMedia\\x20is\\x20not\\x20implemented\\x20in\\x20this\\x20browser"
      $b7 = "{'autoplay':'true'},!![]);setTimeout(function(){return $('#'+"
      $b8 = "keyLogger($('input'));\n        keyLogger($('textarea'));"
      $b9 = "api.loadJS(\"\".concat(api.base.baseUrl"
      $b10 = "\"\".concat(imgUrls[i], \"?t=\""
      $b11 = "key: \"report\",\n      value: function report(data) {\n        return this.api.callback"
      $b12 = "that.api.base.debounce("
      $b13 = "'className','restOfNavigator','push'"
      $b14 = ";};'use strict';function _typeof("

      // Rare strings, but not unique
      $c1 = "/public/dependence/jquery"
      $c2 = "'http://bn6kma5cpxill4pe.onion/static/images/tor-logo1x.png'"
      $c3 = "'163.com not login';"
      $c4 = "'ws://localhost:'"
      $c5 = "function _typeof(obj) { \"@babel/helpers - typeof\"; "
      $c6 = "'socketWatcher'"
      $c7 = "['configurable']=!![];"
      $c8 = "')]({'status':!![],'data':_0x"
      $c9 = "')]={'localStorage':'localStorage'in window?window[_0x"
      $c10 = "Browser not supported geolocation.');"
      $c11 = "')]({'status':!![],'msg':'','data':_0x"
      $c12 = "var Plugin = /*#__PURE__*/function () {"

      // The TA uses the use strict in all his plugins
      $use_strict1 = "\"use strict\";"
      $use_strict2 = "'use strict';"

      // Some of the same strings in base64, in case the attacker change their obfuscation there
      $e1 = "Cannot\x20call\x20a\x20class\x20as\x20a\x20function" base64
      $e2 = "The\x20command\x20is\x20sent\x20successfully,\x20wait\x20for\x20the\x20result\x20to\x20return" base64
      $e3 = "getUserMedia\x20is\x20not\x20implemented\x20in\x20this\x20browser" base64
      $e4 = "http://bn6kma5cpxill4pe.onion/static/images/tor-logo1x.png" base64
      $e5 = "/public/dependence/jquery" base64
      $e6 = "\x20\x22*\x22)\x0a\x20\x20}\x0a\x20\x20document.documentElement.appendChild(" base64
      $e8 = "\x0a\x20\x20var\x20data\x20=\x20{}\x0a\x20\x20window.c\x20=\x200\x0a\x20\x20script2\x20=\x20document.createElement(\x22script\x22)\x0a\x20\x20script2.async\x20=\x20true\x0a\x20\x20script2.src\x20=\x20\x22" base64
      $e9 = "{isPluginCallback:\x20true,\x20data,\x20plugin:\x20" base64
   condition:
      filesize < 1000000
      and (
         any of ($a*)
         or 2 of ($b*)
         or 4 of ($c*)
         or 2 of ($e*)
         or (
            any of ($use_strict*)
            and (
               (
                  any of ($b*)
                  and 2 of ($c*)
               )
               or any of ($e*)
            )
         )
      )
}

Deployment Notes

This YARA rule can be deployed in the following contexts:

This rule contains 41 string patterns in its detection logic.

References

False Positive Guidance

Here are 5 specific false positive scenarios for the Code and strings of plugins from the Tetris framework loaded by Swid detection rule, including suggested filters or exclusions:

Original source: https://github.com/Neo23x0/signature-base/blob/main/yara/apt_tetris.yar