代码审计学习之某shop任意文件删除

栏目: 数据库 · 发布时间: 5年前

内容简介:之前看了phpoop师傅的PbootCMS漏洞合集之审计全过程文章,一直没有真正的审过一套cms,代码审计只是停留在ctf题的层面上。所以接下来准备认真审计一些cms。菜鸡文章,希望大佬们不要喷。URL 的访问方式是Action 有两种,一种是脚本处理类的 Action,此类 Action 是 Controller 的一个 function另一种是视图类的 Action(也就是视图),当 Controller 中不存在此 function 时,系统自 动会加载此 action 对应的视图文件,如果此视图也不

Contents

  • 1 查看网站目录结构确定基本内容
  • 3 了解系统参数与底层过滤情况
    • 3.1 原生 GET,POST,REQUEST
    • 3.2 系统外部变量获取函数
  • 4 查看系统DB类,了解数据库底层运行方式
  • 7 后台两处任意文件删除+任意文件读取

之前看了phpoop师傅的PbootCMS漏洞合集之审计全过程文章,一直没有真正的审过一套cms,代码审计只是停留在ctf题的层面上。所以接下来准备认真审计一些cms。菜鸡文章,希望大佬们不要喷。

查看网站目录结构确定基本内容

某shop-V3.1.1
├─ cache          缓存目录(自动创建)
├─ data           数据目录
│  ├─ database     数据库文件备份目录
│  ├─ uploads     上传数据目录
├─ framework      Tiny 框架目录
├─ install        html模板
├─ logs           日志目录(自动创建)
├─ protected     应用保护代码目录
│  ├─ classes     自由扩展类目录,可自己配制
│  ├─ config     配制文件目录,可自己指定
│  ├─ controllers     控制器目录
│  ├─ extension     程序扩展目录
│  ├─ widgets     插件目录
│  ├─ views     视图目录
├─ runtime       运行时生成的编译目录(自动创建)
├─ static        共用的静态文件
├─ themes        主题目录
│  ├─ default     默认主题
│  ├─├─skins     皮肤目录
│  ├─├─widgets     专属主题的插件目录
│  ├─├─views     视图目录
├─ index.php      前端入口文件

URL 模式

URL 的访问方式是 index.php?con=Controller&act=Action

Action 有两种,一种是脚本处理类的 Action,此类 Action 是 Controller 的一个 function另一种是视图类的 Action(也就是视图),当 Controller 中不存在此 function 时,系统自 动会加载此 action 对应的视图文件,如果此视图也不存在,系统会跳转 404 页面。

开启伪静态时 URL 访问方式是 /Controller/Action 也可为 /index.php/Controller/Action

了解系统参数与底层过滤情况

原生 GET,POST,REQUEST

代码审计学习之某shop任意文件删除 根据结果可以看到原生GET,POST,REQUEST变量没有任何过滤。

系统外部变量获取函数

代码审计学习之某shop任意文件删除 可以看到获取外部变量都调用了Req类,跟进 /framework/lib/util/request_class.php

<?php
/**
 * Tiny - A PHP Framework For Web Artisans
 * @author Tiny <tinylofty@gmail.com>
 * @copyright Copyright(c) 2010-2014 http://www.tinyrise.com All rights reserved
 * @version 1.0
 */
/**
 * 封装$_GET $_POST 的类,使$_GET $_POST 有一个统一的出入口
 * @class Req 
 * @note  
 */
class Req
{
    //对应处理$_GET
    public static function get()
    {
        $num = func_num_args();
        $args = func_get_args();
        if($num==1)
        {
            if(isset($_GET[$args[0]])){
                if(is_array($_GET[$args[0]]))return $_GET[$args[0]];
                else return trim($_GET[$args[0]]);
            }
            return null;
        }
        else if($num>=2)
        {
            if($args[1]!==null)$_GET[$args[0]] = $args[1];
            else if(isset($_GET[$args[0]])) unset($_GET[$args[0]]);
        }
        else
        {
            return $_GET;
        }
    }
    //对应处理$_POST
    public static function post()
    {
        $num = func_num_args();
        $args = func_get_args();
        if($num==1)
        {
            if(isset( $_POST[$args[0]])){
                if(is_array( $_POST[$args[0]]))return  $_POST[$args[0]];
                else return trim( $_POST[$args[0]]);
            }
            return null;
        }
        else if($num>=2)
        {
            if($args[1]!==null) $_POST[$args[0]] = $args[1];
            else if(isset($_POST[$args[0]])) unset($_POST[$args[0]]);
        }
        else
        {
            return $_POST;
        }
    }
    //同时处理$_GET $_POST
    public static function args()
    {
        $num = func_num_args();
        $args = func_get_args();
        if($num==1)
        {
            if(isset($_POST[$args[0]])){
                if(is_array($_POST[$args[0]]))return $_POST[$args[0]];
                else return trim($_POST[$args[0]]);
            }
            else{
                if(isset($_GET[$args[0]])){
                    if(is_array($_GET[$args[0]]))return $_GET[$args[0]];
                    else return trim($_GET[$args[0]]);
                }
            }
            return null;
        }
        else if($num>=2)
        {
            if($args[1]!==null)
            {
                $_POST[$args[0]] = $args[1];
                $_GET[$args[0]] = $args[1];
            }
            else
            {
                if(isset($_GET[$args[0]])) unset($_GET[$args[0]]);
                if(isset($_POST[$args[0]])) unset($_POST[$args[0]]);
            }
        }
        else
        {
            return $_POST+$_GET;
        }
    }
    public function only()
    {
        $hash= md5(serialize($_POST));
        $safebox = Safebox::getInstance();
        $__hash__ = $safebox->get('__HASH__');
        if($hash != $__hash__)
        {
            $safebox->set('__HASH__',$hash);
            return true;
        }
        else
        {
            return false;
        }
    }
}
?>

