php 引用controller_基于PHP的代码安全审计方法研究与实践

引用本文:陈艺夫.基于PHP的代码安全审计方法研究与实践[J].通信技术,2020,53(07):.

摘 要

随着互联网的普及,internet在人们生活中的作用日益凸显。而PHP是web互联网时代的编程语言主力军之一。与此同时,编程人员的安全意识不足,代码逻辑不合理等原因造成了各种各样的安全问题。但因此产生的网络安全事件却并没有让软件开发人员的网络安全意识与软件开发能力齐头并进,保持同水平的增长。形成了“开发能力强,安全意识弱”的奇怪现象。本人就网络中基于PHP开发的CMS系统作为切入点,进行网络安全审计的思路分析与探讨,以便普及网络安全意识,促进网络安全意识与软件开发能力齐头并进。

关键词:代码审计;php;web安全;CMS系统;代码安全

内容目录:

0 引 言

1 漏洞发掘方式简介

2 代码安全审计的方式简介

3 php语言开发的项目漏洞产生的原因

4 审计的主要思路以及技术

4.1 漏洞产生的必要条件

4.2 一般情况下代码审计的主要类别

4.3 危险函数追踪法

4.4 逻辑分析法

5 结 语

0

引 言

随着web3.0概念的提出,web2.0的“主力军”之一的PHP并没有退居幕后,依然以“微服务”、“api服务”占据着web3.0的主力地位。其便捷易学的特

性使得加入PHP开发的人员多而杂,进而导致PHP开发的项目容易产生安全漏洞;而市场占有率高,则容易吸引别人寻找漏洞。造成了审计PHP开发的开源CMS成为了攻击web服务的最有效的手段之一。具体web应用漏洞占比如图1所示。

a059cbe31368e43e81708c9537236f8a.png

图1CNVD 2020年4月通用漏洞统计

1

漏洞发掘方式简介

漏洞发掘方式主要包含了代码审计和渗透测试。相对于渗透测试,代码审计只关心某个系统的代码漏洞,不关心提供代码支持环境或者其他支持环境的漏洞;其受测面更窄,却更具深度。但是代码审计主要针对的是owasp top 10漏洞,对于逻辑漏洞的发掘能力相对较弱。

2

代码安全审计的方式简介

代码安全审计是一种漏洞挖掘方式,主要包含了白盒审计、黑盒审计、灰盒审计。三种不同的测试方式有不同的优缺点。根据要求使用不同的审计方法。这里我们主要讨论以何种思路来利用上面三种审计方式完成漏洞挖掘任务。

3

PHP语言开发的项目漏洞产生原因

PHP语言开发的产品产生漏洞的客观原因有:①PHP发展过热,导致进入行业的初学者较多。总体而言,代码的质量不高。②早期安全事件不受重视,安全开发意识的培训不到位。③PHP项目以小公司为主,形成了“短平快”的开发方式,追求的是“敏捷开发”。因为需要提高开发效率、维护客户关系等原因,有意无意的忽略安全管理。

PHP语言开发的产品产生漏洞的具体原因有:①代码编写者在编写代码时对传入的参数没有过滤或过滤不严。②PHP语言本身提供的方法出现了漏洞。③使用了不安全的函数。④代码运行逻辑不严谨。

4

审计的主要思路以及技术

4.1 漏洞产生的必要条件

条件一:用户可以控制的输入。条件二:用户可以获得输出。条件三:用户可以利用输入在服务器或者客户端执行权限外的操作。

值得注意的是,以上的第一个条件中,用户“可以控制的输入”既指可以完全随意输入,也包含具有限制性的输入。反应在漏洞上就是漏洞的利用难度高低以及影响范围的大小。

第二个条件不单指直接通访问获得及时反馈或结果,也包含利用dnsLog、反弹shell、延时判断、非正常返回判断等获得反馈或结果。

第三个条件为主观条件。在某一个权限范畴内出现BUG,尽管是设计者因未考虑周全产生的问题,但是获取的信息或者操作的权限任在管理者允许的权限内,就不能视作安全漏洞。这种漏洞的判断条件弹性较大,也是众多白帽子和厂商关于漏洞定级存在的主要矛盾点。

4.2 一般情况下代码审计的主要类别

一般的代码审计需求分为两类,第一类是针对开源系统进行的。大多数属于公益类审计。另一类是针对授权获取到源码后的审计。大部分属于商业行为。但是本文所述审计方法都适用以上两种情况。

4.3 危险函数追踪法

思路:在php种常见的任意文件读取、任意文件删除、任意变量覆盖、任意文件包含等漏洞中都

会有一些固定而且危险的函数或者方法。主要涉及的函数包含以下但不限于以下函数:read()、unlink()、extract()、include()。所以审计的时候可以针对性的去查找相关方法、函数、关键字等。这里使用YCCMS开源系统进行测试(注:所有本文展示的漏洞均已上报国家信息安全漏洞共享平台,勿做违法用途)。

