PHP代码审计学习总结

0x01 引言

PHP是一种被广泛使用的脚本语言,尤其适合于web开发。具有跨平台,容易学习,功能强大等特点,据统计全世界有超过34%的网站有php的应用,包 括Yahoo、sina、163、sohu等大型门户网站。而且很多具名的web应用系统(包括bbs,blog,wiki,cms等等)都是使用php 开发的,Discuz、phpwind、phpbb、vbb、wordpress、boblog等等。
随着web安全的热点升级,php应用程序的代码安全问题也逐步兴盛起来,越来越多的安全人员投入到这个领域,越来越多的应用程序代码漏洞被披露。面对 这种现状,PHP漏洞“挖掘者”所能得到的漏洞也将越来越少。但是“穷则思变”,既然传统的审计方法不能达到挖掘漏洞的目的,那么我们何不尝试新的审计手 法与思路呢?
在这篇文章中,主要提供给大家的是我在学习PHP代码审计过程中,所获得的一些经验,以及对审计过程的思考。文章内容所提及的内容很浅,但是希望能给大家带来一些思路,对于代码审计或者漏洞挖掘能有新的思考。

0x02 审计之初

代码审计的目的是以挖掘到可以利用的漏洞,所以我们不必通篇的去将代码完全看懂,但是在开始之前做一些准备还是必须,就像渗透之前,我们也需要收集足够多的目标信息,利用工具和制定渗透计划一样。

2.1  流程

在我刚开始练习审计时,拿到一套源码,马上做的事情就是,丢到工具里,去扫敏感的函数,然后去一个一个的回溯它,找到入口点。但是,这样审计了几套源 码,发现这个方法很浪费时间,因为每次我都要在回溯过程中,不断的去寻找源码中定义的一些通用函数。由于不了解整个源码的流程,导致在找这些通用函数的过 程中浪费了很多的时间与精力。
所以,我重新调整了我的审计流程。在拿到源码之后,先从它开始的地方(一般是根目录下的index文件)按照执行的顺序去读代码,一直到它的初始化内容, 和基本功能实现完毕为止。这样,可以明确的了解整套源码的结构,哪一种函数文件放在哪个文件夹下;知道通用函数放在哪个文件中。这对我们在之后阅读“疑 似”有问题的代码时,有很好的帮助,例如,在看到一个通用函数时,我们可以快速的切换到通用函数文件,查找这个函数的实现代码。这个方法带来好处还有好 多,这里就不一一列出了。

2.2  了解

流程的优化可以帮助我们在之后审计的过程中,免去时间和精力上不必要的浪费。而在深入阅读代码之前,了解整套代码的每一个功能点,每一个输入框和他曾经出现的漏洞及相关修补方案,将会大大提高我们在之后的审计效率。
在了解源码的每个功能时,如果你能够注意以观察url的变化,也许能你在后面的阅读带代码过程中跳过很多没用的分支。
而在测试每一个输入框时,如果你仔细观察HTML源码中输入框的id或者name,这也许能帮你在后面的审计过程中更快的定位到利用点。
尝试了解这套源码曾经出现过的漏洞,以及相关的修补方案,这是代码审计中的一条不错的捷径。因为一套源码虽然可能不是一个人完成的,但是它肯定是基于一 个框架的,为这套源码编码的程序员们都会围绕着这个框架进行开发,他们肯定必须要遵守框架的规则,而了解这些曾经出现过的这些漏洞,说不定可以发现他们所 共有的陋习。如果你能够了解这些漏洞修补的详细细节,那就更好了,因为随着Web平台的升级变迁,或者新的技术出现,这些修补也许就会变成摆设。

2.3  计划

有计划地做事,这是一个很好的习惯。计划可以帮助我们明确我们取得了什么样的成果就可以称之为成功,面临什么样的问题才可以称之为失败。这样可以避免我们可能因为某天的情绪不佳而“果断”的放弃,也可以避免我们将时间不断地投向一个不可能完成的任务。
我在代码审计学习过程中,总结有两点是在前期计划必须明确的,
1.        要找什么样的漏洞
2.        要花多长时间完成这次审计
明确找什么样的漏洞,能够方便我们在收集相关资料(如:引发问题的函数字典)时的目标更精准,收集资料更全面。
确定整个审计的时间范围,一时间作为审计的量化标准,可以准确的定位审计是否成功,当然,在不同的情况或者过程中,计划时间是可以调整的

0x03  漏洞本质

