高级篇主要讲

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. Elastic Stack 笔记(二)Elasticsearch5.6 安装 IK 分词器和 Head 插件

    博客地址:http://www.moonxy.com 一.前言 Elasticsearch 作为开源搜索引擎服务器,其核心功能在于索引和搜索数据.索引是把文档写入 Elasticsearch 的过程, ...

  2. linux文件系统分区、格式化、挂载、卷标挂载、永久挂载

    思想不放松你的行为就不会放松,你的行为放松了,说明你的思想放松了.

  3. Spark比MR快是因为在内存中计算?错!

    MapReduce 就像一台又慢又稳的老爷车,虽然距离 MapReduce 面市到现在已经过去了十几年的时间,但它始终没有被淘汰,任由大数据技术日新月异.蓬蓬勃勃.花里胡哨地发展,这个生态圈始终有它的 ...

  4. 移动端适配(手机端rem布局详解)

    1. 问题的引出 如果html5要适应各种分辨率的移动设备,应该使用rem这样的尺寸单位,同时给出了一段针对各个分辨率范围在html上设置font-size的代码: html{font-size:10 ...

  5. ABP vNext 不使用工作单元为什么会抛出异常

    一.问题 该问题经常出现在 ABP vNext 框架当中,要复现该问题十分简单,只需要你注入一个 IRepository<T,TKey> 仓储,在任意一个地方调用 IRepository& ...

  6. 正则表达式在Java中使用

    正则表达式 定义 用一组特殊的字符来描述一组字符串的格式 用于验证字符串是否满足格式 不关心字符串的内容是否有效 1. 基本正则表达式所谓正则表达式就是使用一系列预定义的特殊字符来描述一个字符串的格式 ...

  7. [scrapy-redis] 将scrapy爬虫改造成分布式爬虫 (2)

    1. 修改redis设置 redis默认处在protection mode, 修改/etc/redis.conf, protected-mode no, 或者给redis设置密码, 将bind 127 ...

  8. Java 学习笔记之 Sleep停止线程

    Sleep停止线程: 在Sleep状态下被interrupt,interrupted 状态会被擦除,返回false. 线程在Sleep状态下被interrupt: public class Sleep ...

  9. sql中的 where 、group by 和 having 用法解析

    --sql中的 where .group by 和 having 用法解析 --如果要用到group by 一般用到的就是“每这个字” 例如说明现在有一个这样的表:每个部门有多少人 就要用到分组的技术 ...

  10. ActiveMQ学习总结------原生实战操作(下)03

    本篇将继续延续上一篇的内容,作为知识补充篇,为接下来我们学习spring整合ActiveMQ打好基础 本篇主要学习内容: 1.ActiveMQ 队列服务监听 2.ActiveMQ Topic模型 回顾 ...