JavaScriptによる新種の難読化マルウェア解析方法

  • Pocket
  • LINEで送る

私たちPC PitstopのMalware Research Teamは、いくつかの新種JavaScriptマルウェアを発見しました。そのマルウェアの1つには、悪意のあるコードの一部を難読化するために使用されるものでした。

コード難読化は、パソコンによって実行されるプログラムのコードを人が解析するのを困難するために用いられる技術ですが、パソコンでは問題なく実行されるものです。それはリバースエンジニアリングを困難とするための方法であり、他の用途には利用されていません。コードを難読化する主な理由は、リバースエンジニアリングなどの分析を行う者に対して、それを困難にすることです。そして難読化にも関わらず、パソコンにて実行可能な状態を保持することです。これはよくある「スパゲッティコード」を読んだり、100本のワイヤーが絡み合っていたりするようなものを分析するようなものです。難読化されたコードと暗号化されたコードは、まったく異なる二つのものです。たとえば、WannaCry / WanaCrypt0rは暗号化されたコードを使用していましたが、このコードでは、コードを構成するすべてのバイトが暗号化アルゴリズムによってスクランブルされ、コードは実行前にメモリ内で復号化されます。

暗号化されたコードがどのように見えるかを最初に確認し、その後にわかりにくいコードの2つの例を次に示します。 暗号化された(難読化されていない)コード:

このコードは完全に暗号化され、復号化キーなしでは利用不可能なものです。これは、難読化されたコードではありません。

 

難読化されたコード:

 

難読化された.NETコード。Obfuscarで難読化したもの

 

暗号化されたコードとは異なり、難読化されたコードでは実際にはすべてのプログラミング構造がそのまま残っています。さらに、余分な非論理的なステップがコードに追加され、それにより追跡するのをより困難なものにしています。たとえば、15番の番号を取得する方法を伝えたい場合は、次のように言います。

答えを得るには、5と10を追加します。

または、このように言うことができます。

答えを得るには、657,983を2で割って3を掛け、2,000を引いて75を加え、1を掛けて985,033を引く

後者は難読化され、分析者がこの算式によって得られる結果を計算することに時間を取らせることを除き、どちらも結果として15の結果が得られます。これはコードの難読化が使用する技術とまったく同じです。上記の最初のスクリーンショットを調べると、g()とa()の呼び出しが繰り返し表示されます。実際、a()はg()の内側にあります。

まず第一に、g()とa()はあまり良い関数名ではありません。次に、これらの関数呼び出しの頻度と表示される文脈によって、即座に私たちのアナリストは関数の定義をみて、ある異変に気が付きました:

印刷機能とデコード機能

g() はコンソールに入力テキストを表示する難読化する関数です。
a() は復元関数です。他のすべての文字を取得しそれを処理しています:

String.fromCharCode (parseInt (b.substr (c, 2) 16)

率直に言えば、このコードを逆難読化する関数を理解する必要はなく、この関数が入力文字列を受け取り、それを解読して手掛かりを得ていることをです。操作中のコードをさらに調べるために、デバッガを使用することが有効です。この特定のコードでは、ActiveXやWScriptなどのWindows固有の機能を利用しています。このため、Internet Explorerに実装されている F12 開発者ツールを使用することにしました。通常、これはあまり良い分析のための選択肢ではありませんが、FirefoxやChromeはIEなどのMicrosoft独自の機能をサポートしていません。また、できるだけセキュリティ保護の少ないものを利用することにしました。IEはこの点では最適です。IEのF12開発者ツールのスクリーンショットを以下に示します。

WScriptオブジェクトを読み込むことができないため、実際にコードが実行されてしまいましたが、幸いなことに「ステップオーバー」ボタンをクリックしてコードが実行され続け、復元機能の発見に至りました。私はデバッガを起動し、コマンドを復元機能の内部で実行させ、一度に1行ずつコードを進め、復元処理が一度に1文字ずつ発生するのを確認しました。IEがコードを実行できるように、このプロセスを最初に起動したときにActiveXオブジェクトを許可する必要がありました。以下の復元された文字をご覧ください:

この時点で、私たちはコードにおける難読な数字の1つを試し、この復元機能を使って着実に分析することができました。しかし、このような手動による方法は分析に時間がかかることがあります。このため、最初にいくつかの自動化されたツールを試してみることをお勧めします。私はJSNice、JSDetox、JSUnpackを試してみましたが、残念ながらこれらのコードのすべてを解読できませんでした。そこで私は分析のために時間を惜しまず、手動で行うことにしました。これを行うには、コードからa()関数を取り出し、Chromeを開き、F12キーを押し、[Source]をクリックして[Snipet]をクリックし、このコードをボックスに貼り付けます。私は関数の入力を手動で制御できるようにコードを配置し、出力はconsole.log()を実行し、入力と出力の両方をChromeコンソールに出力します。これにより、それぞれの難読化された文字列を貼り付けて、復元された文字列を得ることができました:

Chromeでスニペットを使用して文字列を手動で解除

最終的に、このコードをすべて解凍すると、次のようなコードになります。

難読化解消後のコード

私の手作業による難読化の分析において、重複している機能を削除し、いくつかのオブジェクトの名前を謎めいた1文字の名前から意味のある名前に変更しました。私は皆さんがこのコードのオナジナル版を見た場合、私たちがコードを修正したかわかかるようにな文字列を残しました:

ご覧のように、難解なコードはオリジナルより遥かに解読しやすく、コードが実際に行うことを把握するのに役立ちます。今回の場合は、スクリプトが悪意のあるURLに移動し、さらに悪意のあるマルウェアをダウンロードしようとしました。スクリプトだけで構成された、スクリプティング攻撃は一般的なウイルス対策ソフトによる防御を回避することに非常に優れているため、最近ではマルウェア作成者間で一般的な選択になりつつあります。PC Maticは、この種のファイルレスマルウェア攻撃からコンピュータを完全に保護します。

 

JavaScriptマルウェアの難読化を解除するワークフローを以下に示します。

1.まず、コードを調べてコードが難読化されているかどうかを判断します。
2.次に、JSNice、JSUnpackなどの自動化された難消化ツールを試してください。通常、コードはすべて圧縮されているか、または1行に「縮小」されているので、JSBeautifierが役に立ちます。私はJS Beautifierを使って、コードに触れる前にコードをコードのように見せました。
3.コードを書式設定した後、コードを読み取って、コード全体で繰り返し呼び出される関数を探します。
4.それらの機能のリバースエンジニアリング、またはデコード(難読化)またはエンコード(復元)機能の特定を試みるために、これらの機能の定義を調べます。
5.エンコード関数の場合は、それを元に戻すことができます。デコード機能の場合は、ここで行ったようにChromeスニペットで抽出して使用できます。
6.各シンボルをデコードして元のコードに戻し、それぞれを置き換え、コメントと独自の関数と変数名を使用してコードを把握します。
7.URLとIPアドレスについては特に注視してください。このマルウェアには、ハッカーのWebサーバーへのURLが記載されていました。

原文:http://techtalk.pcpitstop.com/2017/07/03/deobfuscating-javascript-malware

  • Pocket
  • LINEで送る