Javaミドルウェアの一般的なエコーメソッドの問題と解決策(アップデート7.7)

「Javaミドルウェアユニバーサルエコーメソッド(HTTP用)のリクエスト/レスポンスオブジェクト検索に基づいて」を書く前に、実際の使用に問題があり、それを解決するために別の記事に水をかけます。

今後他に質問があればこちらで更新します〜

エコー/高並行性はありません

マスターキャンシャオからフィードバックがありました:同時実行性の高い環境でのみエコーの結果が表示されます。結果には、HTTPのみのコマンド出力がない場合、エコーがない場合、エコーの場合、およびエコーの数が含まれます。状況を回します。

説明は次のとおりです:
この記事では、サイトに他の通常のリクエストがある場合、エコーが文字列化される可能性があるという問題を主に解決します。
例:コマンド実行リクエストに加えて、同時にサイトにアクセスしている他の10のリクエストが表示される場合があります。文字列ビット。

この問題は、NIOキューが検索されるために発生します。リクエストはcmdヘッダーの存在によって制限されるため、検索されたリクエストは自分のリクエストである必要がありますが、レスポンスは言うことが困難です。つまり、この攻撃パッケージを送信する場合その時、他の人が訪問している場合、あなたのコマンドの出力が他の訪問の結果に出力される可能性が非常に高いです。

前のテストでは、単一のスレッドのみがテストされたため、この問題は見つかりませんでした。ええと、まだ十分にテストする必要があります。

シミュレーションテスト:

通常のアクセスのシミュレーション: Burp IntruderはNullペイロードを使用して1000回、同時に10回送信し、固定送信間隔は500msです。

アクセスしたのは実際には404ページです

ここに画像の説明を挿入

シミュレートされた攻撃アクセス: Burp Repeaterが攻撃パケットを送信します

次に、一部の攻撃リクエストでは応答が空であることがわかりますが、必要な結果は通常のリクエストに表示されます。

特定の攻撃要求の結果はどこにも見つかりませんでした。見つかったのはResponseオブジェクトであるはずです。書き込まれる前に破棄されました。

ここに画像の説明を挿入

ここに画像の説明を挿入

解決

現在、Tomcat、Weblogic、Jetty、JBOSSのコードを読み、Requestオブジェクトの下に対応するResponseオブジェクトがあることがわかりました。これで、Requestオブジェクトを正確に配置できるようになり、Responseも利用できるようになりました。

(Jettyのresposneはリクエストオブジェクトに直接含まれていません。3つすべてにパラメーターのないgetResponseメソッドがあります。リフレクションで直接呼び出すだけです)

PS:数日前、私はマスターPの小さな秘密サークルにいて、WeblogicのRequestオブジェクトの下にResponseがあるのは奇妙だとマスターKingkkに話しました。その結果、ミドルウェアはすべてこれを行っていました。

これまでのところ、Tomcat / Weblogic / Jettyをテストしましたが、問題はありません。JBossはインストールが面倒なので、興味があれば試してみてください。

ここに画像の説明を挿入

変更されたコード:

https://gist.github.com/fnmsd/5c98b20cef16cf4942de0eba34dc2ad7

参照:

http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/connector/Request.html#field_summary

https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/server/Request.html

https://docs.jboss.org/jbossweb/latest/api/org/apache/catalina/connector/Request.html

Weblogicのリクエストクラス名は次のとおりです。weblogic.servlet.internal.ServletRequestImpl

Tomcatエコーが不安定

マスターph4nt0merは、Tomcatが安定していないと報告しました。テストの結果、次のことがわかりました。

Tomcat org.apache.catalina.connector.Request加えてorg.apache.catalina.connector.Request.RequestFacadeこのラッパークラスはHttpServletRequestインターフェースを継承します。

ただしRequestFacadegetReponseメソッドが含まれていないため、Responseオブジェクトに対して正確に取得できません。

次のロジックを変更します。

  1. getResponseメソッドがリフレクションを介して呼び出されない場合、正しいRequestオブジェクトが検索されていないと見なされ、rフィールドがリセットされます
  2. 代わりに、応答は要求からのみ取得されるため、元の応答検索ロジックは削除されます。

