inyección de MySQL SQL sin consultas apiladas: ¿qué es realmente posible sin afectar el FS?

5

Estoy explorando una vulnerabilidad en un sitio web de PHP que básicamente está plagado de inyecciones de SQL. Con SQLMap, logré volcar todas las tablas y obtener información básica (nombre de usuario, nombre de base de datos, nombre de host, aunque parece bastante inútil porque el servidor de base de datos no está disponible externamente). Mi objetivo es modificar los datos en una tabla específica, no mencionada en ninguna consulta SQL inyectable. Probé el interruptor --db-shell de SQLmap, pero descubrí que no puedo hacer nada más allá de SELECT porque la combinación PHP + MySQL no permite realizar consultas apiladas.

Por lo tanto mi pregunta. Dado uno de los siguientes fragmentos de código:

mysql_query("SELECT * FROM sometable WHERE id=".$_GET['id']);
mysql_query("INSERT INTO sometable (id) VALUES (".$_GET['id'].")");
mysql_query("UPDATE sometable SET id= ".$_GET['id']);
mysql_query("DELETE FROM sometable WHERE id=".$_GET['id']);

¿Puedo modificar (eliminar, insertar, actualizar) datos desde fuera de Sometable, sin trucos de LOADFILE / INTO OUTFILE (y similares)? ¿La sintaxis de MySQL me dejaría hacerlo en este caso? Si la respuesta es "depende", ¿cómo sería la sintaxis de la consulta para dejarme pasar? No soy un DBA en este host. Tampoco hay procedimientos almacenados en el sitio web, solo algunas cosas muy básicas para aficionados que podrías aprender de un solo libro que ni siquiera menciona la seguridad.

    
pregunta d33tah 17.09.2013 - 16:18
fuente

3 respuestas

1

Primero que nada: no estoy seguro de haber entendido tu consulta, pero supongo que quisiste decir: ¿Cómo puedo afectar los datos externos (en la tabla de la que se tratan estas consultas)?

El ataque más obvio hubiera sido insertar múltiples consultas, es decir, "; delete from other_table" pero en este caso parece que no puedes hacer eso.     mysql_query () envía una consulta única (no se admiten varias consultas)

Lo que significa que estás atascado con los efectos secundarios, haciendo cosas dentro de la consulta original. Parece que al menos puedes ser disruptivo con los bloqueos: enlace en particular, debería poder hacer que la selección sea un 'seleccione ... para actualizar';

Todavía no puedo ver otra forma de afectar las consultas específicas que tienes.

    
respondido por el pacifist 13.12.2013 - 05:51
fuente
0

He estado jugando un poco con esto por un tiempo y no he encontrado ninguna manera de hacer lo que estás hablando. Es posible que alguien que sea más inteligente que yo pueda encontrar una manera de hacerlo, pero por lo que puedo decir, no se puede hacer.

    
respondido por el Abe Miessler 17.09.2013 - 19:54
fuente
-3

Es mucho mejor usar objetos de datos PHP para sus consultas de capa de acceso a datos. Esto eliminará la inyección de SQL por completo; sin mencionar que también puede querer ser amigable con el grupo de sitios web conocido como OWASP.

Ejemplo:

  

// Declarar & establecer variable

     

lista ($ db_dbdriver, $ db_hostname, $ db_database, $ db_username,   $ db_password) = Connection :: dbConnect ();
             // Establecer zona horaria predeterminada

     

date_default_timezone_set ('America / Los_Angeles');              $ my_success = false; $ my_message="";

     

prueba {

     

// Crear & establecer conexión

     

$ db_options = array (PDO :: MYSQL_ATTR_INIT_COMMAND = > "SET NAMES   'UTF8' ");

     

$ conn = new PDO ($ db_dbdriver. ": host=". $ db_hostname. "; dbname=".   $ db_database, $ db_username, $ db_password, $ db_options);

     

$ conn- > setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);

     

// Preparar una declaración SQL

     

$ my_sql = 'INSERT INTO Message (Message_State, Message_Body,   Message_CBy, Message_EBy) VALUES (: Message_State,: Message_Body,   : Message_CBy,: Message_EBy) ';

     

$ stmt = $ conn- > prepare ($ my_sql);                  // Vincular parámetros para evitar la inyección SQL.

     

$ stmt- > bindValue (': Message_State', $ message_state);

     

$ stmt- > bindValue (': Message_Body', $ message_body);

     

$ stmt- > bindValue (': Message_CBy', $ message_cby);

     

$ stmt- > bindValue (': Message_EBy', $ message_eby);

     

// Ejecutar la sentencia SQL

     

$ stmt- > execute ();

     

// Cierra el cursor, permitiendo que la sentencia se ejecute de nuevo

     

$ stmt- > closeCursor ();

     

// Cerrar & Desactivar la conexión

     

$ conn = null; unset ($ conn);

     

// Establezca el valor de éxito en TRUE

     

$ my_success = true; $ my_message="éxito";

     

} captura (PDOException $ e) {

     

// Mensaje de error de captura

     

$ error_message = $ e- > getMessage ();

     

// Añadir mensaje de error al registro de errores

     

file_put_contents ('../../ log / error / php_errors.log', "\ r \ n".   fecha ("Y-m-d h: i: s A"). ": data_access_layer - > my_class.php   (class_name) - > Function_Name: ". $ E- > getMessage (), FILE_APPEND);

     

// Establezca el valor de éxito en FALSO & devolver un mensaje de error

     

$ my_success = false; $ my_message = $ error_message;

     

}

     

matriz de retorno ($ my_success, $ my_message);

    
respondido por el John Edward Law 17.09.2013 - 20:55
fuente

Lea otras preguntas en las etiquetas