高级篇主要讲

1. 熟知各个开源框架历史版本漏洞。

2. 业务逻辑漏洞

3. 多线程引发的漏洞

4. 事务锁引发的漏洞

在高级篇审计中有很多漏洞正常情况下是不存在的只有在特殊情况下才有

PHP常用框架

Zendframwork,Yii,Laravel ,、ThinkPHP

这里举例因为thinkphp由国内人开发用户量较多而且历史漏洞也多

Thinkphp历史漏洞很多,对于漏洞形成原因可以自己复现。

篇幅有限只介绍披露漏洞

Query方法 低于3.1.3 有sql注入问题

Order方法 低于 5.x 有sql注入问题

Update方法 低于3.2.3 有sql注入问题

/**
* 更新记录
* @access public
* @param mixed $data 数据
* @param array $options 表达式
* @return false | integer
*/
public function update($data,$options) {
$this->model = $options['model'];
$this->parseBind(!empty($options['bind'])?$options['bind']:array());
$table = $this->parseTable($options['table']);
$sql = 'UPDATE ' . $table . $this->parseSet($data);
if(strpos($table,',')){// 多表更新支持JOIN操作
$sql .= $this->parseJoin(!empty($options['join'])?$options['join']:'');
}
$sql .= $this->parseWhere(!empty($options['where'])?$options['where']:'');
if(!strpos($table,',')){
// 单表更新支持order和lmit
$sql .= $this->parseOrder(!empty($options['order'])?$options['order']:'')
.$this->parseLimit(!empty($options['limit'])?$options['limit']:'');
}
$sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:'');
return $this->execute($sql,!empty($options['fetch_sql']) ? true : false);
}

5. x 版本有命令执行漏洞

在github上也有历史分支可以查看修复代码

业务逻辑

想要对整体的逻辑进行审计

  1. 熟悉业务场景
  2. 熟悉业务流程
  3. 通读代码

多线程引发的漏洞

这里我写了个例子

<?php

$money=100;//数据库查询的用户余额

$buy=intval($_GET['buy']);

if ($money>0&& $money-$buy>0)

{

    sleep(10);

    $moeny-=$buy;

    //写入数据库

}

return $money

正常情况下用户余额一定不为负数 如果在并发情况下呢?

用户发送恶意并发请求时就有可能出现这种情况。这么防御呢

这里需要知道事务和锁的概念可以自行百度理解我这里简单概述一下

事务:类似一个执行任务 成功就任务完成 ,失败任务自动回滚到未接任务前

锁:悲观锁,乐观锁。

我们可以把多线程请求变成单线程处理,这里也可以用队列压入压出。

<?php

$money = 100;//数据库查询的用户余额

$buy = intval($_GET['buy']);

try {

    if (flock($money, LOCK_EX)) {

        if ($money > 0 && $money - $buy > 0) {

            sleep(10);

            $moeny -= $buy;

            //写入数据库A

            throw new ExceptionNew("xp");

            //写入数据库B

        }

        flock($money, LOCK_UN);

    }

} catch (Exception $exceptione) {

    throw new ExceptionNew("xp");

}

return $money

这样确实解决了这个并发问题,但又有另外一个问题,如果有多个数据库操作中间一段中断是无法对数据还原的,这里我们需要把事务也加上同时默认加锁。

我们修改一下代码看一下

<?php

$money=100;//数据库查询的用户余额

$buy=intval($_GET['buy']);

try

{

    $this->startTrans();//开启事务

    if ($money>0&& $money-$buy>0)

    {

        sleep(10);

        $moeny-=$buy;

        $this->commit(); //提交事务

        //写入数据库

    }

}

catch (Exception $exceptione)

{

    $this->rollback();//回滚

}

