JBoss Application Server におけるディレクトリトラバーサルの脆弱性

Similar documents
Spacewalkにおけるクロスサイトフォージェリ(CSRF)の脆弱性

Apache ActiveMQ における認証処理不備の脆弱性

MySQL Connector/J における SQL インジェクションの脆弱性

Apache Tomcatにおけるクロスサイトリクエストフォージェリ(CSRF)保護メカニズム回避の脆弱性

Apache Axis2 におけるXML署名検証不備

Javaセキュアコーディングセミナー東京 第2回 数値データの取扱いと入力値の検証 演習解説

Blojsom におけるクロスサイトスクリプティングの脆弱性

Oracle Java 標準ライブラリ AtomicReferenceArray クラスにおけるデシリアライズに関する脆弱性

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

ログを活用したActive Directoryに対する攻撃の検知と対策

JEB Plugin 開発チュートリアル 第4回

JEB Plugin 開発チュートリアル 第3回

Javaセキュアコーディングセミナー東京 第3回 入出力(File, Stream)と例外時の動作 演習解説

メディプロ1 Javaサーブレット補足資料.ppt

Javaセキュアコーディングセミナー東京 第4回 メソッドとセキュリティ 演習解説

制御システムセキュリティアセスメントサービス

Eclipse 操作方法 (Servlet/JSP 入門補助テキスト)

はじめての暗号化メール(Thunderbird編)

FW ファイルアップロード ダウンロード機能利用ガイド Version 年 9 月 21 日富士通株式会社 i All Right Reserved, Copyright FUJITSU LIMITED

Microsoft PowerPoint - Lecture_3

JPCERT/CCインシデント報告対応レポート[2015年4月1日 ~ 2015年6月30日]

Apache Commons の HttpClient におけるSSLサーバ証明書検証不備

PowerPoint Presentation

V8.1新規機能紹介記事

IM-SecureBlocker

intra-mart Accel Platform — イベントナビゲータ 開発ガイド   初版  

SpringSecurity

JPCERT/CC インターネット定点観測レポート[2014年7月1日~9月30日]

WTM2019SingleSignOn

Red Hat Enterprise Linuxのcron(8)デーモンにデフォルト定義されたtmpwatch命令の動作による、WebOTXのトラブル対処方法

Microsoft Word - XOOPS インストールマニュアルv12.doc

PowerPoint Presentation

富士通Interstage Application Server V10でのOracle Business Intelligence の動作検証

SOC Report

intra-mart Accel Platform — 外部ソフトウェア接続モジュール 仕様書   第3版  

Android Layout SDK プログラミング マニュアル

Java - Visual Editor

CloudEdgeあんしんプラス月次レポート解説書(1_0版) _docx

Microsoft PowerPoint - Lecture_2

第 7 回の内容 動的な Web サイト フォーム Web システムの構成

Microsoft IISのWebDAV認証回避の脆弱性に関する検証レポート

JPCERT/CCインシデント報告対応レポート[2018年4月1日 ~ 2018年6月30日]

intra-mart Accel Platform — イベントナビゲータ 開発ガイド   初版   None

Himawari の異常な暗号

HULFT Series 製品における Javaの脆弱性(CVE )に対する報告

Java言語 第1回

— intra-martで運用する場合のセキュリティの考え方    

WEBシステムのセキュリティ技術

Prog2_6th

Javaの作成の前に

モバイルアプリを Azure で作る - データを扱う Azure Storage を利 してデータを保存する 本稿では PHP と Windows Azure を使って 画像などのファイルを扱うアプリケーションを開発する方法を説明します Windows Azure Platform では データの

WebOTXマニュアル


スライド 1

プレポスト【問題】

Prog2_10th

オブジェクト指向プログラミング・同演習 5月21日演習課題

機能紹介 : Java ゲートウェイとインターシステムズ製品

intra-mart Accel Platform — IM-BloomMaker プログラミングガイド   初版  

PowerPoint Presentation

ISE の BYOD に使用する Windows サーバ AD 2012 の SCEP RA 証明書を更新する

