c99 is the original — attributed to locus7s / Locus7 group (this variant modified by #!physx^), it established the template that every subsequent PHP webshell copied.
Capabilities
File browser, command execution, database client, server info dump, self-delete. Its influence on the underground PHP tool ecosystem is difficult to overstate — nearly every shell in the corpus traces design decisions back to c99.
Zero Authentication
The most immediate finding is the complete absence of access control. The password variable ships as an empty string, which means the authentication check never fires. Any visitor who discovers the shell’s URL has immediate, unrestricted access to every function — file management, command execution, database queries, network tools. This is not a misconfiguration; it is the default state of every copy that ships unmodified.
PHP Object Injection
The shell deserializes cookie input using unserialize() with no validation or type checking. An attacker can craft a cookie value containing a serialized PHP object that triggers arbitrary code execution through the application’s class autoloading — a classic POP (Property-Oriented Programming) chain. This vulnerability is exploitable by any unauthenticated visitor, independent of whether the operator has set a password. The attack surface is the HTTP Cookie header itself.
Vulnerabilities
| # | Class | Impact | Status |
|---|---|---|---|
| 1 | No authentication — empty password string disables auth check | Unrestricted access | Live-proven |
| 2 | PHP object injection — unserialize() on cookie input | Pre-auth RCE via POP chain | Confirmed |
Detection Surface
File-system indicators
| Indicator | Type | Detail |
|---|---|---|
| SHA256 | Hash | 960feb502f913adff6b322bc9815543e5888bbf9058ba0eb46ceb1773ea67668 |
| Expected size | ~229 KB | Source variant |
$pass='' | Variable | Empty password = zero auth by default |
$disablefunc | Variable | c99-family variable for disabled function tracking |
$cfe | Variable | Command variable (c99 uses $cfe where others use $code or $cmd) |
$datapipe | Variable | Port forwarding configuration (unique to c99) |
$anypass, $anyphpcode | Variables | c99shell auth variables |
b76d95e82e853f3b0a81dd61c4ee286c | MD5 hash | c99shell default password hash (triple-hash: md5(sha1(md5()))) |
"Port alredy in use" | String (typo) | Typo alredy — on ~4/11 local c99 variants (c99, c99shell, c99_empire, c99_saldiri); NOT universal (absent from c99_antivirus, c99_locus7s, c99_madnet, c99_PSych0, c99_w4cking, c99ud) |
$data{0} == "\x99" | Code pattern | Magic byte check (unique to c99) |
Cookie: unserialize($_COOKIE["$sess_cookie"]) | Code pattern | PHP object injection via cookie |
Locus7Shell, c99shell | Strings | Self-identification in title/comments |
| Runtime | PHP 5.6 only | 500 on PHP 7.4 (ereg, mysql_connect removed) |
HTTP access-log indicators
| Log pattern | What it means |
|---|---|
$pass='' — no auth on default install | Any visitor who discovers the URL has full access |
| Cookie with serialized PHP object | unserialize() on cookie input — PHP object injection |
POST act= | Action dispatcher for all c99 functions |
POST cmd= | Command execution |
POST charset= | Character set selector |
| Bind port / datapipe endpoints | Creates local TCP listeners (bind shell, port forwarding) |
Response: c99shell in title | Shell self-identifies in HTML title |
POST test1_file= | File read via curl LFI (shared with r57) |
YARA rule
rule webshell_c99 {
meta:
description = "c99 webshell (Locus7 / physx variant)"
author = "OHIIHO Threat Research"
reference = "https://research.ohiiho.com/arsenal/c99/"
status = "validated"
strings:
$title1 = "c99shell" ascii nocase
$title2 = "Locus7Shell" ascii
$bind_port = "Port alredy in use" ascii
$datapipe = "$datapipe[\"port\"]" ascii
$fsock = "fsockopen(\"localhost\",$bind" ascii
$anypass = "$anypass" ascii
$anyphp = "$anyphpcode" ascii
$md5chain = "md5(sha1(md5($anypass)))" ascii
$disablefunc = "$disablefunc" ascii
$cfe_var = "@shell_exec($cfe)" ascii
$magic_byte = "$data{0} == \"\\x99\"" ascii
$default_hash = "b76d95e82e853f3b0a81dd61c4ee286c" ascii
condition:
filesize < 300KB
and (
($title1 or $title2)
or ($anypass and $anyphp and $md5chain)
or ($disablefunc and $cfe_var)
or ($magic_byte and $default_hash)
or ($bind_port and ($datapipe or $fsock))
)
}
MITRE ATT&CK
| Technique | Context |
|---|---|
| T1505.003 | Web Shell |
| T1059.004 | Command and Scripting Interpreter: Unix Shell |
| T1212 | Exploitation for Credential Access (object injection via cookie deserialization) |
OHIIHO Threat Research.