return $money
<?php $buy=intval($_GET['buy']); try { $this->startTrans();//开启事务 $money=100;//数据库查询的用户余额 if ($money>0&& $money-$buy>0) { sleep(10); $moeny-=$buy; $this->commit(); //提交事务 //写入数据库 } } catch (Exception $exceptione) { $this->rollback();//回滚 } return $money

在加了事务的悲观锁后,所有请求到已经开启事务的代码,都会进行阻塞只有提交了事务或者回滚才会处理下一个请求。

然而这样的代码并不能防御并发。这也是很多开发中的问题,确实做了事务加锁,依然没有用。 加事务必须是在查询内加,不然依旧会造成并发问题。 我们在改改把读放入事务锁中。

<?php

$buy=intval($_GET['buy']);

try

{

    $this->startTrans();//开启事务

    $money=100;//数据库查询的用户余额

    if ($money>0&& $money-$buy>0)

    {

        sleep(10);

        $moeny-=$buy;

        $this->commit(); //提交事务

        //写入数据库

    }

}

catch (Exception $exceptione)

{

    $this->rollback();//回滚

}

return $money

这样也解决了脏读的问题。

脏读:

(针对未提交数据)如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。

当然也有更复杂的情况可能框架有多个端。这种二次利用的情况更加难以审计。

在实际审计中我们想要精通一个语言的代码审计我们要做的更难

  1. 要比产品更懂业务
  2. 要比测试更懂流程
  3. 要比开发更懂代码
  4. 要比架构更懂框架

自此囊括从初级到高级的学习就到此为止了,但我们的学习却不能停止,这也是我个人对php代码审计学习的理解肯定有不合理的地方,不足可以直接提出修改,共勉!

 

PHP代码审计基础-高级篇的更多相关文章

  1. PHP代码审计基础-中级篇

    初级篇更多是对那些已有的版本漏洞分析,存在安全问题的函数进行讲解,中级篇更多是针对用户输入对漏洞进行利用 中级篇更多是考虑由用户输入导致的安全问题. 预备工具首先要有php本地环境可以调试代码 总结就 ...

  2. PHP代码审计基础-初级篇

    对于php代码审计我也是从0开始学的,对学习过程进行整理输出沉淀如有不足欢迎提出共勉.对学习能力有较高要求,整个系列主要是在工作中快速精通php代码审计,整个学习周期5天 ,建议花一天时间熟悉php语 ...

  3. Java基础高级篇 NIO

    nio模型与io模型的对比 netty 是什么 怎么使用

  4. Spark学习体系整理(基础篇、中级篇、高级篇所涉及内容)

    新手刚开始学习比较迷茫,参考下面,然后找相关资料学习 1 Spark基础篇      1.1 Spark生态和安装部署          在安装过程中,理解其基本操作步骤.          安装部署 ...

  5. Kotlin——高级篇(四):集合(Array、List、Set、Map)基础

    在实际的项目开发中,集合的运用可以说是多不胜数.不过Kotlin中的集合运用和Java中还是有很大的差别,他们两者之间,除了集合的类型相同以外,还包含集合的初始化的不同,以及Kotlin对于集合封装特 ...

  6. C#高级知识点&(ABP框架理论学习高级篇)——白金版

    前言摘要 很早以前就有要写ABP高级系列教程的计划了,但是迟迟到现在这个高级理论系列才和大家见面.其实这篇博客很早就着手写了,只是楼主一直写写停停.看看下图,就知道这篇博客的生产日期了,谁知它的出厂日 ...

  7. 【转载】Spark性能优化指南——高级篇

    前言 数据倾斜调优 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 查看导致数据倾斜的key的数据分布情况 数据倾斜的解决方案 解决方案一:使用Hive ETL预处理数 ...

  8. .NET ORM 的 “SOD蜜”--零基础入门篇

    PDF.NET SOD框架不仅仅是一个ORM,但是它的ORM功能是独具特色的,我在博客中已经多次介绍,但都是原理性的,可能不少初学的朋友还是觉得复杂,其实,SOD的ORM是很简单的.下面我们就采用流行 ...

  9. 【转】【技术博客】Spark性能优化指南——高级篇

    http://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651745207&idx=1&sn=3d70d59cede236e ...

随机推荐

  1. DirectX12 3D 游戏开发与实战第四章内容(上)

    Direct3D的初始化(上) 学习目标 了解Direct3D在3D编程中相对于硬件所扮演的角色 理解组件对象模型COM在Direct3D中的作用 掌握基础的图像学概念,例如2D图像的存储方式,页面翻 ...

  2. vue2.0生成二维码图片并且下载图片到本地兼容写法

    vue生成二维码图片,这里使用的是qrcode.js 这个插件(亲测写法,兼容没有问题) 第一步,下载插件 需要注意,这里下载的是qrcodejs2 cnpm install --save qrcod ...

  3. Java13新特性

    Java 13 的官方开发目标包含改进垃圾收集.应用程序的类数据共享和文本块 Java 开发工具包(JDK)13,标准 Java 的下一个版本,现在可作为候选版本使用,所有新功能都已锁定.JDK 13 ...

  4. C#操作SQLServer的一个简单封装

    class DBHandler { //SqlConnection数据库连接对象 private SqlConnection localConnection = null; //构造函数中初始化连接对 ...

  5. Maven 创建项目之简单示例

    maven 是一个项目管理工具.可以用来管理jar包依赖,构建项目等. 那么接下来,就在eclipse中使用maven创建一个简单的项目. 1,依次点击File-> New -> Othe ...

  6. mysql5.6.27压缩版安装配置指南【个人总结】

      1..下载准备压缩包   360云盘下载地址: https://yunpan.cn/cPKyugkUcDEmP  访问密码 375b   2.解压缩,将压缩版解压到D盘 D:\mysql-5.6. ...

  7. mybatis-generator生成数据对象

    mybatis-generator生成数据对象 步骤一:在pom文件中添加build的插件 <build> <finalName>doudou</finalName> ...

  8. windows无法安装到这个磁盘怎样解决,及激活

    在cmd输入.sql server 2008  slmgr.vbs -ipk KH2J9-PC326-T44D4-39H6V-TVPBY  这个问题遇到的挺多次的,依稀记得上次搞这个问题搞了很久,今天 ...

  9. python + selenium 环境搭建及问题

    搭建平台windows 准备工具如下: ------------------------------------------------------------- 下载python https://w ...

  10. 【Python笔记】Python变量类型

    Python 变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据 ...