JEB Plugin 開発チュートリアル 第1回

メディプロ1 Javaプログラミング補足資料.ppt

2

Java知識テスト問題

メソッドのまとめ

Team Foundation Server 2018 を使用したバージョン管理 補足資料

デジタル表現論・第6回

PowerPoint プレゼンテーション

McAfee Application Control ご紹介

1. クライアント証明書管理手順 本章では サービス参加機関の利用管理者に配付するクライアント証明書の発行 更新 失効及び管理を行う登録担当者の操作方法について記述します サービス参加機関の利用管理者からクライアント証明書の発行要求があり クライアント証明書の新規発行が必要な場合は 1-2. クライ

PowerPoint Presentation

Prog2_6th

Prog2_12th

SQLインジェクション・ワームに関する現状と推奨する対策案

JAVA H13 OISA JAVA 1

本章では サービス参加機関の利用管理者に配付するサーバ証明書の発行 更新 失効及び管理を行う登録担当者の操作方法について記述します サービス参加機関の利用管理者からサーバ証明書の発行要求があり サーバ証明書の新規発行が必要な場合は 1-1. サーバ証明書新規発行 を行ってください 既にサーバ証明書を

目次 第 1 章はじめに... 3 第 2 章ネットワーク設定 DNS の設定 アウトバウンド HTTPS 接続の許可 アウトバウンド SMTP/POP 接続の許可... 4 第 3 章 JDK への追加ライブラリインストール

think9i Oracle Internet File System i を使用した ソフトウェア開発手法 日本オラクル株式会社製品本部システム製品マーケティング部 Copyright 2001 Oracle Corporation Japan. All Rights Reserved.

Java演習(4) -- 変数と型 --

HDC-EDI Base deTradeII送受信機能起動時におけるJava8のセキュリティ警告とその回避策について

4-4- 基スクリプト言語に関する知識 コードの作成や修正が容易とされるスクリプト言語を学習し アプリケーション開発の手法を習得する 本カリキュラムでは まずスクリプト言語に位置づけされる Perl PHP Python JavaScript Ruby といった Ⅰ. 概要プログラミング言語の特徴に

Microsoft Word 基_シラバス.doc

新環境への移行手順書

- 2 / 25 - 表示される

--- サーバ側処理 Java servlet の例 // 通常の Java servlet での POST で受信と同じ protected void dopost(httpservletrequest request, HttpServletResponse response) throws S

HTTP 404 への対処

CA Federation ご紹介資料

JPCERT/CC インシデント報告対応レポート[2017年1月1日-2017年3月31日]

MISAO with WPF

intra-mart Accel Platform — IM-Repository拡張プログラミングガイド   初版  

あなたも狙われている!?インターネットバンキングの不正送金とマルウエアの脅威

Servlet JSP JSP Servlet/JSP における 日 本 語 の 処 理 - 1

Delphi/400でFlash動画の実装

Oracleセキュア・エンタープライズ・サーチ

スライド タイトルなし

intra-mart Accel Platform — OData for SAP HANA セットアップガイド   初版  

基本情報STEP UP演習Java対策

ファイル アップロード

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

Transcription:

Japan Computer Emergency Response Team Coordination Center 電子署名者 Japan Computer Emergency Response Team Coordination Center DN c=jp, st=tokyo, l=chiyoda-ku, email=office@jpcert.or.jp, o=japan Computer Emergency Response Team Coordination Center, cn=japan Computer Emergency Response Team Coordination Center 日付 2013.09.27 091442 +09'00' Javaアプリケーション脆弱性事例調査資料 について この資料は Javaプログラマである皆様に 脆弱性を身 近な問題として感じてもらい セキュアコーディングの 重要性を認識していただくことを目指して作成していま す Javaセキュアコーディングスタンダード CERT/Oracle版 と合わせて セキュアコーディングに 関する理解を深めるためにご利用ください JPCERTコーディネーションセンター セキュアコーディングプロジェクト secure-coding@jpcert.or.jp 1

