php代码审计-1 & emlog pro SQL注入&bluecms SQL注入

代码审计

首先代码审计的流程

函数的类型一般有

Bluecms sql注入分析


首先搭建这个环境,这里是BlueCMS BlueCMS 1.6
php5 + apache+ mysql
然后访问
http://192.168.124.32:8888/install/
之后进行安装


之后下一步即可,然后访问首页没有报错说明安装成功

之后将这个源码载入到phpstorm
使用正则全局进行搜索sql注入的函数

(update|select|insert|delete|).*?where.*=

通过cnvd的描述可以知道出现漏洞的点在user_id这个参数

然后在审计的时候首先得看几个关键的地方

1 看文件的路径,查看关键函数的文件,如果是在后台,那么就得需要登录后台才能触发,比较鸡肋
2 看代码里面的变量是否是可控的,还是写死的
3 查看变量的前后是否有过滤

查看搜索的结果

然后排除admin路径后面的搜索结果然后寻找可控的变量

然后一个一个进行查看,首先看第一个位置并不是admin里面的文件然后点开进行查看是否有变量

可以看到这里有这个ad_id的变量,然后查看这个变量的赋值

这里就一个判断是否为空,还有trim去空格的函数,相当于没有过滤,之后查看getone这个函数是否有对这个变量进行过滤
ctrl之后点击即可,有的时候会出现很多的地址,可以查看这个文件包含了那些文件然后进行筛选,如果没有那就得一个一个看

点开第一个

这里可以看到就是执行sql语句然后返回执行的结果,也没有对变量进行过滤,第二个地方同样也是一样的

然后我们就知道了这个地方对输入的变量完全没有过滤就可以尝试进行注入
这个文件是ad_js.php在网站的根目录,之后访问就可以,然后查看参数的传入方式,就是通过ad_id进行参入的,然后就可以进行访问传参进行验证

http://192.168.124.32:8888/ad_js.php?ad_id=1

访问空白,可以进行打印sql语句查看是否执行了我们找到的位置,因为刚刚我们发现了getone函数有两个地方声明了,然后可以一个一个进行输入看看,如果能打印出我们的sql语句那么说明这个地方就是应用的这个文件首先在第一个文件里面写入

然后重新访问这个文件,发现并没有输出,然后修改第二个文件

然后重新访问

出现了sql语句,说明是引用的第二个文件。然后就是判断这个语句执行后是否有输出,如果有输出的话那么就可以回显到页面就可以直接常规的注入测试,如果没有输出语句,那么就说明无法回显,就可以使用盲注进行测试

可以看到最下面有echo的输出,而且输出的内容就是从查询结果中截取的,那么说明可以回显,然后连接数据库查看数据列数,进行select判断回显位
刚刚的页面回显是查询的blue_ad表,然后看数据库的列数

然后使用select进行回显测试

因为源码里面是echo 的 这个就是html的注释,查看页面源码是否有这个输出

发现回显位是7,然后就开始注入


sqlmap也可以进行测试

emlog v6.0.0 后台 SQL注入

首先下载emlog 6.0.0使用phpstudy搭建环境


从cnvd介绍可以看出这个注入点是在后台,那么就载入源码然后在admin文件夹里面进行寻找co开通的文件

可以看到这里面就有两个co开头的文件

两个文件都进入查看,首先查看这个config这个文件,看名字就知道是配置文件,所有估计不是这个文件,点开发现确实是配置文件

然后查看comm这个文件,因为想要产生sql注入,那么肯定必须有能传参数的位置,所以有优先查看传参的地方,这是第一个地方

这段代码的意思就是通过get方式以gid进行接受数据,然后判断参数是否设置了,如果设置了就将参数数据进行转整,如果不存在就设置为null,第二个使用hide接受参数,如果不存在就设置为空,存在就使用addslashes对传入的数据进行转义

第三个也是一样的判断,为空就设置为1,这里对数据进行了过滤,然后看下面是否还有参数,可以看到下面还有id和ip这两个参数

查看id的参数,发现有intval的转整过滤然后查看下面的ip,很显而易见,完全没有过滤,就判断了是否设置了ip参数,然后下面的都是有过滤的参数,那么大概率就是这里,然后点击查看这个delCommentByIp($ip)函数是干的,ctrl点击进入

    function delCommentByIp($ip) {
        $blogids = array();
        $sql = "SELECT DISTINCT gid FROM ".DB_PREFIX."comment WHERE ip='$ip'";
        $query = $this->db->query($sql);
        while ($row = $this->db->fetch_array($query)) {
            $blogids[] = $row['gid'];
        }
        $this->db->query("DELETE FROM ".DB_PREFIX."comment WHERE ip='$ip'");
        $this->updateCommentNum($blogids);
    }

这段代码的意思就是\$blogids创建一个空的数组,然后使用传入的$ip拼接成一个sql语句,用于从数据库中选择具有特定 IP 地址的评论的不重复的 gid,然后执行这个sql语句把结果存储到query里面,使用while循环去取查询的数据,将每一行的gid添加到创建的空数组里面,接下面就执行delete的sql语句,删除指定的评论。最后使用updatecommentnum函数更新删除之后的评论数目
updatecommentnum函数

那么就可以知道这里就确实没有对这个ip参数进行任何过滤,所以下一步就是验证注入点

http://192.168.9.13:8898/admin/comment.php?ip=123


发现跳转到了登录页面,尝试输出我们的sql语句

然后重新访问,还是没有变化,查看代码的执行流程

可以看到上面还有一个if判断,而且还有判断权限的函数,第一步action必须为delbyip,然后下一步就是checktoken函数,跟进这个函数

