高级篇主要讲

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. The 10 Most Important Linux Commands/10个最经常使用的命令行

    1. ls 命令:to show all of the major directiories filed under a given file system. for example: ls /app ...

  2. Java多线程基础知识例子

    一.管理 1.创建线程 Thread public class Main { public static void main(String[] args) { MyThread myThread = ...

  3. [Leetcode] 第319题 灯泡开关

    一.题目描述 初始时有 n 个灯泡关闭. 第 1 轮,你打开所有的灯泡. 第 2 轮,每两个灯泡你关闭一次. 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭).第 i 轮,每 i  ...

  4. Mach-O在内存中符号表地址、字符串表地址的计算

    KSCrash 是一个用于 iOS 平台的崩溃捕捉框架,最近读了其部分源码,在 KSDynamicLinker 文件中有一个函数,代码如下: /** Get the segment base addr ...

  5. 基于Docker搭建大数据集群(五)Mlsql部署

    主要内容 mlsql部署 前提 zookeeper正常使用 spark正常使用 hadoop正常使用 安装包 微云下载 | tar包目录下 mlsql-cluster-2.4_2.11-1.4.0.t ...

  6. Spring boot 梳理 - @Conditional

    @Conditional(TestCondition.class) 这句代码可以标注在类上面,表示该类下面的所有@Bean都会启用配置,也可以标注在方法上面,只是对该方法启用配置. spring框架还 ...

  7. 利用echarts展示旅行足迹

    前言 一直有个环游世界的梦,周游列国,体验不同国家的人类文明,寻山访水,体验造物主大自然的伟大造化.毕竟人生不止眼前的苟且,还有诗和远方.这么多年以来,陆续走过了一些地方,每到一个地方,都让我离梦想又 ...

  8. jenkins+svn+Ant+tomcat+非maven项目构建

    首先,输入项目名称,创建一个自由风格的项目; 然后,配置旧项目的策略参数,目的是防止构建项目太多,占用资源. 下一步,jdk版本选择: 下一步,关联svn项目. 下一步:配置ant 看不清,再来一张. ...

  9. 深度解密Go语言之反射

    目录 什么是反射 为什么要用反射 反射是如何实现的 types 和 interface 反射的基本函数 反射的三大定律 反射相关函数的使用 代码样例 未导出成员 反射的实际应用 json 序列化 De ...

  10. MongoDB的复制源oplog

    ​ 之前有说过MongoDB的复制是异步复制的,其实也就是通过oplog来实现的,他存放在local数据库中,我们来查询一下主节点的日志大小. ​ 除了主节点有oplog之外,其他节点也就有oplog ...