JBoss Application Server における ディレクトリトラバーサルの脆弱性 CVE-2006-5750 JVNDB-2006-002376 2

JBoss とは JavaEE のアプリケーションサーバ JBoss の名のもとに 40 以上のさまざまなプロジェクトが存在し JBoss.org コミュニティによって開発 運営されている Web サーバ Web アプリケーション 3

JBoss Application Server とは Java で記述されたサーバサイドアプリケーションを動作させるための基盤を提供する JBoss の様々なソフト群の中核になるソフトであることから このソフトを指して単に JBoss と呼ぶ場合もある 4

JBoss Application Server とは JBoss プロジェクトポートフォリオ JBoss Application Server 内に JBoss と名の付く複数のコンポーネントが存在している JBoss Application Server 5.0.0 Administration And Development Guide から引用 http//docs.jboss.org/jbossas/docs/server_configu ration_guide/beta500/html-single/index.html 5

脆弱性の概要 JBoss Application Server には JMX コンソールという管理機能が存在する JMX コンソールは 外部からサーバのシャットダウンやファイルのアップロードなどの管理機能を提供している その中のファイル操作機能においてディレクトリトラバーサルの脆弱性が存在する 6

ディレクトリトラバーサルとは パスの値を不正に操作されることで 想定外のファイルやディレクトリに対して操作が行われてしまう攻撃 ファイル操作 ( 読み出し / 変更 / 削除等 ) におけるパスの値を 外部から受け取った入力を元に動的に生成するアプリケーションで発生する 2 ファイル操作 1 http//www.example.com/?file=../../../../../etc/passwd 3 機密情報の漏えい 7

脆弱性が悪用された場合のリスク 機密情報の漏えい アプリケーションが動作するサーバ上のファイルの内容が読み出され 機密情報が漏えいする可能性があります システムやデータの破壊 改ざん アプリケーションが動作するサーバ上のファイルが改ざん 削除され アプリケーションの誤動作 停止などサービス提供に影響が及ぶ可能性があります 8

JMX コンソールとは JMX コンソールは サーバの実行状況モニタリングや設定の変更などを行う機能 JMX コンソールのファイル操作機能では以下の操作が可能ファイル作成ファイル削除ファイル存在確認 本来はアプリケーションのプログラムが配置されているパス配下のファイルに対してのみ 上記の操作が可能である 9

JMX コンソールの悪用 JMX コンソールから不正なリクエストを送信するだけで脆弱性が悪用でき アプリケーションが稼働するサーバ内の任意のファイル作成 削除 存在確認を行うことが可能となる JBoss Application Server のフォルダ構成 jboss server 本来ファイル操作が可能な範囲 default deploy Manage ment 脆弱性を悪用することで サーバ内の任意のパスのファイル操作が可能となる!! 10

JMX コンソールの悪用 JMX コンソールを通じてファイル作成 / 削除 / 存在確認機能を悪用することでこんなことが可能!! ファイル作成機能 / ファイル削除機能 設定ファイルの削除 / 作成による上書き セキュリティ設定の変更 ユーザーの追加等 不正なバイナリの配置 ウイルスやバックドアの配置等 サーバ上で稼働するサービスへの攻撃 Web コンテンツの改ざん等 ファイル存在確認機能 ディレクトリ構造を調べることで OS バージョンの特定等 11

JMX コンソールにおけるファイル作成 JMX コンソールを利用したファイル作成時の処理フロー は以下のようになる 1 クライアントからリクエストが送信される 2 アプリケーション (Jboss Application Server) がリクエストを受信し フォルダ名 ファイル名 拡張子 ファイルデータの情報を取り出す 3 DeploymentFileRepository クラスの store メソッドでファイルを作成する 4 結果を含むレスポンスがクライアントへ送信される 12

1 クライアントからリクエストが送信される ファイル./testfolder/testfile.txt 作成リクエストがどのように処理されるか見てみよう JMX コンソール 13

