# アジェンダ [発表時のスライド](https://drive.google.com/file/d/1YEXVjO0KLguO6xu6hKMG318X8TCV4PpT/view?usp=sharing) 研究テーマ: 「CFGを用いたマルウェア検知」 # 概要 WatchGuardのレポート(2020)によると, 昨年発見されたマルウェアの約50%が未知のマルウェアであった。そのような未知のマルウェアは既知のマルウェアを改変して作成されることが多い。また, レガシーなパターン検知は改変に非常に弱いことから, 新しい検知手法の提案は有効であると考えられる。 私の提案手法では, ファイルの中間表現としてCFG(Control Flow Graph)を用いる。CFGを用いる理由は, **多少の改変に影響されず, マルウェアの構造を表すことが出来る**ためである。私の提案手法は, 既知のマルウェアと検査対象のファイルを中間表現であるCFGに変換し, グラフ同士の類似度を算出することで, その類似度に応じてマルウェアか否かを判断する。 データセットには, VirusShareから得られたELF形式のマルウェアと良性の実行ファイルを用いる。2014年に採取された2778件を既知のマルウェアとして, 2019年に採取された10426件のマルウェアと良性のファイルを混ぜ合わせた検査対象のファイルからどれだけの精度で検知できるかを検証する。 # 相談したいこと 今後の研究方針を, 転換するのであれば下記の2つになりそう......? 1. 検知を目的にするのではなく, CFG生成を目的にする 2. CFG生成で妥協して, その後の類似度算出を行う # CFG生成用 - 高速そうなのでLLDBに固執していたが, 遅めのGDBに変えたら実装はある程度上手くいっている - Pythonスクリプトなので, 規模が大きくなると間に合わなくなる? - ELF形式の32bitマルウェアに対してjump命令の列挙が出来たのは確認できた - **質問したいこと** - 64bit ELFだと`leave`命令で判断できるが, 32bit ELFだと`ret`で判断することしかできない - 他に判断できる方法があれば教えてください ## CFG生成用のアルゴリズム ``` 準備するもの: CFG保存用のリスト, 命令とアドレスを保持するstack main関数にbreakpointを立てる デバッガ実行 while True: ステップ実行 現在のアドレスのアセンブリを取得 # 関数の終端まで来た時に, stackが空ならCFG生成終了 # stackが空でなければ, アドレスを取り出してそのアドレスから再開 if 関数の終端まで来た: if 記憶しているアドレスが無い: 終了 $eflagsを, 記憶している命令が条件を満たす値に強制変更 記憶しているアドレスにbreakpointを立てる 記憶しているアドレスにjump continue # jump系の命令があれば, アドレスと命令をStackに積んで # true/falseの両方の道を探索する # 例: # JEならZF=0とZF=1を検証する # JLEならZF=0&&SF=ZFとZF=1を検証する if 止まっている場所のアセンブリに`j*`の命令が入っている: addr_stack.append([jump命令, 現在のアドレス]) graph[現在のアドレス] = jumpしない場合のアドレス ``` # CFG同士のマッチング - まだ何も触れていない...... - 時間的に厳しい? - 機械学習を用いるならGraphEmbeddingsを用いる実装が妥当か - 埋め込みは[benedekrozemberczki/karateclub](https://github.com/benedekrozemberczki/karateclub)というライブラリが使える? - その後にどの機械学習を使うかは未定 # メモ - 教師無し学習を使う? - webアプリで分かりやすいのが出ているらしい - 要調査 - 1/30-31で最終発表 - 成果発表会3/5 - ポスター作製 - 年末~一月末にかけてポスターを作る