• 新闻动态
  • 行业动态
  • 公司新闻
  • 关于我们
  • 公司简介
  • 经典活动
  • Web
    代码审计入门实战
    2020-02-24 15:52

    前段时间在整理一个PHP函数代码审计的项目,所以文章也是围绕PHP的代码审计来写,如果有写的不对的地方,还请大佬们指正。

    前段时间在整理一个PHP函数代码审计的项目,所以文章也是围绕PHP的代码审计来写,如果有写的不对的地方,还请大佬们指正。文章开始前,我们先来了解一下PHP是什么。

    0x01 PHP是什么

    根据百度百科的描述,PHP是一种在服务器端执行的通用开源脚本语言,主要适用于Web开发。

    既然是网站编程语言,自然需要一款工具辅助程序员高效编程。PhpStorm就是一款PHP集成开发工具,可以随时帮助程序员对代码进行调整、运行单元测试、且提供可视化debug功能。

    当然也可以使用其他工具对PHP程序进行调试,比如Xdebug,一款开放源码的PHP debug工具,用来跟踪、调试和分析PHP程序的运行状况。

    大家可以通过学习这个实验,掌握PhpStorm环境搭建和Xdebug工具的安装和配置:

    1.png

    实验地址:http://www.hetianlab.com/expc.do?ec=ECIDc27f-481e-40ca-ad80-921e29487d65

    网传这么一个段子:如何让一个论坛的人吵起来?答:PHP是世界上最好的语言。这个梗出自PHP的官方文档,最早出现在2001年7月的PHP文档中。虽然有PHP是世界上最好的语言这种说法,但是也有一些因为弱类型语言的安全性问题出现,这就需要安全人员通过代码审计来检查PHP程序的安全性。

    0x02 代码审计又是什么

    代码审计,顾名思义就是检查源代码中的安全缺陷。通过自动化工具或人工审查的方式,对程序源代码逐条进行检查和分析,发现源码缺陷引发的安全漏洞,有时还需要提供代码修订措施和修复建议。

    软件的源代码、程序缺陷可能导致严重的安全漏洞,要消除代码中的漏洞、减少不必要的补丁升级,就需要进行源代码的安全审计。源代码审计是对代码库和软件架构的安全性、可靠性进行全面的安全检查。人工审查已经成为软件源码设计、开发和应用的最佳保障,因此做好代码审计就是从安全的角度对整个代码质量进行评估。安全人员需要在黑客发现系统漏洞之前,找出应用的安全隐患,并提供相应的安全报告和修复方法,从而提高应用系统的安全性。

    除了人工审查的方式,还可以通过一些自动化工具进行代码审计,下面简单介绍两种代码审计利器:

    1、  Seay源代码审计系统

    这是一款针对PHP代码安全审计的系统,基于C#语言开发,主要运行于Windows系统上。这款软件能够发现SQL注入、代码/命令执行、文件包含、文件上传、拒绝服务、XSS、信息泄露、任意URL跳转等漏洞。关于Seay源代码审计系统工具的使用,可以通过下面的实验进行学习:

    2.png

    实验地址:http://www.hetianlab.com/expc.do?ec=ECIDed58-7789-4897-a8cf-8d332411e6db

    2、  RIPS

    RIPS通过标记和解析所有源代码文件,自动检测PHP应用程序中的漏洞。RIPS能够将PHP源代码转换为程序模型,检测程序流期间用户输入可能污染的敏感接收器,即潜在易受攻击的函数。RIPS工具的使用参考下面的实验:

    3.png

    实验地址:http://www.hetianlab.com/expc.do?ec=ECIDb9ac-4540-46b4-b676-22df36b5935b

    学习了代码审计的常用工具,相信大家会对代码审计的方法和步骤有一定的了解,那么接下来简单总结一下代码审计的流程:

    ①  通读全文代码:更好地了解程序的架构及业务逻辑,挖掘更多高质量的漏洞;

    ②  通读敏感功能点:快速挖掘某种漏洞;

    ③  正向追踪可控变量;

    ④  敏感关键字回溯参数传递过程。

    下面进入文章的重点部分——PHP函数的代码审计,通过具体实例分析PHP部分函数,包括in_array函数、filter_var函数、escapeshellarg与escapeshellcmd函数、parse_str函数及addslashes函数,学习上述函数缺陷引发的漏洞及利用方式,结合CTF练习掌握PHP函数漏洞审计流程。

    0x03 PHP函数的代码审计

    项目来自https://github.com/hongriSec/PHP-Audit-Labs

    这里我们根据《PHP函数漏洞审计》课程顺序进行学习。

    一、PHP代码审计之in_array函数

    既然是对in_array函数进行具体分析,我们先来了解一下in_array函数的相关定义:

    注:后面说到的函数定义均来自PHP手册,手册地址:http://php.net/manual/zh/index.php


    4.png

    $needle变量表示待搜索的值,$haystack表示待搜索的数组。in_array函数用法为:在$haystack数组中搜索$needle变量的值,检查值是否存在。如果第三个变量$strict的值为true,则in_array函数会进行强检查,检查$needle的类型是否和$haystack数组中的相同。

    in_array函数为什么会存在漏洞呢,原因是程序员在使用in_array函数进行数据处理时,未使用第三个参数进行严格匹配,比如Piwigo软件2.7.1版本就是因为in_array函数的不安全使用,导致SQL注入漏洞发生。

    查看源码/picture.php文件可以发现,当$_GET[‘action’]为rate时,会调用文件/include/function_rate.inc.php文件中的rate_picture方法,漏洞就存在于这个方法中:

    5.png

    而在rate_picture方法中,使用了in_array函数对$rate变量进行检测,判断$rate是否在$conf['rate_items']中:

    111.png

    由于functions_rate.inc.php文件中没有将in_array函数的第三个参数设置为true,所以会进行弱比较,可以将$rate的值设置成1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));#进行绕过。

    那么SQL语句就变成:

    INSERT INTO piwigo_rate(user_id,anonymous_id,element_id,rate,date) VALUES (2,'192.168.2',1,1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));#,NOW())

    这样就可以进行盲注了。

    直接利用sqlmap进行漏洞利用:

    python sqlmap.py -u "http://10.1.1.79/piwigo/picture.php?/1/category/1&action=rate" --data "rate=1" --dbs

    6.png

    还可以用sqlmap获取目标数据库的表及敏感数据。

    总结一下in_array函数的审计流程:

    7.png

    大家可以访问下面的链接,学习in_array函数缺陷引发的相关漏洞及其利用方式:

    http://www.hetianlab.com/expc.do?ec=ECID1ead-872b-4ec9-b7f4-ba4b2e97fe41

    8.png

    二、PHP代码审计之filter_var函数

    filter_var函数定义:

    9.png

    $variable变量表示待过滤的变量(变量的值在过滤前,会被转换成字符串),$filter变量表示要应用的过滤器的ID,$options变量代表一个选项的关联数组或按位区分的标识。filter_var函数返回过滤后的数据,过滤失败则返回false。

    这里以一个CTF练习介绍filter_var函数缺陷引发的漏洞可以怎么利用,题目考察filter_var函数的绕过与远程命令执行。题目源码为:

    0.png

    程序使用exec函数来执行curl命令,很容易让人联系到命令执行。可以看到用于拼接命令的$site_info变量是从用户传来的url参数,经过filter_var和parse_url两个函数过滤而来。之后又规定当url参数的值以hetianlab.com结尾时,才会执行exec函数。

    这就需要绕过filter_var和parse_url函数,并且需要满足$site_info['host']的值以hetianlab.com结尾,然后通过执行系统命令获取flag。

    Payload为/ctf/index.php?url=demo://%22;ls;%23;hetianlab.com:80/

    11.png

    直接用cat f1agi3hEre.php命令过不了filter_var函数检测,因为包含空格,使用如下payload获取flag:/ctf/index.php?url=demo://%22;cat<f1agi3hEre.php;%23;hetianlab.com:80/

    12.png

    总结一下filter_var函数的审计流程:

    13.png

    PHP代码审计之filter_var函数实验的学习地址:http://www.hetianlab.com/expc.do?ec=ECIDd59c-36b2-455e-833d-7e8c5dc92a17

    14.png

    三、PHP代码审计之escapeshellarg与escapeshellcmd函数

    先看一下两个函数的相关定义,escapeshellarg函数:

    15.png

    $arg变量表示需要被转码的参数,函数返回值为转码之后的字符串。

    escapeshellcmd函数:

    16.png

    $command变量代表要转义的命令,函数返回值为转义后的字符串。

    以一个由PHP内置函数mail,结合escapeshellarg与escapeshellcmd函数所引发的命令执行漏洞为例,代码如下:

    17.jpg

    第4行代码的作用是确保只使用有效的电子邮件地址$email,filter_var函数用于使用特定是过滤器过滤一个变量。PHP的mail函数在底层实现中,调用了escapeshellcmd函数,对用户输入的邮箱地址进行检测。即使存在特殊符号,也会被escapeshellcmd函数处理转义,无法达到命令执行的目的。第6行代码的作用是处理$email传入的数据,而escapeshellarg和escapeshellcmd两个函数一起使用,会造成特殊字符逃逸,导致远程代码执行。

    PHPMailer命令执行漏洞(CVE-2016-10033)也是利用escapeshellarg和escapeshellcmd两个函数结合使用,导致了单引号逃逸。具体的漏洞分析和利用过程可以通过下面这个实验进行学习:

    18.png

    学习地址:http://www.hetianlab.com/expc.do?ec=ECID2117-c828-49a4-89bf-b5f362976166

    总结一下escapeshellarg与escapeshellcmd函数的审计流程:

    19.jpg

    四、PHP代码审计之parse_str函数

    同样先了解parse_str函数的相关定义:

    20.png

    $encoded_string变量代表输入的字符串,如果设置了第二个变量result,变量将会以数组元素的形式存入数组,作为替代。

    下面简述parse_str函数缺陷引发的变量覆盖漏洞,代码如下:

    21.png

    由于第22行parse_str()调用,其行为非常类似于注册全局变量,通过提交类似config[dbhost]=127.0.0.1这样的数据,因此可以控制getUser()中第6到第9行的全局变量$config。如果目标存在登录验证的过程,就可以通过变量覆盖的方法,远程连接我们自己的MySQL服务器,从而绕过登录验证进行下一步攻击。一个简单的例子:

    22.png

    直接覆盖了原有的变量$b。

    parse_str函数还有一个有意思的CTF练习,首先利用PHP哈希比较缺陷,构造请求参数,使其经过哈希之后,值是以’OE’开头。缺陷就是如果两个不同的密码经过哈希之后,其哈希值都是以'OE'开头,PHP将会认为它们结果都为0。请求后页面会出现‘flag is here’,点击跳转至flag.php。题目真正的考察点在于flag.php存在一个refer判断,判断refer是否存在,如果存在则展示上传页面,否则返回‘you can not see this page’。接下来的部分存在时间竞争问题,需要在写入too slow之前访问之前写入的文件,才能获取flag。

    此题的解法是开burp的200线程不断发包,在start attack之前写一个脚本不断请求写入文件的路径,是变量覆盖与竞争条件漏洞的结合利用。

    CTF练习地址:http://www.hetianlab.com/expc.do?ec=ECIDb63c-5d84-4073-aa26-353052390460

    23.png

    总结一下parse_str函数的审计流程:

    24.png

    五、PHP代码审计之addslashes函数

    addslashes函数相关定义:

    25.png

    $str表示要转义的字符,当我们要往数据库中输入数据时,例如将名字O’reilly插入到数据库中,就需要对其进行转义。

    以一个用户登录程序为例,考察通过SQL注入绕过登录验证,代码如下:

    26.jpg

    第29行通过POST方式传入user和passwd两个参数,通过isValid函数判断是否合法。isValid函数主要功能代码在第10~20行,调用sanitizeInput方法对user和passwd进行相关处理。sanitizeInput方法主要功能代码在第22~25行,针对输入的数据调用addslashes函数进行处理,然后对处理后的内容进行长度判断,长度大于20则只截取前20个字符。

    这道题已经过滤了单引号,正常情况是没有注入了,为什么还能导致注入呢?原因实际上出在第24行substr函数这里,下面简单看一下substr函数的定义:

    27.png

    substr函数的参数说明:string表示输入的字符串(至少有一个字符),如果start为非负数,返回的字符串从string的start位置开始,从0开始计算;如果start为负数,返回的字符串从string结尾处向前数,从第start个字符开始。

    注:如果string的长度小于start,将返回false。

    length:如果length为正数,返回的字符串将从start处开始,最多包括length个字符(取决于string的长度);如果length为负数,string末尾处的length个字符将会被省略(若start是负数则从字符串尾部算起);如果length为0、false或null,则返回一个空字符串;如果没有提供length,返回的字符串将从start位置开始,直到字符串结尾。

    关于substr函数一个简单的例子:

    28.png

    substr中的参数0代表从位置为0的字符开始计算,2代表返回的字符串将从0(start)处开始最多包括2(length)个字符。

    再回到题目中,我们知道反斜杠可以取消特殊字符的用法,而注入想要通过单引号闭合,必然会引入反斜杠。将官方提供的payload带入题目中,拼接第15~17行代码中的SQL语句:select count(p) from user u where user = ’1234567890123456789\’ AND password = ‘$pass’

    这里的SQL语句由于反斜杠的原因,user=’1234567890123456789\’最后这个单引号会失去它的作用,我们让password=or 1=1#,那么最后的SQL语句为:select count(p) from user u where user = ’1234567890123456789\’ AND password = ‘or 1=1#’

    此时user值为1234567890123456789\’ AND password =,可以保证带入数据库执行的结果为true,就能顺利地通过验证。因此使用形如user=1234567890123456789’&passwd= or 1=1#的payload即可逃逸出\(反斜杠)注入。

    苹果CMS视频分享程序8.0版本也曾爆出过SQL注入漏洞,程序调用addslashes函数对反斜杠进行转义处理,但是对用户请求的参数又会进行url解码,因此可以使用双url编码绕过addslashes函数,触发漏洞。

    具体的漏洞分析过程可以通过下面的实验进行学习:http://www.hetianlab.com/expc.do?ec=ECIDbc29-1b6f-4392-af74-fe7473b1d6e9

    29.png

    总结一下addslashes函数的审计流程:

    30.png

    0x04 总结

    除了上面提到的,PHP还有很多常见危险函数,也有相关的实验方便大家了解PHP常见的危险函数,以及使用这些函数可能导致的漏洞。实验地址:http://www.hetianlab.com/expc.do?ec=ECID9d6c0ca797abec2017051115373800001

    31.png

    代码审计重在分析、重在坚持。文章看到最后,相信大家对代码审计这个名词不再陌生,学习完上述所有的实验,再上GitHub找几个代码审计的案例源码练练手,差不多就算入门了。安全学习贵在实践、贵在总结,还记得文章一共提到了哪些实验吗,还等什么,点击链接直接前往合千赢官方下载安实验室进行学习啊!

    上一篇:浅析一个二进制结合Web的漏洞利用典范
    下一篇:某团购CMS的SQL注入漏洞代码审计
    版权所有 合天智汇信息技术有限公司 2013-2020 湘ICP备14001562号-6
    Copyright © 2013-2020 Heetian Corporation, All rights reserved
    4006-123-731