1 クライアントからリクエストが送信される HTTP リクエスト POST /jmx-console/htmladaptor HTTP/1.1 Host localhost8080 action=invokeop&name=jboss.admin%3aservice%3ddeploymentfilerepository& methodindex=5&arg0=testfolder&arg1=testfile&arg2=.txt&arg3=testcontent&ar g4=true 上記 HTTP リクエストを送信するための HTML <form action= /jmx-console/htmladaptor method= POST > <input type= hidden name= arg0 value= testfolder > <input type= hidden name= arg1 value= testfile > <input type= hidden name= arg2 value=.txt > <input type= hidden name= arg3 value= testcontent > </form> arg0 作成するファイルの上位フォルダ名 arg1 ファイル名 arg2 ファイル拡張子 arg3 ファイルの内容 14

2 アプリケーションがリクエストを受信し コピー処理を開始 ファイル作成は DeploymentFileRepository クラスの store メソッドで行われる HTTP リクエスト POST /jmx-console/htmladaptor HTTP/1.1 Host localhost8080 &arg0=testfolder&arg1=testfile&arg2=.txt&a rg3=testcontent&arg4=true 経由するメソッド HtmlAdaptorServlet.doPost() HtmlAdaptorServlet.processRequest() HtmlAdaptorServlet.invokeOp() Server.invokeOp() Server.invokeOpByName() MBeanServerImpl.invoke() XMBean(AbstractMBeanInvoker).invoke() Invocation.invoke() Invocation.dispatch() ReflectedDispatcher.invoke() Method.invoke() DelegatingMethodAccessorImpl.invoke() NativeMethodAccessorImpl.invoke() NativeMethodAccessorImpl.invoke0() DeploymentFileRepository.store() DeploymentFileRepository.java public class DeploymentFileRepository public void store( 15

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository extends ServiceMBeanSupport implements DeploymentFileRepositoryMBean public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException arg0 testfolder arg1 testfile arg2.txt arg3 testcontent store メソッドの第 1 引数 (folder) にリクエストの arg0 第 2 引数 (name) に arg1 第 3 引数 (fileextension) には arg2 第 4 引数 (data) には arg3 の値が渡される 16

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository testfolder public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); log.debug("absolute " + dir.getabsolutepath()); if (!dir.exists()) if (!dir.mkdirs()) throw new RuntimeException("Failed to create directory " + dir.tostring()); } } 17

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException testfolder log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); log.debug("absolute " + dir.getabsolutepath()); if (!dir.exists())./deploy/management/testfolder }./deploy/management if (!dir.mkdirs()) 引数 folderを使用してfileオブジェクトを作成する baseはjmxコンソール上で設定されたコンテンツ保存 throw new RuntimeException("Failed のディレクトリパスの to create Filedirectory オブジェクトであり デ " + フォルトでは dir.tostring());./deploy/management となる } そのため ここで作成されるFileオブジェクトのパスは./deploy/management/testfolder となる 18

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException./deploy/management/testfolder log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); log.debug("absolute " + dir.getabsolutepath()); if (!dir.exists()) } if (!dir.mkdirs()) }./deploy/management/testfolder が作成される throw new RuntimeException("Failed to create directory " + dir.tostring()); 19

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository testfile.txt public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException 第 2 引数と第 3 引数を使ってfilenameを作成する ここでは testfile.txt となる if (!dir.mkdirs()) String filename = name.replace(' ', '_') + fileextension; File file = new File(dir, filename); File tmpfile = new File(dir, filename + ".tmp"); PrintWriter writer = new PrintWriter(new FileOutputStream(tmpfile)); writer.write(data); writer.close(); 20

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException./deploy/management/testfolder/testfile.txt if (!dir.mkdirs())./deploy/management/testfolder testfile.txt String filename = name.replace(' ', '_') + fileextension; File file = new File(dir, filename); File tmpfile = new File(dir, filename + ".tmp"); PrintWriter writer = new PrintWriter(new FileOutputStream(tmpfile)); writer.write(data); writer.close(); File オブジェクト./deploy/management/testfolder /testfile.txt を作成 21

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException./deploy/management/testfolder /testfile.txt.tmp./deploy/management/testfolder if (!dir.mkdirs()) testfile.txt String filename = name.replace(' ', '_') + fileextension; File file = new File(dir, filename); File tmpfile = new File(dir, filename + ".tmp"); PrintWriter writer = new PrintWriter(new FileOutputStream(tmpfile)); writer.write(data); writer.close(); 一時ファイル用の File オブジェクト./deploy/management/testfolder /testfile.txt.tmp を作成する 22

