sServletFilterScript (JavaScript で制御する ServletFilter)

JavaScript で制御する ServletFilter です。

ベースは、《Apache Struts2(2.3.16、S2-020の修正版)に対するゼロディを弊社エンジニアが発見いたしました。 からリンクされているhttp://www.mbsd.jp/img/testFilter.java》ですが、元々 Content-Type の DoS 脆弱性のために作った ServletFilter を手直ししました


謝辞

プログラミングにあたり @kinyuka さん、@masa141421356 さん、NTT-Cert 鈴木さんには大変有益なご助言を頂きました。ありがとうございます


仕様上の注意

どうも、MIME データを取得すると、それ以降の Filter(おそらくServletも)にて、MIMEデータを取得できなくなるようです。
javax.servlet.ServletInputStream に mark() メソッド、reset() メソッド共に実装されていないためと思われます。

(ver1.0で解決) Servlet3.0(Tomcat7) 以降で getPart()/getParts() を使用しているアプリケーションには不具合が出ます。


特徴




仕様上の注意

SevletFilter の起動順には注意しましょう


設定方法

  1. バイナリを使用する、またはソースコードをコンパイルする

  2. ソースコードは、UTF-8/CrLf です。お使いの環境に合わせて、文字コード/改行コードを変換してください

  3. ソースコードをコンパイルする際、(%tomcat%/commom/lib/ または %tomcat%/lib/ 配下の "servlet-api.jar") をクラスパスに入れてコンパイルする必要があります。

  4. jar ファイルを作成する際は「jar.exe cvf sServletFilterScript.jar *.class」な感じのコマンドで作成できます。
  5. %tomcat%/.../WEB-INF/classes/ 配下に「common.class」「FakeHttpServletRequest.class」「FakeHttpServletRequestWrapper.class」「FileWrapper.class」「MemoryInputStream.class」「retclass.class」「sServletFilterScript.class」を配置します。

  6. jar ファイルを使う場合、%tomcat%/.../WEB-INF/lib/ 配下に「sServletFilterScript.jar」を配置します
  7. class ファイル群を使う場合、%tomcat%/.../WEB-INF/classes/ 配下に「common.class」「FakeHttpServletRequest.class」「FakeHttpServletRequestWrapper.class」「FileWrapper.class」「MemoryInputStream.class」「retclass.class」「sServletFilterScript.class」を配置します。

  8. %tomcat%/.../WEB-INF/web.xml を編集して、ServletFilter を Tomcat に登録します。
    例えば、
    <filter>
     <filter-name>sServletFilterScript</filter-name>
     <filter-class>sServletFilterScript</filter-class>
     <init-param>
      <param-name>ScriptEngine</param-name>
      <param-value>js</param-value>
     </init-param>
     <init-param>
      <param-name>ScriptFilePath</param-name>
      <param-value>/tmp/sServletFilterScript.js</param-value>
     </init-param>
     <init-param>
      <param-name>MIMECharset</param-name>
      <param-value>UTF-8</param-value>
     </init-param>
     <init-param>
      <param-name>IsDebug</param-name>
      <param-value>TRUE</param-value>
     </init-param>
     <init-param>
      <!-- from http://www.cybersyndrome.net/env.cgi -->
      <param-name>LogHeaderName</param-name>
      <param-value>X_LOCKING,X_FORWARDED_FOR,SP_HOST,FORWARDED,CLIENT_IP</param-value>
     </init-param>
    </filter>
    <filter-mapping>
     <filter-name>sServletFilterScript</filter-name>
     <url-pattern>/*</url-pattern>
    </filter-mapping>


  9. スクリプトを書きます。
    例えば、
    var returl = "http://www.example.com/";
    var checked = false;
    var IsMime = false;
    var regex = "(^|\\W)[cC]lass\\W";
    // MIME かどうか・・・
    if(jObj.isMime() == true){
     IsMime = true;
     // MIME の時点でアウトもあり
     // checked = true;
     // jObj.SetRetUrl(returl);
     var str = jObj.getHeader("content-type");
     jObj.LogWrite("Content-Type=" + str);
     // 4096以上だとアウト
     if(4096 > str.length){
      checked = true;
      jObj.SetRetUrl(returl);
     }
    }
    if(checked == false){
     if(jObj.CheckRegex(regex,true,true,IsMime) == true){
      jObj.SetRetUrl(returl);
      jObj.LogWrite("Bingo");
     }else{
      jObj.LogWrite("No Hit");
     }
    }


  10. ログは、%tomcat%/logs/ 以下の catalina.out または、指定されたファイルへ出力されます。



ServletFilter での初期化パラメータ(web.xml の filter → init-param)は以下です。
プロパティ名意味既定値
ScriptEngineスクリプトエンジンを指定するjs
ScriptFilePathスクリプトの保存しているファイル/ディレクトリを指定する-
ScriptExcludedExtentionsスクリプトとして実行しないファイルの拡張子(ファイル名の後半部分)をCSV形式で指定(ScriptFilePath がディレクトリ指定の場合のみ)-
MIMECharsetMIME 対象の場合の文字コードを指定するUTF-8
IsDebugログ出力のレベル(デバグモードかどうか)true
LogHeaderNameログ出力時のヘッダ名の指定(カンマ区切りで複数指定可能)-
LogFilePathログファイルの指定。この後ろに《日付》+《.log》がつく。指定がない場合は catalina.out-
TempDirectoryServletInputStream のバックアップ先の一時ファイルのディレクトリ。指定がない場合はメモリ上に保持-
IsServerSigHTTP Response Header にサインを出力するかどうかfalse



スクリプトに公開しているオブジェクトは「jObj」
プロパティ/メソッド名意味
(HttpServletRequest)reqServletFilter内部で使われている HttpServletRequest クラスそのもの
ver1.2で廃止
(HttpServletRequest)getHttpServletRequest()ServletFilter内部で使われている HttpServletRequest クラスそのもの
ver1.2
(String)returlヒット時にリダイレクトさせる先の Web ページの URL
(void)LogWrite(String)LogWrite(msg,true)
(void)LogWrite(msg,Boolean)catalina.out へログ出力する。第二引数が true の場合はデバグモードなくても出力する
(void)SetMIMEboundary(String)第一引数から、MIME デリミタ文字列を抽出してクラス内部に格納
(boolean)isMime()HTTPリクエストが MIME 形式かどうか
(String)getHeader(String)HTTPリクエストから特定のリクエストヘッダを取得する
(boolean)isAttack(String)第一引数に対して、既に登録された正規表現でのチェックを行う
(boolean)CheckRegex(String,boolean,boolean,boolean)パラメータ(GET/POST)、クッキー、MIME の名前に対して正規表現チェックを行う
第一引数 : 正規表現
第二引数 : パラメータをチェック対象とするかどうか
第三引数 : クッキーをチェック対象とするかどうか
第四引数 : MIME の場合、MIME ボディをチェック対象とするかどうか
MIME データは、複数行拡張ヘッダ対策のため、タブ、改行、スペースなどを削除した一行の状態で比較するため、先頭を示す正規表現「^」や最後尾を示す「$」はない方がよいだろう
(boolean)CheckRegexName(String,boolean,boolean,boolean)(boolean)CheckRegex(String,boolean,boolean,boolean)
(boolean)CheckRegexValue(String,boolean,boolean,boolean)値に対して正規表現チェック{CheckRegex()}を実行する
(boolean)CheckRegexValue(boolean,boolean,boolean)既に登録した正規表現を使って、値に対して正規表現チェック{CheckRegex()}を実行する
(boolean)CheckRegexName(boolean,boolean,boolean)既に登録した正規表現を使って、名前に対して正規表現チェック{CheckRegex()}を実行する
(void)init()DecodeCount と DecodeCharset を初期化する
(void)SetDecodeCharset(String)CheckRegex() 系のチェックにて URL デコードする際の文字コード(既定は「UTF-8」)をセットする
(void)SetDecodeCount(int)CheckRegex() 系のチェックにて URL デコード(文字コード=UTF-8)する回数(既定は「0」回)をセットする
(int)GetDecodeCount()CheckRegex() 系のチェックにて URL デコード(文字コード=UTF-8)する回数を返す
(String[])getMIMEBodyHako()リクエストボディを MIME として分割する
(String)getMIMEBody()リクエストから、MIME の場合は、ボディを返す
(String)csvExcape()ログを解析しやすいように CSV 形式のエスケープを実施する
「"」「\」「,」「\r」「\n」がある場合、
「\」→「\\」
「"」→「""」
「\r」→「\\r」
「\n」→「\\n」
(void)SetPatternObj(java.util.regex.Pattern)正規表現オブジェクトをクラス内部へセットする
(void)SetPattern(String)正規表現をクラス内部へセットする
(String)GetPattern()クラス内部へセットした正規表現を得る(セットしていなければ null が返る)
(void)SetPatternUnicodeCase()クラス内部へセットした正規表現を、大文字/小文字を区別するようにコンパイルする
(void)SetPatternCaseInsensitive()クラス内部へセットした正規表現を、UNICODE に準拠した大文字/小文字を区別しないようにコンパイルする
(void)SetRetUrl(String)リダイレクト先の URL をセットする
(void)dobreak = true/false;再帰的に次のスクリプトを読まないようにする(既定は false{次のスクリプトを読む})






to do list



著作権は保持します。(とりあえず...)
しかし、プログラムの実行においては、各自の責任で行ってください。

このソフトを使用したいかなる不正使用に関する責任は、
すべて、本プログラムの利用者に属します。

プログラムの改変については、各自の責任で行う分については、自由に行って結構です。(参考になりましたメールをくれると、うれしい...(*^_^*))


download
All files set
sServletFilterScript.lzh LZH file (42,594byte) (sServletFilterScript.lzh.base64)
バイナリは、JDK1.6.0_07-b6 と ApacheTomcat5.5.26 でコンパイルしたもの

ソースの説明

省略


mail to active@window.goukaku.com