前言

先知上一个大佬挖的洞,也有了简单的分析

https://xianzhi.aliyun.com/forum/topic/2135

我自己复现分析过程,漏洞的原理比较简单,但是漏洞的利用方式对我而言则是一种新的利用方式。本文对分析过程做一个记录。

正文

分析软件运行的流程

拿到一个需要分析的 php 程序,首先看看客户端的 http 请求是如何对应到程序中的代码的。

首先得找一个分析的开始点,就以 触发漏洞 的 请求为示例把。

GET /cash/block-printTradeBlock.html?param=eyJvcmRlckJ5IjoiaWQgbGltaXQgMCwxO3NlbGVjdCBpZigxPTIsMSxzbGVlcCgyKSkjIiB9 HTTP/1.1
Host: hack.ranzhi.top
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=2c17fafndhnfle6j4r9dskopk3; lang=zh-cn; theme=default; rid=kcvhkos22q574sqdjiha39icl5; keepLogin=false; XDEBUG_SESSION=14822
Connection: close

安装系统时我们设置 www 目录为虚拟主机目录, 所以当我们访问 /cash/block-printTradeBlock.html  时,实际上访问的是 www/cash/block-printTradeBlock.html, 但是 cash 目录中并没有相关的文件

不过该目录下有 .htaccess 文件,通过该文件可以重写 url, 根据规则我们知道,如果访问 cash 目录下不存在的文件,会把请求交给 index.php 处理。

.htaccess 文件参考

http://t.cn/REFVyCJ
https://www.zybuluo.com/phper/note/73726

那下面就分析 index.php 即可,下好断点,然后发送数据包

f7 跟进 loader.php, 首先加载了一些基础类。

然后做一些初始化的操作,实例化一些基础对象,后面用来加载程序的主体

然后是设置路由方式

$app->parseRequest();

会对 处理后 url- 分割,第一项作为 module_name 第二项作为 method_name. 以上面的数据包为例。执行完后的结果如下。

此时我们已经设置好了 模块名 和 方法名,  下面回到 loader.php

$common->checkPriv();  # 权限校验
$app->loadModule(); #  加载相关模块的方法

进入 loadModule 方法


public function loadModule()
{
$appName = $this->appName;
$moduleName = $this->moduleName;
$methodName = $this->methodName; /*
* 设置control的类名。
* Set the class name of the control.
**/
$className = class_exists("my$moduleName") ? "my$moduleName" : $moduleName; /*
* 创建control类的实例。
* 根据 `$app->parseRequest()` 设置好的 模块名 实例化对应的类
* Create a instance of the control.
**/
$module = new $className();
$this->control = $module; /*
* 使用反射机制获取函数参数的默认值
* 通过反射获取 函数的参数名称,
* 通过 `php` 的反射机制 , 获取参数名, 并且初始化好
*
* */
$defaultParams = array();
$methodReflect = new reflectionMethod($className, $methodName);
foreach($methodReflect->getParameters() as $param)
{
$name = $param->getName(); $default = '_NOT_SET';
if(isset($paramDefaultValue[$appName][$className][$methodName][$name]))
{
$default = $paramDefaultValue[$appName][$className][$methodName][$name];
}
elseif(isset($paramDefaultValue[$className][$methodName][$name]))
{
$default = $paramDefaultValue[$className][$methodName][$name];
}
elseif($param->isDefaultValueAvailable())
{
$default = $param->getDefaultValue();
} $defaultParams[$name] = $default; # 组成一个由 defaultParams[参数名] = "" 构成的字典
} /**
* 根据PATH_INFO或者GET方式设置请求的参数。
        * 根据请求方式, 从请求数据包中获取需要的参数信息。
*/
if($this->config->requestType != 'GET')
{
$this->setParamsByPathInfo($defaultParams);
}
else
{
$this->setParamsByGET($defaultParams);
}        # 过滤数据
       if($this->config->framework->filterParam == 2)
{
$_GET = validater::filterParam($_GET, 'get');
$_COOKIE = validater::filterParam($_COOKIE, 'cookie');
} /* 调用方法,并传入参数 */
call_user_func_array(array($module, $methodName), $this->params);
return $module;
}

该函数的流程为

  • 根据 $app->parseRequest() 设置好的 模块名 实例化对应的类
  • 通过 php 的反射机制 , 获取方法参数名, 并且初始化好
  • 根据请求方式, 从请求包中获取需要的参数信息到 $defaultParams
  • 过滤数据
  • 调用方法,并传入参数

    看一看设置参数的方式

