setodaNote

忘れる用のメモ書き for Cybersecurity

FLASHMINGO を少し動かしてみた

FLASHMINGO とは

FLASHMINGO は FireEye が無償で公開している Flash 解析フレームワークです。

FireEye の FLASHMINGO 紹介記事

FireEye 曰く、すでに Flash は技術として終わりを迎えているものの、世界中からそれらがすぐに消えるわけではなく、 むしろ脆弱性対応などがされなくなることを考えれば、Flash の寿命を超えてセキュリティの脅威となり得るとのこと。

どんな感じなのか、少しだけ使ってみました。 公式からの説明がほとんどなかったこともあり、かなり手探りな状態です。 とりあえず Windows 環境で Flash のデコンパイルをしてみたところまで記載しています。

まずはインストール(Python(2.7)系)

Github から FLASHMINGO を取得し、flashmingo-master 直下で以下を実行する。

pip install -r requirements.txt

Windows でデコンパイルするための準備

Windows 環境でデコンパイルを有効にするためには Jython をインストールし、プラグイン記述を修正して Jython へのパスを通す必要がある様子。

  1. Jython をダウンロードする
  2. デフォルト設定のままインストールする

    Jython インストールのパス設定画面

  3. FLASHMINGO のプラグイン記述を修正する

    • flashmingo-master\plugins\decompiler\plugin.py
    • 77行目付近
## For Windows systems:
##'C:\\jython2.7.0\\bin\\jython.exe',

  ↓

## For Windows systems:
'C:\\jython2.7.0\\bin\\jython.exe',

これで plugin としての Decompiler は使えるようになる(はず)。

FLASHMINGO のコマンドラインを起動

実際にコマンドラインで使ってみます。 flashmingo-master 直下に格納されている flashmingo-cmd.py を実行します。

python flashmingo-cmd.py
FLASHMINGO!

The SWF analysis framework... with a funny name!

            _
    <SWF>- ^-)
            (.._
             \`\\
              |>
             /|

FireEye's FLARE team
<carlos.garcia@fireeye.com>

Type 'help <command>' on any of these commands to get started:

- load
- status
- show_plugins
- run_plugin

[flashmingo] > 

サンプルを解析してみる

もともとサンプルの Flash ファイルが同梱されているので、それを FLASHMINGO で解析してみます。

解析するためには、まずファイルをロードする必要があります。 ロード自体は相対パスでも実行できてしまいますが、絶対パスでロードしておかないと各種プラグインがうまく動かなかったので要注意です。

[flashmingo] > load C:\0\flashmingo-master\samples\Evil.swf
warning: unknown tag 63
[*] Sample samples\Evil.swf loaded!

これでロード完了です。続いて各種コマンドやプラグインを試していきます。

status : 現在の状況を確認

[flashmingo] > status
Sample file: samples\Evil.swf

Embedded binary data:
 - com.Payload (535887 bytes)

Plugins already executed:
 - No plugins executed yet

show_plugins : 利用可能なプラグインの確認

[flashmingo] > show_plugins

Active plugins
--------------

Plugin name: BinaryData
  - desc: Searches embedded binary data for a given pattern
  - returns: A dictionary of class names and pattern offsets

Plugin name: CVESearch
  - desc: Uses a simple heuristic to flag potential CVEs
  - returns: A list of potential CVE names

Plugin name: DangerousAPIs
  - desc: This looks for APIs known to be abused, for example direct memory access
  - returns: A set of tuples (name of AS3 module, dangerous instruction)

Plugin name: Decompiler
  - desc: Leverages FFDEC library to decompile SWF methods
  - returns: a dictionary d[method name] = decompiled_method_text

Plugin name: SuspiciousConstants
  - desc: This looks for suspicious constant values
  - returns: A list of suspicious constants

Plugin name: SuspiciousLoops
  - desc: Find suspicious constructs within loops
  - returns: A list of methods doing sneaky things

Plugin name: SuspiciousNames
  - desc: It finds suspicious names in methods, constants, etc.
  - returns: A list of suspicious names found in the constant pools (all ABC tags)

None
[flashmingo] > 

BinaryData : 埋め込まれているバイナリデータの取得

  • desc: Searches embedded binary data for a given pattern
  • returns: A dictionary of class names and pattern offsets

説明によると引数で検索パターンを指定できるらしいものの、 どんな形で与えればいいのかよくわからず、いくつか与えてもヒットすることはありませんでした。

[flashmingo] > run_plugin BinaryData > out.dat
  • out.dat
{u'com.Payload': 'x\x9c\xec\xbd\x07t\\\xd7y\xef\x0b\x80\re0\xe8\xc0`\n\x06}\xd0\x1b\x89\xdeH\xc9~\x8b\x04\x08\x82\x9d\x14%\x92*\x14\xa9.\xf6^\x9cb\'v\x12{\xddw\x93\\[\xf1M\x9c8\xb1\xadf[\xb6\xca\x9f\xb2\x1d\x13 z#:\xa6\x0f\t\xa2\xb0Sb}\xef\xde\xd8~\xdf\xdeg\xce\xc1\x99\xc1\x0c\x08P\x94\xe4\xdc\x97\xc5\xf5[\xa7\x97\x993\x98\xd9?~\xdf\xb77\x94!1\x08VF\xcf\x8e\x90H(\x94a\x08\n\x0eE\xa0B\xefBpp8\x14\x8ap\x04\x06\x86\xc2\xdf?\x0e\xd1\xd1ZDEi\x10\x19\xa9Fx\xb8\x1a\xa1a\xb1\xd0\x87\xa9\x10\x17\x11\x8b8Z\xa7\x8bRC\x13\xadAl\x80\x1e\x1aE\x04t\xca\x00\xc4\xf9\x86@\xe7\xebK\xcc\x83&D\t\x8d\xd2\x1f\xaa\xa0(\x18b\xf40\xd0\xf9\x0c\x91\x1a\x18"T\xd0F$\x11\x89\xd0\x87\x0b\x84G$#&\xca\x80\x00\x7f\x15\xdd\x8bA" (\x15\xfe\x81)\x9c\xe8\xe8\x14DE\xa4 ,<\tq\xa1\tP\xc7\xe5 V\x9f\x03\x15#
(snip)

