stringsコマンド
Strings -a log.exe
-aオプションでファイル全体から文字列を抽出するstrings -a -el multi.exe
-elオプションでUnicode文字列を抽出する
Windowsではpetudio(https://www.winitor.com)が便利なサイト
FLOSSによる難読化文字列のデコード
マルウェアから難読化された文字列を複合して抽出する。
[用法例]
$chmod +x floss
$./floss spy.exe
マルウェア作成者は、ファイルを難読化してアンチウイルスなどのセキュリティソフト からの検出を回避し、分析を妨害するため、パッカーやクリプターと呼ばれるプログラムを利用する
パッカー・クリプター
Packer
プログラムを圧縮して、実行ファイルのコンテンツを難読化する。
その後、新しい実行ファイルが作成されて、難読化されたプログラムは新しい実行ファイルの プロファイル構造内部に格納されます。難読化されたプログラムを実行すると、解凍モジュールが実行され、 元もプログラムをメモリ内へ展開し、本来のプログラムの実行を開始します。— UPX
-dオプションを利用して検体を解凍することが可能upx -d -o spybot_unpacked.exe spybot_packed.exe
Cryptor
暗号化を利用して実行ファイルのコンテンツを難読化します。 暗号化されたコンテンツは、新しい実行ファイルのファイル構造内部に格納されます。 難読化されたプログラムを実行すると、複合モジュールを実行し、 元のプログラムをメモリ内へ展開し、本来のプログラムを実行します。
ファイルの依存関係とインポート関数の調査
マルウェアは通常OSのAPIを使ってOS内でファイルを作成したりする。例えばWindowsのディスク上に新しいファイルを 作成する場合。Kernel32.dllを読み込んでCreateFile関数を呼び出す必要がある。
これらの依存関係を調査するにはpestudioの[libraries]が有効である。 しかしマルウェアは、LoadLibrary関数やLdrLoadDLL関数などのAPI呼出しを使い、実行時にDLLを明示的に読み込み、 GetProcessAddress関数を利用して、関数アドレスを解決することもあります。実行時に読み込まれたDLL情報はPEファイルの インポートテーブルに存在しないため、ツールでは検出されません。
また、インポート関数が非常に少ない場合、難読化されていることを強く示している。
dllファイルの調査
dllファイルはWindowsにおいてプログラムの実行時に利用される関数やリソースの集合体です。
dllファイルをpestudioにインポートして[exports]を見るとDLLの機能を簡単に知ることができる。
しかしエクスポート関数名は必ずしもマルウェアの機能を教えてくれるとは限らない。攻撃者はランダムな名前 や誤った関数名を設定して、解析から逃れようとするときがある。
PEセクションテーブルとセクションの調査
PEファイルはセクション単位に分割される。これらのセクションはコードなのかデータなのかを表しています。 コードを示すセクションにはプロセッサによって実行される命令が含まれています。 データを含むセクションには、読み書きされるプログラムデータ(グローバル変数・インポート/エクスポート変数・リソース)
各セクションにはそれらセクションの目的を表す名前がついている。下記がその一覧。
これは人間のためにあるものなので、攻撃者や難読化ソフトによって異なる名前のセクションがつけられる可能性がある。
セクション名 | 概要 |
---|---|
.text・CODE | 実行コードが含まれている |
.data・DATA | 読み書きされるデータとグローバル変数が含まれている。 |
.rdata | 読み取り専用データ。インポート、エクスポート情報が含まれていることもある。 |
.idata | 存在している場合、インポート情報を含む。存在していない場合、インポート情報は.rdataセクションに格納されている。 |
.edata | 存在している場合、エクスポート情報を含む。存在していない場合、エクスポート情報は.rdataセクションに格納されている。 |
.rsrc | アイコン、ダイアログ、メニュー、文字列など、実行ファイルが利用するリソースが含まれている。 |
pestudioで実行ファイルを読み込み、[Section]をクリックすると、セクションテーブルから抽出されたセクション情報と属性が表示される。 下記はそのフィールド名の概要です。
フィールド名 | 概要 |
---|---|
Names | セクション名を表示。実行ファイルには4つのセクション(.text , .data , .rdata , .rsrc)が含まれる。 |
Virtual-Size | メモリに読み込まれた場合におけるセクションサイズ。 |
Virtual-Address | メモリ内でセクションのバスを示す相対仮想アドレス(実行ファイルのベースアドレスからのオフセット。相対仮想アドレスは、RVA[Relative Virtual Address]と呼ばれることがある。 |
Raw-size | ディスク上におけるセクションサイズ。 |
Raw-data | ファイル内で、セクションの場所を示すオフセット。 |
Entry-point | コードが実行される場所を示す相対仮想アドレス(RVA)。通常であれば、エントリポイントは。.textセクション(実行コードが格納されているセクション)となる。 |
UPXで難読化されたプログラムの特徴として以下があげられる。
- フィールド名が[UPX0]や[UPX1]と表示される。
>> 通常であれば、一般的な .text .data が含まれるはず。 - Entry-pointがUPX1セクションにある。
>> この特徴は解凍モジュールから始まる可能性がある。 - 通常、raw-sizeとvirtual-sizeはほぼ等しくなるが、難読化されているとメモリ内でより多くのスペースを占有することとなり 通常とはことなり、等しくなる可能性がある。
コンパイル時刻の分析
PEヘッダにはコンパイルした時刻を示す情報が含まれている。これは作成された時系列として役立つが、攻撃者がタイムスタンプを 書き換えることも可能。
Pestudioではexeファイルをインポート後に[file-header]欄を選択。stampセクションに記載されている。
書き換えられていると未来の日付になっていたりするが、これはこれで、異常な挙動を示すプログラムを特定するのに役立ちます。
PEリソースの解析
アイコン、ダイアログ、文字列などの実行ファイルに必要なリソースは、リソースセクション(.rsrc)に格納されています。 このリソースセクションには攻撃者の追加のプログラム、おとり文書、構成データが含まれている可能性があります。 なので、プログラムに関する重要な情報が含まれていることが多いです。
Resource Hacker は分析対象からリソースを分析、表示、抽出するツールです。
バイナリをディスクに保存するときは、[Save Resource to a *.bin file]をクリックします。xlsで保存されます。
マルウェアの比較と分類
マルウェアはほかのプログラムと似ていたりしますが、これを判断するのにハッシュ値はプログラムが同一であることを示すので 役に立ちません。
ファジーハッシュを利用した分類
Fuzzy Hashingはファイルの類似性を比較するための優れた方法。ssdeepは、マルウェアのファジーハッシュを生成する 便利なツールです。
[ssdeepの使い方]
$ ssdeep virus.exe
ssdeepの完全モード(-pオプション)
$ ssdeep -pb virus.exe bad.exe
> virus.exe maches bad.exe (99)
これは99%の類似性を持っていることを表しています。この二つは同じマルウェアファミリーに属していると考えられます。
多くのマルウェア検体の類似性を識別するときは、再帰モード(-r)を利用します。
$ ssdeep -lrpa samples/
次の例ではすべてのプログラムのssdeepハッシュ値をテクストファイル(all-hashes.txt)に保存します。そして対象ファイル(blab.exe) を、テキストファイル内のすべてのハッシュ値と参照します。
$ ssdeep * > all-hashes.txt
$ ssdeep -m all-hashes.txt blab.exe
pythonでは、フィジーハッシュは、python-ssdeepで利用可能です。
インポートハッシュを利用した分類
ファイルが同じソースから同じ方法でコンパイルされた場合、それらのファイルは同じimphash値を持つ傾向があります。 マルウェアの調査中に同じインポートハッシュ値を持つサンプルが見つかった場合、それらは同じインポートアドレステーブルを 持ち、おそらく関連していることを意味します。
インポートハッシュに関する詳細な情報、及び攻撃グループを追跡するかについては、FireEye社のブログ(https://web.archive.org/web/20201101083019/www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html)
JPCERT(https://blogs.jpcert.or.jp/ja/2016/05/impfuzzy.html)
pestudioではmd5とかがあるところでインポートハッシュ値を確認できます。
pythonではpefileモジュールを使って計算することができます。
セクションハッシュを利用した分類
インポートハッシュ同様に各セクションのMD5を計算した値を用いて分類することが可能です。
Pestudioでは[section]欄で確認することができます。
YARAによるマルウェアの分類
YARAルールの基本
YARAは{ルールを書く} → {実行する}の手順で行う。個人的にはTOMLとSQLを組み合わせたような記述をしてると思う。
rule suspicious_strings
{
strings:
$a = "Synflooding"
$b = "Portscanner"
$c = "Keylogger"
condition:
($a or $b or $c)
}
[解説]
- (Rule Identifier) : Ruleの後はルールの名前をつける。制限は一般の変数宣言と同じ。(大文字小文字の区別。先頭に数字は禁止。128文字を超えることはできない。)
- (String Definition) : ここで探したい文字列や16進数を宣言して変数のように扱う。
- (Condition Section) : これは必須。ここではルールが一致した場合、一致しない場合の条件を指定する。
YARAルールの実行
Yaraを実行し、ルールに書いた3つの文字列(b or $c)を検索して、一致すればルールに合致したとみなします。
ルールは.suspicious.yaraという名前で保存されます。このルールをMalwareがあるディレクトリに対して実行します。
$ yara -r suspicious.yara malware-collection/
suspicious_strings malware-collection//spybo.ext
suspicious_strings malware-collection//wuamgr.ext
実行ファイル内に含まれる文字列のみを探す場合、次のようにルールを定めます。
条件:"$mz at 0"
と記述されており、ファイルの先頭でファイルシグニチャ’4D 5A’(PEヘッダの初めの2バイト) が含まれているかどうか
YARAではテキストはダブルクォーテーション$mz
変数のような16進数文字は中括弧で囲みます。
ASCII文字列とUnicode文字列の両方をルールで検出させたいときは stringの横にasciiおよびwide修飾子を指定します。nocase修飾子をつけると大文字小文字の区別をつけなくなります。
rule suspicious_strings
{
string:
$mz = {4D 5A}
$a = "Synflooding" ascii wide nocase
$b = "Portscanner" ascii wide nocase
$c = "Keylogger" ascii wide nocase
condition:
($mz at 0) and ($a or $b or $c)
}
YARAの応用
metaセクションはstringsセクションの前に書くこと多いい。ここにはYARAの可読性を向上させるために説明やバージョンなどを書き込む。
filesize…ファイルの終点を指定できる。
以下のYARAはPEヘッダから1024バイトまでの中でMicrosoft Officeドキュメントを示すシグニチャがあるかどうかを探知します。
rule embedded_office_document
{
meta:
name = "Sugano Senpai"
description = "Detects embedded office document / 埋め込まれたオフィスのドキュメント探します"
version = 1.0
string:
$mz = {4D 5A}
$a = {D0 CF 11 E0 A1 B1 1A E1}
condition:
($mz at 0) and $a in(1024..filesize)
}
YARAではPEファイルを読み込ませることもできます。
Exinfo PEツールはパッカーを検出するためにuserdb.txtというテキストファイルに保存されているシグニチャを利用して検出しています。
このデータベースはYARAにも利用できます。具体的にはuserdb.txt
のなかに"ep_only = true"
という記述がされています。これはプログラムの エントリポイントのアドレス(コードが実行を開始する場所)でのみシグニチャをチェックすることを意味します。
YARAでPEファイルを読み込ませるには{import "PE"}
と最初に記述する必要があります。
import "pe"
rule UPX_290_LZMA
{
meta:
description = "Detects UPX Packer 2.90"
ref = "userdb.txt file from the Exeinfo PE"
strings:
$a = {83 7C 24 08 01 0F 85 ?? ?? ?? ?? 60 BE ?? ?? ?? ?? BF ?? ?? ?? ?? FC AD 8D 1C 07 B0 80 3B FB 73 3B E8 ?? ?? ?? ?? 72 03 A4 EB F2 E8 ?? ?? ?? ?? 8D 51 FF E8 ?? ?? ?? ?? 56 8B F7 2B F2 F3 A4 5E EB DB 02 C0 75 03 AC 12 C0 C3 33}
condition:
$a at pe.Entry-point
}