3DeploymentFileRepository クラスの store メソッドでファイルを作成 DeploymentFileRepository.java public class DeploymentFileRepository testcontent public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException 一時ファイル if (!dir.mkdirs())./deploy/management/testfolder /testfile.txt.tmp に第 4 引数 dataの値を書きこむ String filename = name.replace(' ', '_') + fileextension; File file = new File(dir, filename); File tmpfile = new File(dir, filename + ".tmp"); PrintWriter writer = new PrintWriter(new FileOutputStream(tmpfile)); writer.write(data); writer.close();./deploy/management/testfolder /testfile.txt.tmp 23

3DeploymentFileRepository クラスの store メソッドでファイルを作成 24 DeploymentFileRepository.java public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException File file = new File(dir, filename); File tmpfile = new File(dir, filename + ".tmp"); PrintWriter writer = new PrintWriter(new FileOutputStream(tmpfile)); writer.write(data); writer.close(); if (file.exists() && nohotdeploy) file.delete(); } if (!tmpfile.renameto(file)) File オブジェクト./deploy/management/testfolder /testfile.txt./deploy/management/testfolder /testfile.txt が既に存在していたら削除する

3DeploymentFileRepository クラスの store メソッドでファイルを作成 25 DeploymentFileRepository.java public class DeploymentFileRepository Fileオブジェクト./deploy/management/testfolder public void store(string folder, /testfile.txt String name, String fileextension, String data, boolean nohotdeploy) throws IOException Fileオブジェクト./deploy/management/testfolder/testfile.txt.tmp File file = new File(dir, filename); File tmpfile = new File(dir, filename + ".tmp"); PrintWriter writer = new PrintWriter(new FileOutputStream(tmpfile)); writer.write(data); writer.close(); if (file.exists() && nohotdeploy) file.delete(); } if (!tmpfile.renameto(file)) 一時ファイル./deploy/management/testfolder /testfile.txt.tmp を./deploy/management/testfolder /testfile.txt に変更して処理が完了

4 結果を含むレスポンスがクライアントへ送信される ファイル作成処理が終了し 結果をレスポンスとしてクライアントへ送信する Success!! 26

攻撃コード HTTP リクエスト POST /jmx-console/htmladaptor HTTP/1.1 Host localhost8080 action=invokeop&name=jboss.admin%3aservice%3ddeploymentfilerepository&methodind ex=5&arg0=........ testfolder&arg1=testfile&arg2=.txt&arg3=testcontent&arg4=true arg0 作成するファイルの上位フォルダ名 arg1 ファイル名 arg2 ファイル拡張子 arg3 ファイルの内容 攻撃コードのポイントパラメータ arg0 の値として上位ディレクトリを示す値を含んだ........ testfolder が指定されている 27

攻撃コード 攻撃コードの HTTP リクエストを送信するための HTML <form action= /jmx-console/htmladaptor method= POST > <input type= hidden name= arg0 value=........ testfolder > <input type= hidden name= arg1 value= testfile > <input type= hidden name= arg2 value=.txt > <input type= hidden name= arg3 value= testcontent > </form> arg0 作成するファイルの上位フォルダ名 arg1 ファイル名 arg2 ファイル拡張子 arg3 ファイルの内容 28

攻撃コードが実行された際の処理 JMX コンソールでのファイル作成時の処理フロー 1 クライアントからリクエストが送信される 2 アプリケーション (Jboss Application Server) がリクエストを受信し フォルダ名 ファイル名 拡張子 ファイルデータの情報を取り出す 3 DeploymentFileRepository クラスの store メソッドでファイルを作成する 4 結果を含むレスポンスがクライアントへ送信される 攻撃コードが実行された際に 3 の処理でディレクトリトラバーサル攻撃が成立する 29

