2020/02/28

マルウェア解説:JS:Trojan:Cryxos.2550 について

2020 年 2 月 28 日 Emil Hozan 著

急増している中のマルウェア攻撃を 2020 年 1 月に調査していたのですが、特に気になったマルウェアが JS:Trojan:Cryxos.2550 です。このマルウェアは、前週と比べて出現率が 457% 以上も上がっていました。Trojan.Cryxos 自体は幾度となく取り上げられており、決して新しいマルウェアではありません。しかしこの亜種に限っては、比較的新しく、数も増加しています。

ウォッチガード製品のユーザはあらゆるマルウェアから保護されなければなりませんので、この脅威を詳しく見ていきます。

JS:Trojan:Cryxos.2550 について

はじめに、Trojan.Cryxos 系統のマルウェアについてですが、これはすでに数年間存在しているものです。F-Secure の記事に掲載されているように、一般的にはスケアウェア、または偽のサポートコールリクエストと組み合わせられます。ポップアップ広告による警告で、「ハッキングされています!」や「あなたのコンピュータが感染した報告を受けています」などといった恐怖心を煽る文句を目にしたことはないでしょうか。もし身に覚えがあれば、あなたは何らかの形でこのタイプの攻撃の被害者になり得た、ということです。もちろん、攻撃手法はこれだけに限りません。

この系統のマルウェア全体のことはさておき、筆者が分析した特定の亜種を発見したのは、2020 年 1 月 23 日です。これには HTML、PHP、および JavaScript が組み込まれています。上記は基本的な言語であり、それぞれに目的があるため、これ自体は Web ページにおいて珍しいわけではありません。HTML はいわば Web ページの枠組みを表示し、CSS はそのレイアウトを定義するために使われます。JavaScript はクライアントのマシン上でコンテンツを動的に表示するために使われ、対して PHP はクライアントが直接アクセスすることのできないバックエンドサーバで使用されます。

このマルウェアで興味深い点は、HTML コンテンツを表示するために JavaScript がどのように使用されているかということです。たとえば JavaScript の「document.write(unescape())」を利用した「<script>」のブロックが 8 つあるとしましょう。この関数はエンコードされた文字列をデコードします。各ブロックには、URL エンコードされた文字列で関数に渡されるパラメータがあります。したがって、その関数がパラメータの内容をアンエスケープすると、HTML コンテンツにデコードされ、クライアントのブラウザで通常どおり表示されます。図 1 の画像をご覧ください。

71 行目から 77 行目のピンク色のテキストは、65 行目と 67 行目の間の青色のテキストを URL エンコードしたものです。

図 1:ピンク色のエンコードされた文字列が青色のテキストにデコードされる

図 1:ピンク色のエンコードされた文字列が青色のテキストにデコードされる

エンコードされた文字列を元に戻すと、それらはすべてスタイル設定にインライン CSS を使用した HTML コンテンツになります。この亜種で特に懸念されるのは、Web ページのフォームに入力し、それを送信した後に実行されるアクションです。たとえばログイン画面など多くの Web ページでは、認証のためにユーザがデータを入力して送信する必要があります。これは、HTML の POST 送信を使用して行われます。POST 送信とは、サーバにデータを送信して何らかのアクションを実行する方法です。通常このアクションは、ユーザが実際に Web アプリケーションのユーザアカウントを持っているかどうかを確認し、アカウントがあればアクセスを許可する、というものです。しかしこの場合の POST 送信は、収集したデータをドメイン「hxxps [:] // dotcodesoultions [.] com / bb / result [.] php」の攻撃者が制御するサーバに送信します。ここで、偽のログインページの典型的な例を紹介します。

図 2 では、ページが電話番号とパスワードを要求しています。

図 2:最終的に表示される Web ページ

図 2:最終的に表示される Web ページ

エンコードについて

UTF-8 は、世界中の多くの言語に対応するための一般的なエンコード形式です。HTML5 はデフォルトで入力を UTF-8 に変換します。ここでは詳細は説明しませんが、興味がある場合は、こちら(W3Schools)をご参照ください。本記事では、これが具体的にどのような意味かを把握するための例を挙げます。

仮に URL エンコードしたい「Hello, from WatchGuard!」(両端の鉤カッコを除く)という文字列があったとしましょう。この文字列をオンライン URL エンコーダに入力すると、次の HTML の URL エンコード結果が得られます。「Hello%2C%20from%20WatchGuard!」これはそのまま読むことができます。アルファベットの文字が単語のまま保たれ、それらが「%20」で仕切られています。「%20」とはスペースを 16 進数で UTF-8 でエンコードした結果です。「%2C」はコンマです。HTML の URL パラメータにはスペースを含めることができないため、スペースはこのエンコードされたスキーマを使用して表されます。

文字列の内容をさらに難読化するには、最初に UTF-8 を使用してエンコードし、次にその結果を URL エンコードします。同じ「Hello, from WatchGuard!」を使うと、このようになります。「%48%65%6C%6C%6F%2C%20%66%72%6F%6D%20%57%61%74%63%68%47%75%61%72%64%21」ここまで来ると、読みやすいとはとても言えませんが、オンラインツールを使って元に戻すことはできます。「%XX」というまとまりは、UTF-8 によって 16 進数表現した 1 文字に当たります。たとえば「%48」は「H」、「%65」は「e」です。

要約と結論

まとめると、この脅威はメールの中にあるリンクをユーザがクリックした際に引き起こされるのではないかと筆者は考えています。メールアドレスはこのウェブページにパラメータとして渡され、PHP の「$ _GET [’email’]」関数を使用して抽出されます。この関数は、「[’email’]」フィールドで指定されたパラメータを取得します。ページが読み込まれると、メールが分析され、ユーザ名(「@」の前の部分)とドメイン(「@」の後の部分)が抽出され、参照できるようになります。図 3 はその様子です。

図 3:「$ login」から「$ loginID」と「$ domain」を抽出する PHP 関数

図 3:「$ login」から「$ loginID」と「$ domain」を抽出する PHP 関数

2 行目は関数として「getLoginIDFromlogin」を開始し、「$ email」をパラメータとして渡します。7 行目では「$ loginID」が返されます。その値は、「$ email」の最初の文字で、「@」記号までです(「@」記号は含まない)。9行目は「getDomainFromEmail」関数を開始し、「$ email」もパラメータとして渡されます。13 行目で返される「$ domain」は、「$ email」の中でも「@」のあとから「$ email」の最後までの内容で構成されます。

不可解なのは、フォーム上部にある「[[-Domain-]]」や 2 番目のフォームボックスにある「[[-Email-]]」など、関係のないように見えるランダムなテキストがある理由です。このデータはキャプチャされたユーザ名とドメイン名を反映するために、更新されるものではないか思われます。たとえば対応するメールアドレスからドメイン名が抽出された場合、フォームのヘッダには「<COMPANY DOMAIN> Email Verification」などと表示され、2 番目のフォームボックスにはユーザのメールアドレスが自動的に入力されます。最後に、「Verify My Account >>」ボタンの下に隠れボックスがありますが、特に意味はないようです。図 4 を参照してください。

図 4:HTML フォーム入力欄の拡大図

図 4:HTML フォーム入力欄の拡大図