symlink.php is a privilege escalation utility designed for shared hosting environments running cPanel. It exploits the symlink() function in PHP to create symbolic links that traverse account boundaries, allowing the operator to read files belonging to other users on the same physical server.
Capabilities
Symlink creation across cPanel account boundaries. Cross-account file read via symbolic link traversal — targets home directories, configuration files, database credentials of co-hosted accounts. Cookie-based authentication for database operation features. Designed for shared hosting where PHP’s open_basedir and symlink restrictions are not properly hardened.
W0rm Supply-Chain Injection
The version circulating in underground channels carries the standard W0rm supply-chain injection. A GET parameter handler at global scope (early in the file, before any authentication logic) provides pre-auth remote code execution on every request. The tool’s own cookie-based authentication is irrelevant — the W0rm payload fires unconditionally before those checks are ever reached.
The same W0rm infrastructure is present: the xsec/blocker file upload backdoor for persistent secondary access, and the Pastebin C2 beacon exfiltrating the server URL and installation path. The pattern is identical to the injections in dbkiss, unzipper, and the major webshells — same operator, same toolchain, same pre-auth execution model.
symlink.php occupies a specific niche: it is deployed alongside a webshell and used to escalate from a single compromised hosting account to reading the entire server’s configuration files (database credentials, API keys, mail configs). On the majority of shared hosting configurations that have not explicitly blocked cross-account symlinks, it is effective. The W0rm injection means the tool’s own operator is also compromised — using symlink.php backdoors the attacker’s own infrastructure as much as the target’s.
Vulnerabilities
| # | Class | Impact | Status |
|---|---|---|---|
| 1 | Symlink traversal across account boundaries on shared hosting | Cross-account credential theft | Confirmed |
| 2 | W0rm supply-chain injection — pre-auth RCE via GET parameter at global scope | Unauthenticated command execution on every request | Live-proven |
Detection Surface
File-system indicators
| Indicator | Type | Detail |
|---|---|---|
symlink( traversal calls | Code pattern | Cross-account boundary on shared hosting |
Cookie-based auth ($_COOKIE) | Auth | Auth mechanism — but W0rm fires pre-auth |
wp-config.php, configuration.php | Target paths | CMS config targets |
.htaccess creation | File drop | Access override for output directory |
| Expected size ~40 KB | Size |
HTTP access-log indicators
| Log pattern | What it means |
|---|---|
Cookie-based auth ($_COOKIE) | Cookie auth — but W0rm fires pre-auth |
symlink( traversal | Cross-account boundary on shared hosting |
Targets wp-config.php, configuration.php | Well-known CMS config paths |
?cmd= GET parameter | Unauthenticated command execution — W0rm RCE vector |
?xsec=blocker GET parameter | File upload endpoint — drops arbitrary files to webroot |
?xsec= GET parameter | W0rm dispatch parameter (multiple sub-commands) |
YARA rule
rule tool_symlink_privesc {
meta:
description = "symlink.php cPanel privilege escalation with W0rm injection"
author = "OHIIHO Threat Research"
reference = "https://research.ohiiho.com/arsenal/symlink/"
status = "validated"
strings:
$symlink = "symlink(" ascii
$passwd = "/etc/passwd" ascii
$cookie_auth = "$_COOKIE" ascii
$conf1 = "wp-config.php" ascii
$conf2 = "configuration.php" ascii
$htaccess = ".htaccess" ascii
$w0rm_cmd = "$_GET[\"cmd\"]" ascii
condition:
filesize < 60KB
and $symlink
and ($cookie_auth or $passwd)
and ($conf1 or $conf2)
and ($w0rm_cmd or $htaccess)
}
W0rm-infected variants are also caught by the generic W0rm supply-chain rule — see the W0rm supply-chain detection applicable to all infected tools.
Detection quick wins
- Any symlink.php instance with a GET parameter handler at global scope (before the tool’s own cookie authentication) is the W0rm-infected variant — look for
$_GET["cmd"]early in the file - Monitor for mass
symlink()calls targeting well-known CMS config paths across account boundaries — this is the core privilege escalation pattern on shared hosting - The presence of
xsec/blockerfile-write functions confirms the W0rm supply-chain injection — the tool is both a threat to shared hosting targets and a supply-chain risk to the operators deploying it
MITRE ATT&CK
| Technique | Context |
|---|---|
| T1083 | File and Directory Discovery (symlink traversal) |
| T1552.001 | Unsecured Credentials: Credentials In Files (cross-account config theft) |
| T1195.002 | Supply Chain Compromise: Compromise Software Supply Chain |
| T1059.004 | Command and Scripting Interpreter: Unix Shell |
OHIIHO Threat Research.