攻撃コード実行時 3DeploymentFileRepository クラスの store メソッドでファイル作成 DeploymentFileRepository.java public class DeploymentFileRepository extends ServiceMBeanSupport implements DeploymentFileRepositoryMBean public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException arg0........ testfolder arg2.txt arg3 testcontent arg1 testfile store メソッドの第 1 引数 (folder) にリクエストの arg0 第 2 引数 (name) に arg1 第 3 引数 (fileextension) には arg2 第 4 引数 (data) には arg3 の値が渡される 30

攻撃コード実行時 3DeploymentFileRepository クラスの store メソッドでファイル作成 DeploymentFileRepository.java........ testfolder public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); log.debug("absolute " + dir.getabsolutepath()); if (!dir.exists()) if (!dir.mkdirs()) throw new RuntimeException("Failed to create directory " + dir.tostring()); } } 31

攻撃コード実行時 3DeploymentFileRepository クラスの store メソッドでファイル作成 DeploymentFileRepository.java........ testfolder public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); log.debug("absolute " + dir.getabsolutepath()); if (!dir.exists())./deploy/management if (!dir.mkdirs()) 引数 folderを使用して作成したfileオブジェクトは./deploy/management/../../../../testfolder throw new RuntimeException("Failed となる to create directory " + これはフォルダ dir.tostring()); deployの2 階層上に位置する } testfolder フォルダを意味する } 32

攻撃コード実行時 3DeploymentFileRepository クラスの store メソッドでファイル作成 DeploymentFileRepository.java public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); log.debug("absolute " + dir.getabsolutepath()); if (!dir.exists()) if (!dir.mkdirs()) } }./deploy/management/../../../../testfolder という File オブジェクト./deploy/management/../../../../testfolder が作成されてしまう throw new RuntimeException("Failed to create directory " + dir.tostring()); 33

攻撃コード実行時 3DeploymentFileRepository クラスの store メソッドでファイル作成 その後は正常処理と同様の処理が実行され 下記の場所にファイルが作成されてしまう 本来は./deploy/management 配下にフォルダ ファイルが作成されるはずが 攻撃コードでパスを操作することで任意のパスにファイルを作成することが可能となる JBoss Application Server のフォルダ構成 jboss server default 本来フォルダやファイルが作成されるパス (./deploy/management 配下 ) deploy testfolder Manage ment 攻撃コードによってファイルが作成されるパス (./deploy/management/../../../../testfolder) testfolder 34

JMX コンソールにはファイル作成以外にも 次の 3 つの機能に同様の脆弱性が存在する 1. ファイル削除 (remove メソッド ) public void remove(string folder, String name, String fileextension) File dir = new File(base, folder); String filename = name.replace(' ', '_') + fileextension; File file = new File(dir, filename); file.delete(); } 2. ファイル存在確認 (isstoredメソッド) public boolean isstored(string folder, String name, String fileextension) File dir = new File(base, folder); String filename = name.replace(' ', '_') + fileextension; File file = new File(dir, filename); return file.exists(); } 35

3. ファイル保存パス設定 (setbasedir メソッド ) public void setbasedir(string basedir) this.basedir = basedir; this.base = new File(serverHome, basedir); } 36

問題点 今回のアプリケーションにおける具体的な問題点 引数として渡されたパスの値を検証せずに処理を行っていた 以下のコーディングガイドに違反している MET00-J. メソッドの引数を検証する IDS02-J. パス名は検証する前に正規化する 37

問題点 問題点に対してどうすべきだったか 引数の値を使って構成したパスが 想定しているディレクトリの下にあることを検証した上で ファイルを作成すべきであった パスの検証のためには パスの正規化処理が必要 38

