Un sitio de clientes tuvo un gran ataque de inyección de mysql en él, solo quiero aprender de él

9

Creé una tienda en línea para un amigo mío.

Creé un sistema que me envía un correo electrónico cada vez que hay un error en la base de datos, de esa forma, si es un error en mi código, puedo identificarlo y solucionarlo. El correo electrónico incluye detalles sobre la consulta que falló, los datos que se pasaron, los datos de la sesión, etc.

Bueno, a las 3:05 de esta mañana recibí alrededor de 120 correos electrónicos en cinco minutos. para un error en la base de datos y mirando lo que estaba sucediendo, puedo decir rápidamente que fue un ataque de inyección de mysql. Después de ver un montón de cosas que intentó el atacante, me pregunto qué harían realmente algunas de las órdenes de SQL que intentaban pasar.

Después de revisar toda la base de datos, así como los archivos en el sitio, tengo un 99% de certeza de que nada fue dañado, eliminado o cambiado. Lo que me alegra saber que tengo suficiente conocimiento en mi php para saber cómo prevenir estas cosas.

Mi pregunta es, de los comandos mysql a continuación, ¿qué intentaba hacer el atacante?

 or 1=convert(int,(select cast(Char(114)+Char(51)+Char(100)+Char(109)+Char(48)+Char(118)+Char(51)+Char(95)+Char(104)+Char(118)+Char(106)+Char(95)+Char(105)+Char(110)+Char(106)+Char(101)+Char(99)+Char(116)+Char(105)+Char(111)+Char(110) as nvarchar(4000))))--

; if (1=1) waitfor delay \'00:00:07\'--

union all select null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null--

999999.9 union all select 0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--

leachiancs\' and \'x\'=\'x

Gracias por la información.

Más información

La consulta que se ejecutó para cada ataque fue simple

SELECT * FROM tableName WHERE $phpVar AND price!='sold' ORDER BY id DESC

El $ phpVar se rellena en función de si una entrada $ _GET coincide con un término en una matriz de parámetros aceptados.

por lo que la consulta literal que se estaba ejecutando y que devolvía un error era

SELECT * FROM tableName WHERE AND price!='sold' ORDER BY id DESC

Eso es lo que lanzó el seguimiento

 Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND price!='sold' ORDER BY id DESC' at line 1
    
pregunta Ryan 27.04.2013 - 00:16
fuente

4 respuestas

11

El simple hecho de que su base de datos ejecutó las consultas citadas (lo que le arroja los informes de error) significa que tiene una vulnerabilidad de inyección en el código PHP. Tenga en cuenta que algunos métodos para inspeccionar la estructura de las tablas de la base de datos implican ejecutar varias consultas con diferentes parámetros hasta que la base de datos emita un error y salte la página HTML. Eso significa que las consultas fallidas son solo la punta del iceberg de todas las consultas que se ejecutaron.

Hay 5 consultas:

1) Invalida todas las declaraciones WHERE restrictivas anteriores al agregar efectivamente la declaración "o 1 = 1".

2) Compruebe si hay un ataque de DOS contra la base de datos del servidor SQL agregando otra consulta de demora.

3) Inspeccionando el número de columnas en la tabla de base de datos. El número de null-s en el cambio entre consultas pasadas y fallidas es lo que busca el atacante.

4) Lo mismo para las tablas de autenticación de usuario: finaliza la consulta con el ID probablemente inexistente y luego inspecciona el número de columnas. null-s se reemplazan por valores HEX.

5) desvío la verificación de autenticación al inyectar un usuario $ creado en una cadena de PHP de consulta como

"SELECCIONAR ... DONDE ... Y nombre = '" + $ usuario + "'"

(observe la secuencia exacta de comillas simples y dobles) Es probable que el usuario 'leachiancs' haya sido realmente adquirido por investigaciones anteriores.

Las consultas (1) - (4) llevan un comentario de SQL al final para invalidar el resto de la consulta original y derrotar a LIMIT u otra validación de las construcciones DONDE.

La lección principal aquí es utilizar solo consultas parametrizadas y no intentar reproducir todo el trabajo sucio de DB + PHP correcto escapando para todas las versiones posibles y peculiaridades en sintaxis.

    
respondido por el Van Jone 27.04.2013 - 02:41
fuente
10

Me divertí "decodificando" dos consultas, así es como lo hice en PHP: p

