A injeção de comandos remotos (RCE) ocorre quando uma aplicação web transmite dados fornecidos pelo usuário para o shell do sistema operacional sem a devida sanitização. Isso permite que um invasor execute comandos arbitrários com os privilégios do servidor web, comprometendo totalmente a infraestrutura.
Falhas em Defesas Baseadas em Blacklist
Uma abordagem comum, porém frequentemente ineficaz, é o uso de "blacklists" (listas de bloqueio) para remover caracteres especiais que permitem o encadeamento de comandos, como &, ;, | e $. O problema fundamental dessa técnica é que ela é reativa: se o desenvolvedor esquecer um único caractere ou cometer um erro de sintaxe na filtragem, a segurança é comprometida.
Considere o exemplo abaixo, onde uma tentativa de filtrar caracteres falha devido a um erro humano comum:
<?php
if (isset($_POST['execute_ping'])) {
// Captura o input e remove espaços nas extremidades
$address = trim($_REQUEST['ip_address']);
// Definição de uma blacklist para substituição
// Note o erro: o caractere pipe "|" possui um espaço após ele, permitindo o bypass
$forbidden_chars = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Substitui os caracteres da lista por strings vazias
$sanitized_input = str_replace(array_keys($forbidden_chars), $forbidden_chars, $address);
// Execução dependente do Sistema Operacional
if (stristr(php_uname('s'), 'Windows NT')) {
$result = shell_exec('ping ' . $sanitized_input);
} else {
$result = shell_exec('ping -c 4 ' . $sanitized_input);
}
echo "{$result}";
}
?>
No código acima, a falha reside na chave '| ' => ''. Como há um espaço após o símbolo do pipe, um atacente pode simplesmente injetar um comando usando |whoami (sem espaço) para burlar o filtro e executar o comando malicioso.
Implementação de Segurança Robusta via Whitelisting
A maneira mais segura de lidar com entradas de usuários que interagem com o sistema operacional é a utilização de "whitelists" (listas de permissão) e a validação estrita do formato dos dados. Em vez de tentar adivinhar o que é perigoso, o desenvolvedor define exatamente o que é aceitável.
No caso de uma ferramenta de diagnóstico que aceita endereços IP, a entrada deve ser validada para garantir que ela contenha apenas quatro octetos numéricos separados por pontos.
<?php
if (isset($_POST['Submit'])) {
// Verificação de Token Anti-CSRF (boa prática adicional)
checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php');
$raw_ip = $_REQUEST['ip'];
$raw_ip = stripslashes($raw_ip);
// Divide a string em partes usando o ponto como delimitador
$segments = explode(".", $raw_ip);
// Validação estrita: verifica se são exatamente 4 partes e se todas são numéricas
if ((count($segments) == 4) &&
is_numeric($segments[0]) &&
is_numeric($segments[1]) &&
is_numeric($segments[2]) &&
is_numeric($segments[3])) {
// Reconstrói o IP de forma segura a partir dos segmentos validados
$valid_ip = $segments[0] . '.' . $segments[1] . '.' . $segments[2] . '.' . $segments[3];
if (stristr(php_uname('s'), 'Windows NT')) {
$output = shell_exec('ping ' . $valid_ip);
} else {
$output = shell_exec('ping -c 4 ' . $valid_ip);
}
echo "{$output}";
} else {
echo "<p>Erro: O endereço IP fornecido é inválido.</p>";
}
}
?>
Comparação de Estratégias de Defesa
- Blacklisting: Frequentemente incompleta. Atacantes utiliazm diferentes codificações ou operadores que o desenvolvedor pode não ter previsto.
- Whitelisting: A abordagem mais recomendada. Ao restringir o input a um formato conhecido (como
filter_var($ip, FILTER_VALIDATE_IP)em PHP), ipmossibilita-se a inclusão de metacaracteres do shell. - Sanitização/Escapamento: Uso de funções nativas como
escapeshellarg()ouescapeshellcmd()para garantir que o input seja tratado como um argumento literal e não como parte do comando executável.