程序的本质是变量与函数,漏洞所依赖的也无法脱离这两个元素。让我们先来看下漏洞形成的条件
1.        可以控制的变量【一切输入都是有害的 】
2.        变量到达有利用价值的函数[危险函数] 【一切进入函数的变量是有害的】
漏洞的利用效果最终也取决与函数的功能。所以我们在下面讲述漏洞挖掘的过程中,也将围绕着这两个元素来展开。

0x04  漏洞挖掘

这章所讲的内容,不会很深入的讲述漏洞挖掘的技巧,因为每一种技巧都肯能会涉及到一种技术,单单一个技巧就可以作为一篇文章来发表了。所以我在这章中所 讲述的,只是漏洞挖掘中很基础的内容。目的也很简单,做个比喻来说,我只是为被大火困在高楼中的人们打开一扇窗,至于如何爬下这栋楼,这章中不会有涉及。 当然,如果你觉得你可以走楼梯,也是不错的。
在上一章中,我们提到漏洞形成的两大元素是可控变量,和可控变量能够进入的函数。那么在漏洞挖掘中,我们也不外乎从这两个方向来开始。
1.png
从变量开始跟踪,我们就好像处在下图中圆形的位置,我们要处理的“路”很多,但不是每条“路”都能到达三角形(函数)。
2.png
所以在一般的人工代码审计过程中,大都会选择查找危险函数,然后根据危险函数中的变量回溯到传入变量的方式。
我的审计方法也是偏向于通过函数查找变量,虽然这种方式效果很好,但是我们也不应放过变量跟踪。如果你拥有一款不错的变量跟踪自动化工具,那么你很 幸运,不用花费很大的精力便可以完成这个任务。如果你是手工审计的话,我建议,你在跟踪函数之前,收集所有可控变量(参数)的“最终形态”(所谓最终形 态,就是用户通过各种方式传入进程序经过各种处理后,等待调用时的形态)。这样可以帮助我们能够在跟踪危险函数时,更快的确定,函数是否能被利用。

0x05 总结

在这部分内容,给出大家一些,我在学习过程中摸索到的一些不错的方法和学习审计中所必须要积累的一些内容。

5.1  积累

1.        对于爆出的每种漏洞,都要对其进行分析了解(PoC学习)
2.        对于已修复漏洞,对其补丁或修复方法进行分析了解(DEDE,discuz全局变量覆盖漏洞的二次利用)
3.        平台搭建的通用配置和常用配置要了解

5.2  练习

1.        阅读大的源码,了解代码执行流程
2.        挖掘小型源码漏洞,实践+信心
3.        PoC的编写,深入理解漏洞利用过程

0x06 思考

在这一章节中,我将罗列出我在学习和练习代码审计过程中所想到,但是却没有得到答案的问题。希望能给大家带来思考的同时,也能让大家发现新的思路

6.1  如何跳出传统的思维

很多应用程序的官方都成立了安全部门,或者雇佣安全人员进行代码审计,因此出现了很多自动化商业化的代码审计工具。也就是这样的形势导致了一个局面:大公司的产品安全系数大大的提高,那些很明显的漏洞基本灭绝了,那些大家都知道的审计技术都无用武之地了。
没有绝对安全的代码,我们需要跳出传统的思维,来获得新的漏洞。这也就是所谓的“跳出画来看画”,但是如何跳出来,这是我们当前所要思考的地方。

6.2  变量跟踪自动化的可行性

在学习和练习代码审计的过程中,我没有发现一款能够进行变量跟踪的自动工具,大多数都是搜索危险函数的工具。传统的代码审计都是基于静态的,而变量跟踪需要动态的实现,这也是导致跟踪变量,工作量大的主要原因。
基于这个问题,自己有个想法,可以在一款代码调试工具中添加特定变量发生改变或进入某些函数之前运行暂停的功能。这样,我们在代码审计的过程中便可以设定我们需要跟踪的可控变量,当其值发生变化时,能够马上了解它的情况。
也可以制作一个脚本,能够罗列出特定变量所必须或者有可能经历的函数。这样我们可以结合危险函数跟踪的结果进行交集的查找,大大的提高了效率和效果。

0x07  引用

1.        《WEB代码审计与渗透测试(PPT)》by 80vul
2.        《高级PHP应用程序漏洞审核技术》by 80vul
3.        《实例分析讲解为您敲开代码审计大门》by 90sec

原文:https://www.t00ls.net/thread-20855-1-1.html 作者 唐门三少

本文由网络安全攻防研究室(www.91ri.org)信息安全小组收集整理,转载请注明出处。