Problemas y soluciones del método de eco general para middleware de Java (actualización 7.7)

Antes de escribir "basado en la búsqueda de objetos de solicitud / respuesta del método de eco universal de middleware Java (para HTTP)" , habrá problemas en el uso real, y luego riegue el artículo por separado para resolverlo.

Si hay otras preguntas en el futuro, las actualizaré aquí ~

No hay eco / alta concurrencia

El maestro Can Xiao me dio su opinión: Solo en un entorno de alta concurrencia se pueden ver los resultados del eco. Los resultados incluyen: el caso de salida de comando sin HTTP, el caso de no eco, el caso de eco y el número de ecos. Tiempos de la situación.

Aquí hay una explicación:
Este artículo resuelve principalmente el problema de que cuando hay otras solicitudes normales en el sitio, el eco puede ser encadenado. Por
ejemplo: Además de la solicitud de ejecución del comando, hay otras 10 solicitudes que están visitando el sitio al mismo tiempo, que pueden aparecer Bit de cadena.

Este problema se debe a que se busca en la cola NIO. Debido a que la Solicitud está limitada por la existencia del encabezado cmd, la Solicitud buscada debe ser su Solicitud, pero la Respuesta es difícil de decir, es decir, si está enviando este paquete de ataque En ese momento, si hay otras personas de visita, es muy probable que el resultado de su comando se refleje en los resultados de otras visitas.

En la prueba anterior, solo se probó un hilo, por lo que no se encontró este problema, emm, aún es necesario probarlo adecuadamente.

Prueba de simulación:

Simular el acceso normal: Burp Intruder usa cargas útiles nulas para enviar 1000 veces, simultáneamente 10, y el intervalo de envío fijo es de 500 ms.

Lo que visita es en realidad una página 404

Inserte la descripción de la imagen aquí

Acceso de ataque simulado: Burp Repeater envía paquetes de ataque

Luego puede encontrar que en algunas solicitudes de ataque, la respuesta está vacía, pero el resultado que queremos aparece en una solicitud normal:

Los resultados de ciertas solicitudes de ataque no se encontraron en ninguna parte. Debería ser el objeto Response el que se encontró. Se destruyó antes de ser escrito. .

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Solución

En la actualidad, leí el código de Tomcat, Weblogic, Jetty, JBOSS y descubrí que hay objetos de respuesta correspondientes debajo del objeto de solicitud, por lo que ahora que el objeto de solicitud se puede ubicar con precisión, la respuesta también está disponible.

(El resposne de Jetty no está incluido directamente en el objeto de solicitud, los tres tienen métodos getResponse sin parámetros, solo llámalo directamente por reflexión ~)

PD: Hace unos días, estaba en el pequeño círculo secreto del Maestro P y le dije al Maestro Kingkk que era extraño tener Respuesta bajo el objeto Solicitud de Weblogic.Como resultado, todo el middleware estaba haciendo esto, emm, yo estaba fuera. . .

Hasta ahora, he probado Tomcat / Weblogic / Jetty y no hay problema. JBoss es demasiado vago para instalarlo. Si está interesado, puede probarlo.

Inserte la descripción de la imagen aquí

Código modificado:

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

referencia:

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

El nombre de la clase de solicitud de Weblogic es:weblogic.servlet.internal.ServletRequestImpl

El eco de Tomcat es inestable

El maestro ph4nt0mer informó que Tomcat no era estable. Después de la prueba, se encontró que:

Además de Tomcat org.apache.catalina.connector.Request, org.apache.catalina.connector.Request.RequestFacadeesta clase contenedora hereda la HttpServletRequestinterfaz.

Pero RequestFacadeno incluye getReponsemétodos, no se puede obtener precisión al objeto Respuesta.

Modifique la siguiente lógica:

  1. Si el getResponsemétodo no se puede llamar a través de la reflexión , se considera que no se ha buscado el objeto Request correcto y se restablece el campo r
  2. Como la respuesta solo se obtiene de la solicitud, se elimina la lógica de búsqueda de respuesta original.

Código modificado:
(Lo mismo se aplica a otros middleware)

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

referencia:

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

URLCLassLoader no se puede repetir

Esto es descubierto por el maestro de vainilla y cargado usando URLCLassLoader (cadena como CommonsCollection1):

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

Ocurrió un error:

Inserte la descripción de la imagen aquí

No se pudo encontrar HTTPServletRequest .

Probablemente la razón es que URLClassLoader no agrega parámetros, el cargador principal es SystemClassLoader y la clase Web Java no está cargada en SystemClassLoader. (Este no es muy familiar, tenemos que aprender más después)

Intenté proporcionar las clases HTTPServletRequest y HTTPServletResponse en el paquete jar cargado por URLClassLoader. Se pueden ejecutar normalmente, pero no se pueden encontrar Solicitud y Respuesta.

Realice los siguientes experimentos:

<%
    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 y true se muestran respectivamente, lo que significa que HttpServletRequest cargado a través de URLClassLoader no tiene relación de herencia con la solicitud actual, por lo que esto es inútil.

Información encontrada:

一个类, 由不同的La instancia del cargador de clases 加载que 方法区generará 两个不同的类, 彼此不可见y la generación 不同Class实例.

En otras palabras, es imposible resolver este problema proporcionando clases relacionadas en el paquete jar cargado de forma remota.

Luego otra forma de pensar:

  1. No use HttpServletRequest, HTTPServletResponse directamente, sino cargue a través del cargador de clases del hilo actual:

    Class hsr = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.http.HttpServletRequest");
    
  2. Dado que HttpServletRequest no se puede cargar directamente, no se puede usar la conversión de tipo forzada, sino que se pueden llamar métodos como getHeader \ getWriter por reflexión.

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

La clase modificada:

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

El maestro de la vainilla también propuso una solución:

En la clase cargada con URLCLassloader, también es una buena idea crear un URLClassLoader que use el ClassLoader del hilo actual y cargue la clase echo.

referencia:

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

La cadena BasicDataSource + BCEL no se puede repetir

Esto fue descubierto por el maestro Frost Blue. No preparó el entorno de deserialización y escribió un código de cadena de activación.

<%@ 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();
    %>

El problema de la parte ClassLoader es el mismo que el de URLClassLoader, pero getConnection provocará una excepción y, si no se detecta, la solicitud no responderá.

Inserte la descripción de la imagen aquí

Por lo tanto, se agrega un cierre después del vaciado de PrintWriter para evitar las excepciones de respuesta causadas por las excepciones de captura.

Código modificado:

Lo mismo que arriba.

Supongo que te gusta

Origin blog.csdn.net/fnmsd/article/details/106890242
Recomendado
Clasificación