¿Cómo usó Anonymous UTF-16 ASCII para engañar a PHP escapándose?

21

Hace unos meses, Anonymous eliminó un sitio de pornografía infantil mediante inyección SQL. Leí en este artículo que Anonymous afirmó que "el servidor estaba usando PHP endurecido con escape", pero pudieron "evitarlo con la codificación ASCII UTF-16". ¿Qué significa eso que hicieron exactamente? ¿Cómo protejo mi sitio de un ataque similar?

    
pregunta Nate Glenn 02.02.2012 - 21:16
fuente

4 respuestas

26

En primer lugar, la "codificación UTCI-16 ASCII" es una contradicción, ya que UTF-16 y ASCII son esquemas de codificación mutuamente excluyentes. Pero presumiblemente se está refiriendo al uso de Unicode para omitir los mecanismos de filtrado.

El principio general es este: a menudo pensamos en caracteres codificados en ASCII: "A" es el número 65, "z" es el número 122. Pero ese no es el único esquema de codificación de caracteres; Debido a que el mundo usa más que solo el alfabeto inglés, necesitamos representar muchos más caracteres que eso. Por lo tanto, Unicode, que tiene representaciones para casi todos los personajes en todos los idiomas escritos, desde el cingalés hasta el klingon.

Representar a todos esos caracteres (aproximadamente 1.1 millones posibles, no todos en uso) en forma numérica es un verdadero desafío. Podría usar 32 bits, pero eso es un desperdicio de espacio ya que 3 de los 4 bytes suelen ser cero. Podría usar una longitud variable, pero luego no puede realizar operaciones de subcadenas de tiempo constante. Por lo tanto, existen varios estándares, uno de los cuales es UTF-16 (que probablemente haya adivinado utiliza caracteres de 16 bits).

No todos los programadores están acostumbrados a la idea de tratar con conjuntos de caracteres múltiples, aunque el marco subyacente a menudo los respalde. Por lo tanto, a veces se establecerán reglas o precauciones de filtrado asumiendo que los caracteres estarán representados en UTF-8 o ASCII, que generalmente son.

Entonces, el filtro busca una cadena dada, como \" por ejemplo, que en ASCII y UTF-8 corresponde al patrón {92,34}. Pero en UTF-16 se ve diferente; en realidad es {0,92,0,34}, que es lo suficientemente diferente como para deslizarse por un filtro que no lo esperaba.

Y aunque el filtro no comprende UTF-16, el marco subyacente sí lo hace, por lo que el contenido se normaliza e interpreta de la misma manera que cualquier otra cosa, lo que permite que la consulta continúe sin filtrar.

EDITAR PARA AGREGAR:
Tenga en cuenta que PHP es excepcionalmente pobre en el manejo de codificaciones de caracteres; y en todo caso, eso es subestimar el problema. PHP, por defecto, trata a todas las cadenas como ASCII, lo que significa que las funciones internas como strstr y preg_replace simplemente asumen que todas las cadenas están codificadas en ASCII. Si eso suena peligrosamente inadecuado, es porque lo es. Pero en su defensa, recuerde que PHP es anterior a UTF-16 en aproximadamente un año, y todo esto supuestamente se soluciona en la versión 6 de PHP.

Mientras tanto, la biblioteca mbstring se creó para abordar esta deficiencia, pero no se implementa ni se despliega ampliamente. Si tienes la suerte de tener esta extensión a tu disposición, puedes utilizar mbstring.overload en su archivo php.ini para forzar a las funciones internas de procesamiento de cadenas a ser reemplazadas por alternativas multibyte-aware. Esto también se puede activar usando la directiva php_admin_value en sus archivos .htaccess .

Otra función útil es mb_internal_encoding , que establece la codificación utilizada internamente por PHP para representar cadenas. Al utilizar una codificación interna compatible con Unicode, puede aliviar algo de maldad. Al menos una referencia que leí (pero lamentablemente no puedo encontrar ahora) sugiere que al establecer la codificación interna en UTF-8, habilita el procesamiento adicional en las cadenas de entrada que las normalizan a una sola codificación. Por otro lado, al menos otra referencia sugiere que PHP se comporta de la manera más estúpida posible en este sentido, y simplemente absorbe los datos sin modificar independientemente de su codificación, y le permite lidiar con las consecuencias. Mientras que el primero tiene más sentido, con lo que sé sobre PHP, creo que lo segundo es igual de probable.