GET和POST变量分别对应了 Req::get()、Req::post()、Req::args() ,且没有任何过滤,每次过滤都会调用Filter类,跟进 /framework/lib/util/filter_class.php
代码审计学习之某shop任意文件删除 该类的每一个方法都对应着不同的过滤功能。

查看系统DB类,了解数据库底层运行方式

/framework/web/model/module_class.php/framework/web/model/query_class.php

前者用于被控制器调用,后者用于 viewAction

代码审计学习之某shop任意文件删除

基本上 Model 类的底层没有任何过滤,只是简单的进行类字符串拼接,所以只要能将 '\ 带入 Model 类中,且没有被 Filter 类过滤,即可构成注入。

系统情况初步集合

基本上除了Filter类,底层没有进行过于严格的过滤。

xss的话只要用了原生 GET,POST,REQUEST ,或者只调用了 Req 类获取参数没有使用 Filter 类进行过滤,那么就很容易造成xss。

sql注入同理,底层 Model 类没有专门进行过滤。

另外 Filter 类我只是简单的看了一下,具体在某个情况下调用的函数不排除被绕过的可能。

后台一处注入

前台看了好久,过滤的很严格找不到注入点,并且这个cms大部分功能都是后台的,所以我只好在后台找一下了,虽然没什么卵用,就当学习思路。

/protected/crontrollers/goods.php set_online方法中接收id参数进行商品上下架处理,却没有对id参数进行过滤,直接拼接进 sql 语句中。

代码审计学习之某shop任意文件删除 代码审计学习之某shop任意文件删除 构造 id=12) and if(1=1,sleep(1),0)#
代码审计学习之某shop任意文件删除

可以看到成功注入

代码审计学习之某shop任意文件删除

同样的,后台有不少地方都没有进行过滤,就不一一列举。

代码审计学习之某shop任意文件删除

后台两处任意文件删除+任意文件读取

第一处比较鸡肋,只能删除 install.lock 文件

/protected/crontrollers/plugin.php
代码审计学习之某shop任意文件删除

可以看到路径前缀从 $this->widgetPath 中获取,跟进

代码审计学习之某shop任意文件删除

APP_CODE_ROOT 为应用开发路径

代码审计学习之某shop任意文件删除

可以看到 name 参数没有任何过滤,我们可以利用 ../../install 跳转到安装目录,将 install.lock 删除然后重新安装。

然后配合MySQL LOAD DATA 任意文件读取,读取服务器上的文件。

任意文件读取

代码审计学习之某shop任意文件删除

代码审计学习之某shop任意文件删除

第二处可以删除任意文件

代码审计学习之某shop任意文件删除

$backs 变量没有任何过滤,直接和 $database_path 拼接然后执行删除操作。所以我们可以利用 ../ 删除任意文件

代码审计学习之某shop任意文件删除

同样可以删除 install.lock 配合MySQL LOAD DATA读取任意文件。


以上所述就是小编给大家介绍的《代码审计学习之某shop任意文件删除》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法技术手册(原书第2版)

算法技术手册(原书第2版)

George T. Heineman、Gary Pollice、Stanley Selkow / 杨晨、曹如进 / 机械工业出版社 / 2017-8-1 / 89.00元

本书使用实际代码而非伪代码来描述算法,并以经验主导支撑数学分析,侧重于应用且规范严谨。本书提供了用多种程序设计语言实现的文档化的实际代码解决方案,还介绍了近40种核心算法,其中包括用于计算点集的Voronoi图的Fortune算法、归并排序、多线程快速排序、AVL平衡二叉树实现以及空间算法。一起来看看 《算法技术手册(原书第2版)》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具