変更されたコード:(
同じことが他のミドルウェアにも適用されます)

https://gist.github.com/fnmsd/4d9ed529ceb6c2a464f75c379dadd3a8

参照:

https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/connector/RequestFacade.html

URLCLassLoaderをエコーできません

これはバニラマスターによって発見され、URLCLassLoader(CommonsCollection1のようなチェーン)を使用してロードされます。

new URLClassLoader(new URL[]{
    
    new File("aaaa.jar").toURI().toURL()}).loadClass("a1").newInstance();

エラーが発生しました:

ここに画像の説明を挿入

HTTPServletRequestが見つかりませんでした

その理由は、URLClassLoaderがパラメーターを追加せず、親ローダーがSystemClassLoaderであり、Java WebクラスがSystemClassLoaderにロードされていないためです。(これはあまりよく知られていないので、後でもっと学ぶ必要があります)

URLClassLoaderによってロードされたjarパッケージにHTTPServletRequestクラスとHTTPServletResponseクラスを提供しようとしましたが、それらは正常に実行できますが、要求と応答が見つかりません。

次の実験を行います。

<%
    Class o = new URLClassLoader(new URL[]{new File("aaa.jar").toURI().toURL()}).loadClass("javax.servlet.http.HttpServletRequest");
    System.out.println(o.isAssignableFrom(request.getClass()));
    System.out.println(HttpServletRequest.class.isAssignableFrom(request.getClass()));

%>

Falseとtrueはそれぞれ出力されます。つまり、URLClassLoaderを介してロードされたHttpServletRequestには現在のリクエストとの継承関係がないため、これは役に立たないということです。

見つかった情報:

一个类由不同的クラスローダーインスタンス加载、それは方法区生成され两个不同的类彼此不可见そして生成され不同Class实例ます。

つまり、リモートでロードされたjarパッケージに関連クラスを提供することでこの問題を解決することは不可能です。

次に、別の考え方:

  1. HttpServletRequest、HTTPServletResponseを直接使用せず、現在のスレッドのクラスローダーを介してロードします。

    Class hsr = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.http.HttpServletRequest");
    
  2. HttpServletRequestを直接ロードできないため、強制的な型変換を使用できず、リフレクションによってgetHeader \ getWriterなどのメソッドを呼び出すことができます。

    hsr.getMethod("getHeader",new Class[]{
          
          String.class}).invoke(o,"cmd");
    

変更されたクラス:

https://gist.github.com/fnmsd/2fd47012849f25eb53d703f283679462

バニラマスターも解決策を提案しました:

URLCLassloaderでロードされたクラスでは、現在のスレッドのClassLoaderを使用するURLClassLoaderを作成し、エコークラスをロードすることもお勧めします。

参照:

https://blog.csdn.net/csdnlijingran/article/details/89226943

BasicDataSourceチェーン+ BCELはエコーできません

これはマスターのFrost Blueによって発見されましたが、デシリアライゼーション環境を準備しておらず、トリガーチェーンコードを記述していません。

<%@ page import="com.sun.org.apache.bcel.internal.util.ClassLoader" %>
<%@ page import="org.apache.tomcat.dbcp.dbcp2.BasicDataSource" %>
<%    
	ClassLoader  cl = new ClassLoader();
    String BCEL = "$$BCEL$$。。。。。";
    BasicDataSource bds = new BasicDataSource();
    bds.setDriverClassLoader(cl);
    bds.setDriverClassName(BCEL);
    bds.getConnection();
    %>

ClassLoaderパーツの問題はURLClassLoaderの問題と同じですが、getConnectionは例外を引き起こし、キャッチされない場合、リクエストは応答しません。

ここに画像の説明を挿入

したがって、PrintWriterのフラッシュ後にクローズが追加され、キャッチされない例外によって引き起こされる応答例外が防止されます。

変更されたコード:

同上。

おすすめ

転載: blog.csdn.net/fnmsd/article/details/106890242