方法:使用开源的编辑器或者审计工具协助追踪函数,如:vscode中的搜索、seay源码审计系统中的全文搜索以及自动审计。

如图2所示,在使用了seay源码审计系统之后,系统会自动追踪相关危险函数。也可以在规则中自己添加自定义的规则。但由于追踪的目标是危险函数的特征字符,且未对相关的代码逻辑进行进一步的分析,导致这种方法检索出来的漏洞存在大量的误报情况。除图2中所圈出来的信息存在漏洞可能,其余皆为误报。

4b21928edae3ceb1a76fa81aebd0768e.png

图2seay源码系统自动审计所查疑似漏洞

点击图2中圈出的链接可以直接访问到使用该危险方法unlink()的文件。由于误报问题,我们需要进入该文件进行一次逻辑分析。人工判定是否存漏洞。所追踪到的函数内容如图3所示。

28b367187a9021a8d3e8fe13bd7ed1c5.png

图3追踪危险函数unlink

通过阅读该文件,我们发现途中是一个使用该方法的类,该类在触发使用clean方法的时候会调用危险函数unlink()。根据该类的clean方法的说明我们可以知道,该方法是用来清理系统生成的静态文件的方法。是一个正常的删除功能的写法。而unlink()函数使用的参数来自于变量$_fileDir与$_dirName的拼接。根据clean方法的内容我们可以知道。如果变量$_GET[‘navname‘]可控,即可利用../等字符进行跨目录操作。形成任意文件删除漏洞。具体逻辑如图4所示。

d1263f38c4e321b3c022a3c0a76bbd39.png

图4危险方法clean的实现逻辑

然后我们可以继续追踪$_GET有没有被过滤。但是首先应该要确定该类NavAction是否被引用,引用来自于哪里。这里可以使用vscode编辑器的全文关键字搜索功能,如图5所示。

9ec2dc9c6fa8b17009a20a8a2386b554.png

图5通过vscode全文追踪发现关键字

发现该文件并未被引用。那么该类的功能需要触发必然是以参数调用的方式进行引用。一般情况下为自动加载、URL请求加载两种方式。我这里的思路为直接访问入口文件,读懂逻辑获得关键逻辑信息,用于寻找该文件的出发点,以达到寻找到$_get的值的来源。

首先需要理解框架结构。大致的目录如下:

├─admin

├─ceshi1

├─ceshi2

├─compile

├─config

├─controller

├─model

├─public

且admin目录下存在index.php则极可能是后台入口文件。

访问该文件,内容如下:

require str_replace('','/',substr(dirname(__FILE__),0,-6)).'/config/run.inc.php';

?>

发现该文件只有非常简单的一行。这种格式是一个标准的入口文件。

根据require的请求逻辑继续去追踪../config/run.inc.php文件。内容如图6所示。

a7a92bfe8860c101df60fc3dad27f76f.png

图6入口文件run.inc.php文件

在图6文件中第19行可以发现_autoload()类。该函数用于自加载类文件。

触发条件为“访问类”的时候,既当代码运行到29行:Factory::setAction的时候。根据其代码意思可以知晓。在访问该文件的时候会根据$_classname变量的值引入controller目录或者model目录或者class目录下的“.class.php”文件作为类文件的引入。

而$_classname则必然来自于Factory::setAction()-run()的触发。这里使用vscode软件的类追踪按下Ctrl+左键可以直接定位到该文件或者方法。Factory类内容如图7所示。

99862d749a9dd0810d08bbc359814f23.png

图7Factory工厂类

由以上代码我们可以得知,访问类文件依靠getA()方法,表现在url请求中就是a=“xxx”。这里的XXX可以是array中存在任意类文件名。

以上内容可以确定选择类的方式为http://localhost/admin/index.php?a=Nav。而确定Factory::setAction()->run();中的setAction之后需要继续使用vscode的快速链接功能追踪到方法run()。具体内容如图8所示。

60cf0b43e5d255902e918c99a1b7bfdf.png

图8工厂类的run方法实现

由图8代码第29和30行可以知道。想要触发一个类的某种方法需要传参m即可。那么最后我们获取到触发漏洞的方法应该是访问url:

http://localhost/admin/index.php?a=Nav&m=clean。其中Nav是类的缩写。m是需要执行的方法。逻辑如图9所示。

76d5ec957f100ec5c037c395cdd0edeb.png

图9系统运行逻辑

根据以上分析总结发现,在该文件运行的时候不存在对$_get[‘navname’]变量的过滤。所以可以直接传入导致漏洞。最后的exploit如下:

http://localhost/admin/index.php?a=nav&m=clean&navname=../../etc/passwd

这里的index.php因为路径重写可以省略。这里的../../etc/passwd则是需要任意删除的文件。

该方法主要的优势有:①快速找到切入点。②能快速寻找到可能出现漏洞的代码。