1) or 1=convert(int,(select cast(Char(114)+Char(51)+Char(100)+Char(109)+Char(48)+Char(118)+Char(51)+Char(95)+Char(104)+Char(118)+Char(106)+Char(95)+Char(105)+Char(110)+Char(106)+Char(101)+Char(99)+Char(116)+Char(105)+Char(111)+Char(110) as nvarchar(4000))))--

Comencemos por copiar este fragmento de código en una variable:

$str = 'Char(114)+Char(51)+Char(100)+Char(109)+Char(48)+Char(118)+Char(51)+Char(95)+Char(104)+Char(118)+Char(106)+Char(95)+Char(105)+Char(110)+Char(106)+Char(101)+Char(99)+Char(116)+Char(105)+Char(111)+Char(110)';
preg_match_all('/\d+/', $str, $m); // Some regex Fu to get the numbers
$sql = implode('', array_map(function($v){return chr($v);}, $m[0])); // converting the numbers to letters
echo $sql; // output

Esto me dio r3dm0v3_hvj_injection y después de comprobar el mysql convert y la sintaxis del elenco parece que está mal, pero no estoy seguro, pero básicamente este es un método de ofuscación y la intención era terminar con or 1=1 .

2) ; if (1=1) waitfor delay \'00:00:07\'--

Bien ; declara el final de la declaración y el resto parece un ataque basado en el tiempo . Aunque esto parece inútil ya que el api mysql en php no puede realizar 2 consultas al mismo tiempo. -- comentando el resto de la consulta.

3) union all select null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null--

Me parece inútil, pero puede determinar cuántas columnas tienes, ya que esto generará un error si el número de null no coincide con el número de columnas que tienes.

4) 999999.9 union all select 0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--

Bueno, copiemos esas variables hexadecimales en una variable y hagamos un poco de php-fu en ella:

$str = '0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536';

$result = implode(',', array_map('hex2str', explode(',', str_replace('0x', '', $str)))); // PHP-Fu
echo $result;// output

// function hex to ascii
function hex2str($v){
    $r = '';$l = strlen($v)-1;
    for($i=0;$i <= $l;$i+=2){
        $r .= chr(hexdec($v[$i].$v[$i+1]));
    }
    return $r;
}

Esto me dio: 1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056,1025480056

Pienso que esto es extraño, ya que es lo mismo, vamos a reconvertirlo de hexadecimal a cadena:

echo hex2str('1025480056');

La salida es %HV , con un editor hexadecimal normal hay otros 2 caracteres oscuros .

Bueno, creo que el propósito puede ser el mismo que en el ataque # 3 , solo que está confuso.

5) leachiancs\' and \'x\'=\'x

Consulta simple where a=b and x=x .

Conclusión:

Le wild r3dm0v3_hvj_injection y % HV aparecen, con 120 correos electrónicos dentro de 5 millones. Sospecho que esto es una evidencia de que este ataque se realizó con un herramienta de SQLi automatizada Havij .

Prevención:

Utilice DOP o MySQLi con declaraciones preparadas .

    
respondido por el HamZa 12.05.2013 - 16:31
fuente
6
  

Lo que me alegra saber que tengo suficiente conocimiento en mi php para saber cómo prevenir estas cosas.

Esta es una forma de pensar extraordinariamente peligrosa para evitar este incidente.

El hecho de que el atacante no parezca haber borrado los datos no significa que no hayan leído los datos que no deberían. Y el hecho de que hayan podido ingresar entradas que causaron errores en la base de datos es una prueba contundente de que no realmente sabe cómo prevenir estas cosas, como declaraciones preparadas y consultas parametrizadas habrían evitado incluso eso.

En cuanto a las consultas proporcionadas, en su mayoría parecen ser intentos de encontrar una vulnerabilidad de inyección SQL en primer lugar.

    
respondido por el Stephen Touset 27.04.2013 - 02:00
fuente
3

Parece que el atacante estaba intentando investigar qué tipo de ataques eran posibles con la vulnerabilidad que había encontrado.

Independientemente; La lección es siempre la misma: utilizar consultas parametrizadas. Si tiene que recordar citar y escapar de sus datos, entonces lo está haciendo mal.

Si desea obtener más información sobre el funcionamiento de los ataques de inyección de SQL típicos, consulte las herramientas automatizadas, como el conjunto de burp, que se utilizan normalmente para este tipo de ataque.

    
respondido por el tylerl 28.04.2013 - 01:49
fuente

Lea otras preguntas en las etiquetas