按照 -  分割 url格式为

module_name-method_name-param1-param2

所以在该程序中 wwwapp 目录是相互对应的。

当我们请求

/dir_name/module_name-method_name-param-...-paramN.html

最后会调用 app 目录下 module_name 中的 control.php

module_name->method_name(param1,....,paramN)

比如

/cash/block-printTradeBlock.html

实际就是调用 app 目录下 cash 中的 control.php

block->printTradeBlock()

SQL 注入分析

漏洞出现在 lib/base/dao/dao.class.php

这里只对 $order 部分进行了校验, 而没有对 limit 后面的部分进行校验。

看到 printTradeBlock

$this->processParams() 中设置好 $this->params

可以看到 $this->params 就是 json_decode(base64_decode($_GET['param']))

然后又会调用

orderBy($this->params->orderBy)

所以我们可以控制 limit 后面的部分, SQL注入

这套程序中还会执行 sql 语句,用的是 Pdo用的是 $pdo->query(), 这个函数可以一次执行多条 sql 语句。

  /**
* 执行SQL语句,返回PDOStatement结果集。
* Query the sql, return the statement object.
*
* @access public
* @return object the PDOStatement object.
*/
public function query($sql = '')
{
/* 如果有错误,返回一个空的PDOStatement对象,确保后续方法能够执行。*/
/* If any error, return an empty statement object to make sure the remain method to execute. */
if(!empty(dao::$errors)) return new PDOStatement(); if($sql)
{
$sql = trim($sql);
$sqlMethod = strtolower(substr($sql, 0, strpos($sql, ' ')));
$this->setMethod($sqlMethod);
$this->sqlobj = new sql();
$this->sqlobj->sql = $sql;
}
else
{
$sql = $this->processSQL(); // 大概就是获取 sql 语句
}
$key = md5($sql); try
{
$method = $this->method;
$this->reset(); if($this->slaveDBH and $method == 'select')
{
if(isset(dao::$cache[$key])) return dao::$cache[$key];
$result = $this->slaveDBH->query($sql);
dao::$cache[$key] = $result;
return $result;
}
else
{
if($this->method == 'select')
{
if(isset(dao::$cache[$key])) return dao::$cache[$key];
$result = $this->slaveDBH->query($sql);
dao::$cache[$key] = $result;
return $result;
} return $this->dbh->query($sql);
}
}
catch (PDOException $e)
{
$this->sqlError($e);
}
}

这样我们的利用方式就简单了。

  • 闭合 limit 语句,用 ;  连接多条语句
  • 没有回显, 使用 时间盲注

poc

任意文件下载 && 任意文件删除

由于可以一次执行多条 sql 语句 ,我们实质上已经可以控制数据库了。

app/sys/file/control.php ,有两个函数  deletedownload, 分别用于删除文件和下载文件。

以  delete 为例

$this->file->getById($fileID)  时间就是在 表前缀sys_file 中查找对应 id 相对应的 路径。

利用 sql 注入修改为目标路径(用 ../ 进行目录跳转),然后选择相应 id 即可删除指定文件。下载文件也是类似。

getshell

删除 my.php 后 会要求我们重新安装系统。

在重装系统的最后一步,会直接使用 POST 中的值,来设置 my.php 的内容,同时 , 访问 install.php 时,是不会调用参数过滤的函数的

所以可以注入 php 代码,getshell

