W32/RamnitウイルスはEXE、DLL、HTMLファイルに感染します。W32/Ramnitは、自身を複製するため、HTMLファイルに感染する特徴を持っています。この度はこの特徴に関して解説します。
まず、このスレッドのコンポーネントを見てみましょう。W32/Ramnitには基本的に3つのコンポーネントがあります。感染プログラム、EXE/DLLファイルの感染コード、HTMLファイルの感染コードです。
3つの中で最も単純なのが、HTML感染コードです。W32/Ramnitがターゲットマシンで見つけるすべてのHTMLファイルの終わりにVisual Basic Scriptコードが追加されます。コードを見ると、非常に単純なことがわかります。
先頭部分には、svchost.exeという名前を変数に割り当て、大量のデータをWriteDataという名前の変数に割り当てるコードがあります。このデータをよく見ると、4D 5Aで始まっています。これは通常、PEファイルのマジックナンバーで、Windows実行ファイルのシグネチャです。
つまり、この変数にはPEファイルの16進数表現が含まれています。さらに、コードはDropFileNameという名前の変数のファイル名とVBS GetSpecialFolder(2)関数の実行結果を結合して、ファイル名を作成しようとします。この関数はWindowsの%TEMP%パスを返します。その後、16進数表現を実際の16進数バイトに変換して、このファイルに16進数データを書き込もうとします。これにより、WriteData変数の内容が格納されたバイナリファイルが作成されます。さらに、WSHshell.Run DropPath, 0により、新たに作成されたファイルを実行しようとします。
ファイル自体はW32/Ramnitのファイル感染コンポーネントのコピーです。これについては後で見ることにして、先にPE/DLLファイルに追加されるコードを見てみましょう。
W32/Ramnitが感染するEXE、DLLファイルには、共通の特徴がいくつかあります。
ファイルの終わりにセクションを追加して、感染します。このセクションには通常、.ramnitという名前が付けられています。コードのエントリポイントが、ウイルスコードがあるこのセクションの最初に変更されます。
このコードは単なるドロッパーです。システムに作成されて最後に実行される、組み込み型の実行ファイルが格納されています。コードを見ると、非常に単純なことがわかります。
見ての通り、ウイルスは興味深い方法を使って開始アドレスを入手します。フラグを保存するとすぐに、次の命令である0×48b006を呼び出します。これにより、この呼び出しの復帰アドレスとして、スタックの上に次の命令のアドレスが配置されます。その後、この値がEAXに保存されます。
さらに、ウイルスはEAXの値、すなわちアドレス0×0048b006から、コードの開始点へのオフセットを取り除きます。PUSHAD命令へのオフセットは6バイトあり、これがEAXから取り除かれる値になります。これで、このレジスターは感染コードの開始点を指すようになります。ウイルスは後でこの情報を使って、オリジナルエントリポイント(OEP)を見つけます。この値は変数に保存されます。
次に、ウイルスはオリジナルのファイルのインポートテーブルを探し、LoadLibraryA()とGetProcAddress()のアドレスを見つけようとします。これらのオフセットは、感染時に感染プログラムによって事前に計算されます。
これらの関数のアドレスを入手したウイルスは、必要な他のインポートのロードを開始します。
必要なすべての関数をロードすると、処理を続行する前に、別のコピーが動作していないかどうか確認します。
Mutex名や上記の変数はすべて、ウイルスコードの終わりに配置されます。
必要な情報をすべて入手したウイルスは、作成される組み込みファイルを解読します。暗号は0×14バイトのキーを使った簡単なXORベースです。キーは逆の順番で格納されるため、以下のコードは最後のバイトから順に使われます。逆の順番で格納されているキーをそのまま表記すると、「8A 27 0E 94 C1 12 F8 F3 E7 8B C5 ED 35 18 26 9C 52 3A B8」となります。
以下は暗号解読コードです。
ループを数回実行すると、メモリダンプに典型的なPEヘッダーが現れます。
ファイル全体を解読したウイルスは、作成されたファイルの新しい名前を作ろうとします。この名前は、感染ファイルの名前と「Srv」という文字列をベースに作成されます。たとえば、感染ファイルの名前がsample.exeの場合、作成されたファイルの名前はsampleSrv.exeになります。
ウイルスコードは、この新しいファイルに解読したコンテンツを書き込んだ後、CreateProcessA()を呼び出して実行しようとします。ここまでが終われば、あとはOEPに戻ってオリジナルの実行ファイルに制御を戻すだけです。ウイルスコードの開始からOEPまでのオフセットを計算して、これを実行します。
見ての通り、オフセットはローカル変数に格納され、感染時に計算されます。オリジナルのファイルがウイルスコードによって破壊される場合もありますが、オフセットは常にウイルスコードの開始に相対しています。
なお、マカフィーはこのスレッドをW32/Ramnit.a、W32/Ramnit.a!htm、W32/Ramnit.a.drという名前で検出しています。
※本ページの内容はMcAfee Blogの抄訳です。
原文:Taking a Look at W32/Ramnit