可以看到,这个使用token接受token的值,判断token是否和系统设置的token是否相等,系统生成的是通过gentoken函数得到的,所以我们需要传入token,而且在cnvd上面也说了是后台sql注入,那么说明得登录后台进行操作

查看token的位置和生成源代码,使用EM_TOKENCOOKIE_开头,然后加上后面的使用auth_key和uid进行md5的处理然后赋值给token_cookie_name,之后使用setcookie设置cookie,token的值就在cookie里面,最后返回的也是token的值,然后就登录后台查找em开头的token

这里就可以直接看到token

88310461e68564f33f81f54cd106bc38

然后查看这个文件是否有对sql语句查询的输出,如果有就可以直接使用回显注入,没有就只能使用盲注和报错注入,搜索可以发现并没有这种echo等函数进行输出,那么就只能使用报错注入

/admin/comment.php?action=delbyip&ip=123' and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)-- +&token=88310461e68564f33f81f54cd106bc38


注入成功

emlog pro 2.1.9 sql注入

首先使用phpstudy搭建好网站

然后将源码载入phpstorm

cnvd上面说这个注入点是在admin/user.php文件里面,所以我们直接查看user.php文件即可

第一步就是查看是否有select update等标志性sql关键词,发现并没有,那么就可能是在函数里面进行引用的sql语句,然后寻找文件里面的参数

这里可以看到有email nickname keyword的参数,这段代码的意思就是

// 这个就是判断action是否为空,如果为空就执行下面的代码
if (empty($action)) {
    // 获取page的值,如果这个值不存在就设置为1
    $page = Input::getIntVar('page', 1);
    // 获取keyword的值
    $keyword = Input::getStrVar('keyword');
    // 初始化email 和 nickname的值为空
    $email = $nickname = '';
    // 这里就是使用filter_var过滤email,如果输入的参数符合邮箱的规则,那么将keyword的值赋值给email,反之赋值给nickname
    if (filter_var($keyword, FILTER_VALIDATE_EMAIL)) {
        $email = $keyword;
    } else {
        $nickname = $keyword;
    }
   // 使用getusers和getusernum函数获取用户信息和用户数量
    $users = $User_Model->getUsers($email, $nickname, $page);
    $usernum = $User_Model->getUserNum($email, $nickname);

既然要获取用户数量肯定就是从数据库里面进行获取,那么跟进这两个函数
getusers

这个函数发现了第一个sql语句可能有注入,先放着
getusernum

这个是第二个sql语句执行。先放着
然后接下来的参数都是有过滤的

这里有个uid但是强制转换为int了,所以也用不了,那么就只有上面发现的两处可以利用,然后不知道到底是哪一处进行注入的,使用sql语句监控查看执行了那个语句
这里使用mysql_monitor_client工具进行监控,直接将这些文件放到网站根目录就可以了,或者自己创建一个文件夹进行放入也可以

然后访问html页面

http://192.168.9.13:8898/mysql/mysql_monitor_client.html


然后我们去访问user.php之后查看这个监控执行的数据库语句,同时在日常的挖掘中也可以通过这个监控的语句去源码里面搜索然后判断是否有注入
这个就是产生的sql语句执行历史,可以看到我们刚刚查看的getusers和getusernum都执行了,但是我们需要的是可控点

这个sql语句里面全部写死了,根本无法利用

SELECT COUNT(*) AS total FROM emlog_user where 1=1

然后只能用上面的语句,里面的admin好像就是我们的登录名,这个可以控制,然后就可以定位到getusers函数
因为我们要产生sql注入就得拼接sql语句
然后查看源码看看这个参数是否能控制

这个是源码里面的语句
query("SELECT * FROM " . DB_PREFIX . "user where 1=1 $condition order by uid desc $limit");
对比监控的执行语句
	SELECT * FROM emlog_user where 1=1 order by uid desc LIMIT 0, 15
说明这个conditione被设置为空了,那么说明这个也无法利用,admin现在也不清楚从哪里来的
// 这个是原本的sql语句
SELECT * FROM emlog_user WHERE username = 'admin' AND state = 0
admin好像是可以控制的那么我们可以构造
SELECT * FROM emlog_user WHERE username = 'xxx union select xxx-- +'的

那么我们是不是可以创建一个名为 ' union selcet xxx-- +然后带入执行或者是' and updatexml xxx -- +(#)用户
通过创建用户进行查看
创建用户发现这里并没有输入的用户名选项

并且在创建之后会给出一个随机的用户名

这里源码可以知道,使用了随机函数进行创建的,所以这个唯一控制点也无法利用

所以这个方法也不行,只能通过其他的方法进行尝试,通过迪哥的思路发现这个注入点是二次注入,是在后台数据的导入进行注入的

因为我们要增加用户,那么我们必须找到可以增加数据的功能点,这里的导入刚好符合,首先下载一个数据模板下面点击开始备份然后下一个模板

可以看到最后面就是我们刚刚创建的用户数据,然后修改我们创建的那个随机用户名为sql语句,比如database()或者其他的进行测试

// 这里修改一定要注意这个select语句需要用括号进行括起来,然后不能用引号包裹
INSERT INTO emlog_user VALUES('4','','$P$BliycjHmVIvg/pGcjFCDghK/b364zq.',(select database()),'writer','n','','xxx@qq.com','','','0','1703666037','1703666037');

然后导入查看刚刚的用户界面看看是否会执行我们的语句

执行成功,所以这是一个二次注入

posted @ 2023-12-27 16:54  Running_J  阅读(52)  评论(0编辑  收藏  举报