Decompiler : Flash のデコンパイル

  • desc: Leverages FFDEC library to decompile SWF methods
  • returns: a dictionary d[method name] = decompiled_method_text

デコンパイルしてみます。

[flashmingo] > run_plugin Decompiler
[*] Reading file: C:\0\flashmingo-master\samples\Evil.swf...
[*] The entry point is Evil
- Evil
- Payload
TAG: DoABC2 (Evil)
TAG: DoABC2 (com/Payload)
[*] Dumping decompiled methods to a JSON file...
[*] Done.
{u'Evil': {u'1': u'         super();\r\n         var outputText:TextField = new TextField();\r\n         outputText.text = "Defeat the
evil (TM)";\r\n         outputText.width = stage.stageWidth;\r\n         outputText.height = outputText.textHeight + 20;\r\n         th
is.p = new Payload() as ByteArray;\r\n         var dec_p:ByteArray = this.decoder(this.p);\r\n         var bm:Bitmap = new Bitmap();\r\
n         var bmd:BitmapData = new BitmapData(800,331,false,4294967295);\r\n         bmd.setPixels(bmd.rect,dec_p);\r\n         bm.bitm
apData = bmd;\r\n         var imageX:uint = (stage.stageWidth - bm.width) / 2;\r\n         var imageY:uint = (stage.stageHeight - bm.he
ight) / 2;\r\n         bm.x = imageX;\r\n         bm.y = imageY;\r\n         addChild(bm);\r\n         addChild(outputText);\r\n', u'0'
: u'', u'3': u'         this.Evil = new Evil.class extends Sprite;\r\n', u'2': u'         var key:uint = 3735943886;\r\n         var de
coded:ByteArray = new ByteArray();\r\n         p.uncompress();\r\n         var k1:uint = key & 255;\r\n         var k2:uint = key >> 8
& 255;\r\n         var k3:uint = key >> 16 & 255;\r\n         var k4:uint = key >> 24 & 255;\r\n         for(var i:uint = 0; i < p.leng
th; i++)\r\n         {\r\n            decoded[i] = p[i] ^ k1 ^ k2 ^ k3 ^ k4;\r\n         }\r\n         return decoded;\r\n'}, u'com/Pay
load': {u'1': u'         super();\r\n         trace("Payload loaded");\r\n', u'0': u'', u'2': u'         Payload = new Payload.class ex
tends ByteArray;\r\n'}}
[flashmingo] >

結果を整形すると以下のような感じになりました。

{u'Evil': {u'1': u'
         super();
         var outputText:TextField = new TextField();
         outputText.text = "Defeat the evil (TM)";
         outputText.width = stage.stageWidth;
         outputText.height = outputText.textHeight + 20;
         this.p = new Payload() as ByteArray;
         var dec_p:ByteArray = this.decoder(this.p);
         var bm:Bitmap = new Bitmap();
         var bmd:BitmapData = new BitmapData(800,331,false,4294967295);
         bmd.setPixels(bmd.rect,dec_p);
         bm.bitmapData = bmd;
         var imageX:uint = (stage.stageWidth - bm.width) / 2;
         var imageY:uint = (stage.stageHeight - bm.height) / 2;
         bm.x = imageX;
         bm.y = imageY;
         addChild(bm);
         addChild(outputText);
', u'0': u'
', u'3': u'
         this.Evil = new Evil.class extends Sprite;
', u'2': u'
         var key:uint = 3735943886;
         var decoded:ByteArray = new ByteArray();
         p.uncompress();
         var k1:uint = key & 255;
         var k2:uint = key >> 8 & 255;
         var k3:uint = key >> 16 & 255;
         var k4:uint = key >> 24 & 255;
         for(var i:uint = 0; i < p.length; i++)
         {
            decoded[i] = p[i] ^ k1 ^ k2 ^ k3 ^ k4;
         }
         return decoded;
'}, u'com/Payload': {u'1': u'
         super();
         trace("Payload loaded");
', u'0': u'
', u'2': u'
         Payload = new Payload.class extends ByteArray;
'}}

さいごに

FLASHMINGO は解析フレームワークなので、各種プラグインはあくまで参考のためにあるのだろうと思います。 テンプレートをもとに、各自が自分たちで使いたい形のプラグインを作ってくれということのようです。

補足

  • 実行ログ

    • デバッグログやエラーログ含め以下に出力されます。
    • flashmingo-master\flashmingo.log
  • プラグインの細かな説明

    • Github にはほとんど説明がないですが、各Plugin のソースに書かれているコメントに少し詳細な挙動が記載されています。
    • (各プラグインのフォルダ)\plugin.py

更新履歴

  • 2019/04/25 新規作成
  • 2023/01/10 一部リンクを修正