主要缺点:①无法系统而且完整的对文件进行分析,需要在发现漏洞后花费大量精力寻找触发点。②误报率高,危险函数量大,审查较为麻烦。③很难发现逻辑漏洞。

4.4 逻辑分析法

不同于危险函数追踪法,逻辑分析法在漏洞分析之前需要阅读项目核心代码或者通读代码。需要在正式开始审计之前熟悉项目中的各种功能。逻辑分析法主要使用的审计方法是灰盒审计和黑盒审计。

思路:采用最有可能出现问题的输入测试现有所有功能(黑盒测试)。如:在留言框中填写“ ”’ ”、在登陆注册使用“ admin and ‘“`-- /* ”等进行测试。通过查看页面反应、数据反应、后台反应等方法确定是否存在不同的输出。或者思考各个功能之间的逻辑联系,画出权限关系、功能关系、角色关系等的思维导图,从而寻找交叉点、分离点、冲突点等方法。

如图10所示,通过在后台登陆页面尝试使用“返回“的方式测试,测试是否存在验证码不过期的问题。

73599f22251cd0648a600de027b2c4d8.png

图10ZZZCMS后台登陆页面

经过尝试发现返回之后验证码不更新,基本确认这里存在验证码绕过漏洞(注:低危漏洞,一般用于爆破)。这种测试方式属于黑盒测试。

验证思路:采用burpsuit抓取请求包再利用intruder模块大量重放该报文,并且设置password为payload如图11所示。

bce4f67ed2429cecce236cbdbb9dff93.png

图11利用爆破测试验证码更新

其中第一行为访问的序号,第二行为报文中作为变量的payload值,其中第20个payload为我设置的密码。第三行为返回报文的状态值。最后一行为返回的报文的长度。

根据只有一个返回的长度为954和返回的状态码302可以确认登录成功,既验证码可以重复使用。

漏洞验证:

第一步:获取后台登陆模块的基本功能相关的黑盒测试信息。内容如图12所示。

baedda43e69b07f45b8a9558a6695a70.png

图12获取登陆页面请求数据

第二步:确定基本逻辑无误的情况下检查相关源码。需要注意的是,这里如何检查就需要依据通读源码或者理解核心源码进行确定。(因篇幅有限,无法展示通读源码成果,特此说明。)

追踪访问后台登陆文件。/admin/login.php,其登陆模块的主要功能实现如图13所示。

b5d63a16f880cb0cfd89712e12452405.png

图13Login.php文件主要内容

这里可以发现如下代码:

get_cookie('adminname')==''? $code=getform('code','post','code')

该代码中与验证码唯一相关的函数为getform函数。那么追踪getform()函数。在/inc/zzz_main.php第656行找到getform方法。Getform函数实现如图14所示。

7a6251107ef5017cf196f0e424807010.png

图14getform方法的实现

根据以上login.php中的函数的参数可以得知,$code的内容最终会通过692行进入checkstr函数中去。这里继续追踪该函数。该方法依然在/inc/zzz_main.php文件中。主要内容如图15所示。

f194ba04d13bd513d198dc016f9da8bc.png

图15验证码验证逻辑

发现checkstr的代码逻辑是如果满足传输过来的类型为“code”的时候使用_SESSION进行验证码验证。继续追踪该函数。内容如图16所示。

7a774259c618fbc3520cc684164a3076.png

图16_SESSION方法的实现

_session函数在确定验证码的正确性之后未及时的销毁session导致session可以复用,造成验证码绕过漏洞。完整运行逻辑如图17所示。

0c21e0e61e62390209e5bbc8f1023545.png

图17完整验证码的验证逻辑

该漏洞更大的危害是在密码找回功能处,可能出现任意密码重置问题(漏洞成因:在手机接收的验证码长度小于6的时候,利用数据包重放,且页面验证码可以重复利用的情况下爆破手机验证码)。

逻辑分析法主要的优点有:①可以发掘非危险函数产生的漏洞。②漏洞发现的准确率高,并且具有较强的针对性。③结合黑盒、白盒、灰盒的测试方式能够覆盖到几乎全部类型漏洞。

逻辑分析法的主要缺点:①审计前期需要完整读懂项目代码,审计准备实践过长。②功能测试内容繁多,容易漏测或者测试不完全,导致漏洞被忽略。

5

结 语

本文针对php代码审计技术做了综合性的介绍。从白盒审计和黑灰盒审计两个方面演示了审计流程,挖掘到了具体的漏洞。也通过代码逻辑说明了产生漏洞的具体原因。这种漏洞挖掘模式既能有效的挖掘出危害信息系统的漏洞,也能有效的指导信息系统的开发人员写出安全的代码。

作者简介<<

陈艺夫:助教,主要研究方向为信息安全。

选自《通信技术》2019年第十一期(为便于排版,已省去原文参考文献)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值