修正版コード 脆弱性はバージョン 4.2.0 で修正されている JMX コンソールでのファイル作成時の処理フロー 1 クライアントからリクエストが送信される 2 アプリケーション (Jboss Application Server) がリクエストを受信し フォルダ名 ファイル名 拡張子 ファイルデータの情報を取り出す 3 DeploymentFileRepository クラスの store メソッドでファイルを作成する 4 結果を含むレスポンスがクライアントへ送信される 3 の処理を行うコードが修正されている 39

修正前 / 修正後の処理比較 3DeploymentFileRepository クラスの store メソッドでファイル作成 DeploymentFileRepository.java ( 修正前 ) public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException log.debug("store called"); File dir = new File(base, folder); log.debug("respository folder " + dir.tostring()); DeploymentFileRepository.java ( 修正後 ) public class DeploymentFileRepository public void store(string folder, String name, String fileextension, String data, boolean nohotdeploy) throws IOException log.debug("store called"); File dir = getfile(base, folder); log.debug("respository folder " + dir.tostring()); getfile メソッドを使用するようにコードが変更されている 40

修正前 / 修正後の処理比較 3DeploymentFileRepository クラスの store メソッドでファイル作成 getfile メソッド./deploy/management store メソッドの第 1 引数 ( フォルダ名 ) private File getfile(file parent, String child) throws IOException 新規作成するフォルダの File childfile = new File(parent, child); Fileオブジェクトを作成 } if (childfile.getcanonicalpath().indexof(parent.getcanonicalpath())!= 0) throw new IllegalArgumentException( "child '" + child + "' should be a child of parent '" + parent + "' ); getcanonicalpathメソッドで正規化をした後に return childfile; indexofメソッドを使用して parentがchildfileの一部に含まれているか検証している getcanonicalpath メソッドを使用すると /parent/child1/child2/../../child0 /parent/child0 というように正規化される 41

修正前 / 修正後の処理比較 3DeploymentFileRepository クラスの store メソッドでファイル作成 修正版コードが攻撃を受けるとどうなるか getfile メソッド内で getcanonicalpath メソッドにより parent./deploy/management /jboss/server/default/deploy/management childfile./deploy/management/../../../../testfolder /jboss/server/testfolder と正規化される パスを検証するコードが childfile のパスに parent が含まれていないことを検知し エラーとして処理する 42

その他の修正 下記のメソッドも getfile メソッドを利用したパスの正規化と検証を行うように修正されている ファイル削除 (remove メソッド ) ファイル存在確認 (isstored メソッド ) ファイル保存パス設定 (setbasedir メソッド ) 43

まとめ この脆弱性から学べるプログラミングの注意点 アプリケーションの処理内容や扱うデータ構造に応じて 引数が適切な値であることを検証すべき 今回のケースでは ファイル / ディレクトリ操作で扱うパス名を細工されることで ディレクトリトラバーサルの脆弱性につながった 上記への対策 引数のパス名を正規化してから (IDS02-J) 想定した範囲に収まっていることを確認する 44

著作権 引用や二次利用について 本資料の著作権は JPCERT/CC に帰属します 本資料あるいはその一部を引用 転載 再配布する際は 引用元名 資料名および URL の明示をお願いします 記載例 引用元 一般社団法人 JPCERT コーディネーションセンター Java アプリケーション脆弱性事例解説資料 Jboss Application Server におけるディレクトリトラバーサルの脆弱性 https//www.jpcert.or.jp/securecoding/2012/no.05_jboss.pdf 本資料を引用 転載 再配布をする際は 引用先文書 時期 内容等の情報を JPCERT コーディネーションセンター広報 (office@jpcert.or.jp) までメールにてお知らせください なお この連絡により取得した個人情報は 別途定める JPCERT コーディネーションセンターの プライバシーポリシー に則って取り扱います 本資料の利用方法等に関するお問い合わせ JPCERTコーディネーションセンター広報担当 E-mailoffice@jpcert.or.jp 本資料の技術的な内容に関するお問い合わせ JPCERT コーディネーションセンターセキュアコーディング担当 E-mailsecure-coding@jpcert.or.jp 45