然之协同系统6.4.1 SQL注入导致getshell的更多相关文章

  1. 然之协同系统6.4.1 SQL注入之exp编写

    前言 前面已经说明了 漏洞成因,这里介绍一下 exp 的编写. 正文 为了 getshell 或者是 任意文件下载, 我们需要修改 数据库中的 前缀sys_file 表, 所以我们的利用方式如下 使用 ...

  2. 一次SQL注入导致的"越权"

    原文来自SecIN社区-作者:tkswifty 相关背景   在实际的业务开发中,SQL交互往往是业务系统中不可或缺的一项.在Java中提供了类似Mybatis.Hibernate.SpringDat ...

  3. SQL注入到getshell

    SQL注入到getshell 通过本地 pikachu来复现  前提: 1.存在SQL注入漏洞 2.web目录具有写入权限 3.找到网站的绝对路径 4.secure_file_priv没有具体值(se ...

  4. [代码审计]某租车系统JAVA代码审计[前台sql注入]

    0x00 前言 艰难徘徊这么久,终于迈出第一步,畏畏缩缩是阻碍大多数人前进的绊脚石,共勉. 系统是租车系统,这个系统是Adog师傅之前发在freebuf(http://www.freebuf.com/ ...

  5. [漏洞案例]thinkcmf 2.x从sql注入到getshell实战

    0X00 前言 这个案例是某项目的漏洞,涉及敏感的地方将会打码. 很久没更新博客了,放一篇上来除除草,新的一年会有所转变,以后会有更多领域的研究. 下面是正文 0X01 正文 某厂商某个网站用的是th ...

  6. ZZZPHP1.61 代码审计-从SQL注入到Getshell

    近期有很多小伙伴在后台留言想看关于代码审计的文章,其实有关审计的文章网上资源是比较多的,但是从代码审计开始到结束的这类文章却少之甚少. 今天要讲解的ZZZPHP1.61这套审计漏洞比较多,SQL注入漏 ...

  7. sql参数化防止sql注入导致的暴露数据库问题

    #转载请联系 假如你在京东工作,你要做的任务就是做一个商品搜索的东西供用户使用. 然后你写出了这么一个程序的雏形. import pymysql def main(): conn = pymysql. ...

  8. 卧槽,sql注入竟然把我们的系统搞挂了

    前言 最近我在整理安全漏洞相关问题,准备在公司做一次分享.恰好,这段时间团队发现了一个sql注入漏洞:在一个公共的分页功能中,排序字段作为入参,前端页面可以自定义.在分页sql的mybatis map ...

  9. 了解SQL注入攻击

    SQL注入:利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,这是SQL注入的标准释义. 随着B/S模式被广泛的应用,用这种模式编写应用程序的程序员也越来越多,但由于开发人员的水 ...

随机推荐

  1. HLS:OpenCV和RTL代码转换关系

    OpenCV 图像处理是基于存储器帧缓存而构建的, 它总是假设视频帧数据存放在外部 DDR 存储器中. 由于处理器的小容量高速缓存性能的限制, 因此, OpenCV 访问局部图像性能较差. 并且, 从 ...

  2. maven工程下testng简单使用

    创建maven工程后,将Repository仓库中maven代码粘贴复制到pom.xml文件中,仓库地址:<!-- https://mvnrepository.com/artifact/org. ...

  3. Ubuntu14.04下Ambari安装搭建部署大数据集群(图文分五大步详解)(博主强烈推荐)

    不多说,直接上干货! 写在前面的话 (1) 最近一段时间,因担任我团队实验室的大数据环境集群真实物理机器工作,至此,本人秉持负责.认真和细心的态度,先分别在虚拟机上模拟搭建ambari(基于CentO ...

  4. nginx设置开机自启动

    每次启动nginx服务都需要到安装目录下的/sbin下面,感觉挺麻烦的. 下面介绍一下如何在Linux(CentOS)系统上,设置nginx开机自启动. 1 用脚本管理nginx服务 第一步:在/et ...

  5. 西蒙布朗-C4模型

    关于 C4 模型的一些解释 C4 模型是来自 software architecture for developers 一书的定义,指的是 Context 上下文场景.Container 容器.Com ...

  6. git提交代码到远程仓库

    1.仓库初始化 git init 2.连接仓库 git remote add origin 仓库地址 3.查看状态 git status 4.将文件添加到暂存区 git add 状态里的新文件 5.将 ...

  7. 关于function构造函数特别注意的

    function在javascript中是对象,所以function持有构造函数例子:var a = new Function("x","y","re ...

  8. springboot-20-全局异常处理

    springboot的全局异常处理 . 新建一个类GlobalDefaultExceptionHandler 在class上注解 @ControllerAdvice 方法上注解 @ExceptionH ...

  9. Java 中 String 的常用方法(一)

    上一篇介绍了 String 中的几个常用构造方法,由 String 这个核心对象发散出去关于字符的编码,字符的字节表达,对 GC 的影响,正则表达式,模式匹配,这可能是 Java 里内涵最丰富的对象了 ...

  10. SQL注入原理讲解

    1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码被流传于网络,连日来引发众多网民对自己账号.密码等互 ...