Your Browser Is Now Your Enemy: Delivering PHP RCE to Your Local Servers

Executive Summary
This article demonstrates how attackers can chain Orange Tsai's CVE-2024-4577 with DNS rebinding to achieve remote code execution on internal network infrastructure directly through the victim’s web browser. By bypassing Same-Origin Policy (SOP)
and exploiting vulnerable PHP-CGI
instances running on local XAMPP servers
, internal development environments, or corporate networks, this attack enables full code execution on systems never intended to be exposed to the internet.
Background: CVE-2024-4577 - The Return of a Dead Vulnerability
Back in 2012, a critical vulnerability known as CVE-2012-1823
was discovered in PHP's CGI
mode. This bug allowed attackers to inject command line arguments by appending dash-prefixed
parameters to URLs. PHP patched the issue by blocking arguments starting with a dash -
. For over a decade, the vulnerability was considered dead until Orange Tsai
discovered a way to bring it back to life. He managed to bypass the patch by exploiting how Windows converts text between Unicode and legacy ANSI code pages, For more on how it works, I recommend reading this fascinating blog by Orange Tsai Unveiling Hidden Transformers in Windows ANSI.
The core issue lies in how Windows handles characters that cannot be represented directly in a given ANSI code page. Windows uses a feature called Best-Fit Mapping
, which replaces problematic characters with "close enough" alternatives during conversion from Unicode to legacy code pages.
Affected Code Pages:
- Traditional Chinese (Code Page 950)
- Simplified Chinese (Code Page 936)
- Japanese (Code Page 932)
The vulnerability specifically affects Windows systems configured with these East Asian locales due to their Best-Fit mapping
behavior and when PHP is running in CGI mode
. One of the key culprits is the soft hyphen
character U+00AD
, which gets silently converted to a regular hyphen (-)
in the affected code pages. This conversion happens at the Windows API level when PHP-CGI
processes command line arguments.
- Normal blocked request:
http://example.com/script.php?-s
- Bypass using soft hyphen:
http://example.com/script.php?%ADs
When Windows processes the %AD
(soft hyphen)
, it transforms it into -s
, effectively sneaking past PHP's argument filter and re-enabling the original injection vector.
DNS Rebinding: Breaking the Same-Origin Policy
DNS rebinding is a browser-based attack that subverts the Same-Origin Policy
by manipulating DNS resolutions. Normally, browsers enforce that scripts from one origin cannot interact with resources from another. DNS rebinding tricks the browser into believing that malicious scripts hosted on an attacker's domain are actually being served from localhost or internal network addresses.
To test DNS rebinding in a real-world scenario, you can use the excellent tool hosted at https://lock.cmpxchg8b.com/rebinder
. This site, created by Tavis Ormandy
, demonstrates how an attacker can serve malicious JavaScript from a public domain and then rebind it to a specified IP address effectively bypassing the browser’s Same-Origin Policy
. for example, as shown in the image below, the attacker initially resolves the domain to 42.42.42.42 (A)
, then after the DNS TTL
expires, it’s rebound to 127.0.0.1 (B)
. The tool generates a domain like 2a2a2a2a.7f000001.rbndr.us
, which encodes the rebinding behavior A
and B
IPs in hex.

DNS will switch between the two IPs, When performing DNS rebinding, I prefer using DuckDNS
since it gives us more control over the DNS. So, we'll stick with it,

Let’s say the victim visits the domain duckcore.duckdns.org
, which we registered using duckdns.org
. Since DuckDNS allows dynamic updates to the DNS A record via API, we first point the domain to our external attack server, you can use nslookup
or dig
to see the rebinding in action:

Once the victim visits our page, we update the dns record and wait for the TTL
to expire in our case TTL
is set to 2 seconds. At this point, the victim’s browser still believes it’s communicating with duckcore.duckdns.org
, but the IP now points to 127.0.0.1
. This triggers a DNS rebinding condition, effectively bypassing the browser's Same-Origin Policy (SOP)
. As a result, our script can now make requests to internal services running on localhost.

Internal Network Scanning
Since we are now effectively inside the victim’s network, you might wonder how we can scan internal IP addresses. This can be done by iterating through common internal IP ranges (such as 192.168.0.1
to 192.168.0.255
, 10.0.0.1
to 10.0.0.255
, etc.) and sending HTTP requests to each address. To avoid Cross-Origin Resource Sharing (CORS)
restrictions which normally block these requests when targeting different origins we use the mode: no-cor
option this prevents the browser from blocking the request, though it also means the response body will be inaccessible or null. While we can bypass these limitations and read responses from internal services, we’ll save that for another topic.

if you want to implement internal network scanning, you can use the JavaScript snippet above. In my PoC, I’ll be using a predefined list of common IPs to keep it simple and fast.
The attack flow
- The victim visits a malicious website like
evil.com
. - The DNS for
evil.com
is set up to initially resolve to an external IP, allowing the site to load in the browser. - After loading, the DNS server rebounds the domain to resolve to
127.0.0.1
or a local network IP, and wait forTTL
to expire. - Now the browser’s same-origin policy sees the requests as same-origin (still evil.com) and allows cross-origin access to local services (e.g. XAMPP, routers, admin panels).
- performs a quick scan of common internal IP ranges (e.g.,
192.168.0.0/24
,10.0.0.0/24
) with mode:no-cors
to identify which IPs are alive. - Sends crafted requests to local XAMPP servers vulnerable to
CVE-2024-4577
- Remote Code Execution achieved on internal xampp servers
Putting It All Together: Complete Attack Chain Implementation
- This PoC sets up a
DuckDNS
domain(e.g., example.duckdns.org)
fully controlled by the attacker. Initially, the domain points to the attacker’s public server, which hosts a web page containing JavaScript PoC that automates the entire attack chain. Once loaded in the victim's browser, the PoC uses theDuckDNS API
to dynamically update the domain’s IP address, rebinding it to an internal IP such as127.0.0.1
or192.168.x.x
. This bypasses the browser’sSame-Origin Policy
, allowing the script to interact with internal services. The PoC then sends a craftedCVE-2024-4577
exploit request if successful this results in remote code execution on vulnerable local XAMPP servers.

Mitigation
- For PHP, it's recommended to upgrade to the latest versions, as the vulnerability has been fixed,
Orange Tsai
also recommends moving away fromPHP-CGI
and using other alternatives . - For DNS rebinding, it's recommended to
verify Host headers
and enforceTLS
Conclusion
The combination of CVE-2024-4577
and DNS rebinding
creates a powerful attack vector capable of compromising internal network infrastructure through web browser. This attack chain is particularly dangerous because it bypasses network perimeters by originating attacks from legitimate user browsers, targets internal infrastructure by exploiting services not accessible from the internet, has a high success rate, and is difficult to detect since the malicious traffic appears legitimate until exploitation occurs.
DEMO VIDEO
POC
Resources
- https://blog.orange.tw/posts/2024-06-cve-2024-4577-yet-another-php-rce/
- https://blog.orange.tw/posts/2025-01-worstfit-unveiling-hidden-transformers-in-windows-ansi/
- https://www.youtube.com/watch?v=Q0JG_eKLcws&t=2137s
- https://medium.com/@brannondorsey/attacking-private-networks-from-the-internet-with-dns-rebinding-ea7098a2d325
- https://github.com/watchtowrlabs/CVE-2024-4577