Como alternativa final; y menciono esto solo en parte en broma, es simplemente no usar PHP y en su lugar adoptar una arquitectura mejor diseñada. Es difícil encontrar un marco tan popular que tenga tantos problemas fundamentales como PHP. El lenguaje, la implementación, el equipo de desarrollo, la arquitectura de complementos, el modelo de seguridad, es realmente una pena que PHP esté tan ampliamente implementado como lo está. Pero esto es, por supuesto, solo una opinión.

    
respondido por el tylerl 04.02.2012 - 04:39
fuente
4

No tengo idea si este es el método que usó Anonymous, pero eche un vistazo a enlace

Parece que hubo un error en Connector.Net (controlador .Net administrado de MySQL). Desde el informe de error vinculado:

  

Las cadenas .net están codificadas en UTF-16. Las cadenas se convierten a Windows-1252 (SBCS   Codificación) para enviar a través de la red y durante esta conversión, los caracteres Unicode que   Es posible que no se haya comprobado que "se conviertan" en comillas simples.

El informe de errores continúa para enumerar una cadena que contiene el carácter Unicode problemático y dice:

  

Específicamente, en la segunda cadena, la cita del problema es el carácter Unicode 8242 ("\ u8242"). Cuando el servidor reciba esta cadena, la cotización será una comilla simple (ASCII 96) y romperá la consulta y podría utilizarse como un ataque de inyección de SQL.

El error vinculado se marcó como un duplicado de un error fijo en 2009, pero es completamente posible que el servidor explotado estuviera ejecutando una versión anterior de MySql que tenía este problema.

    
respondido por el Farray 05.02.2012 - 10:46
fuente
3

Llegué a la conclusión del artículo de que el sitio dependía más de las técnicas de "endurecimiento" que del buen filtrado / escape de entrada de SQL. No hay ninguna prueba de que el código SQL de los sitios de pornografía infantil no sea defectuoso.

La omisión de los llamados filtros de PHP reforzados suele ser bastante trivial. ModSecurity, por ejemplo, se puede omitir con bastante facilidad y los atacantes utilizan constantemente varios métodos para desplazarse por estos filtros de entrada.

También hay filtros que se incluyen en el código del sitio web como complementos que no codifican correctamente la entrada antes de buscar entradas maliciosas.

Por ejemplo: %5e

como se ve en:

id=0%5E(select%20position(0x61%20in%20(select%20id%20from%20users%20where%20num=1))=1)

Al jugar con estos caracteres como "% bf% 5c% 27", "% bf% 27", "% ef% bb% bf", "% 8c% 5c", es posible omitir el llamado endurecimiento para activar la inyección.

Peor aún son los filtros de la lista blanca que actualizan recursivamente $ _GET con caracteres permitidos en la lista blanca, como:

$cleansed = preg_replace( "/[^\s{}a-z0-9_\.\-]/i", "", urldecode( $get ) );

Entonces considera esto: id = -1% 20ui * o + s | e | l | e | c | t + 1, ^ 2, * 3, [4, [5,] 6,] 7, < 8, < 9, & gt ; 10 >

Si bien la idea de urldecoding antes de filtrar es una buena idea, es completamente inútil, ya que los caracteres de la lista negra se eliminan, por lo que se entrega el vector de inyección en su forma original.

De hecho, este método puede anular la capacidad de los atacantes para evitar a los llamados endurecedores de PHP y mods de filtrado como modsecurity.

Al final, la solicitud se está elaborando de una manera específica para omitir el filtrado de entrada, una vez que se han anulado esas defensas, el código del sitio real en sí debe tener una codificación de entrada DB errónea en primer lugar para que los vectores de inyección se activen independientemente de las reclamaciones de los atacantes, en este caso, Anónimo.

    
respondido por el Taipo 05.02.2012 - 22:05
fuente
0

Sólo una suposición salvaje. Pueden codificar cadenas ASCII en UTF-16, de esta manera, las rutinas que se usaron para verificar la entrada de usuarios peligrosos fueron engañadas / desviadas. La cadena se interpretó y la entrada maliciosa no se filtró.

Esto suena como que los desarrolladores usaron prácticas de codificación inseguras o que algunas bibliotecas / aplicaciones estaban desactualizadas y, por lo tanto, eran peligrosas. No es como si los piratas informáticos / scripters anónimos tuvieran alguna magia de bypass, se trata de experimentar.

En su mayoría, si tienen 0 días o algunas técnicas nuevas para piratear todo, no le informarán a la gente. A menudo utilizan técnicas de la vieja escuela que siguen funcionando debido a la incompetencia de algunos programadores / administradores. La seguridad es importante.

    
respondido por el Aki 05.02.2012 - 13:20
fuente

Lea otras preguntas en las etiquetas