PHP代码审计之旅
2020-07-16 10:50:15 Author: xz.aliyun.com(查看原文) 阅读量:537 收藏

前言:

之前做了很多web题都遇到过审计代码的题目,命令执行、变量覆盖等。但如果这些代码是分布在一套源码中(如CMS),需要我们去发现,去找到并会利用,就需要有一定的查找以及利用思路,这次测试的是BlueCMS1.6,重要不在于去复现这个CMS的漏洞,而在先了解一下整个审计思路还有过程是怎么样的,去锻炼自己的审计能力。由于我比较菜,所以有错误的地方也请师傅们指正。

何为白盒、黑盒、灰盒测试

审计代码会经常遇到这三个名词,这又代表是什么意思那?

  1. 黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。
  2. 白盒测试:已知产品的内部工作过程,可以进行测试证明每种内部操作是否符合设计规格要求,所有内部成分是否经过检查。
  3.  灰盒测试更像是白盒测试和黑盒测试的混合测试,现阶段对灰盒测试没有更明确的定义,但更多的时候,我们的测试做的就是灰盒测试,即既会做黑盒测试又会做白盒测试。

    其他理解来也很简单,就比如搭建一个网站,黑盒测试是在不知道网站源码的情况下,对各个功能进行测试看看是否有问题,而白盒测试则是知道源码,可以从代码入手,看看代码是否有问题,灰盒测试就是两者混合起来进行测试(个人理解,如有错误请师傅指正),当然这些概念还有更深层的知识,这里就不详细介绍了。

白盒测试流程——BlueCMS1.6

由于初学代码审计,通过BlueCMS1.6来进行练习,这里重点写一些白盒测试如何进行分析

0x00:了解目录结构


看到这么多,怎么入手,思路是怎么去做?直接去找SQL漏洞、RCE等估计有点困难,因为这也太多文件了,我看了很多大师傅们都是先了解一下整个目录结构,这个目录是作用于什么的,包含有哪些文件,找到核心文件,再进行入手,会将审计范围缩小一点而且会节省不少时间。

├── admin     后台管理目录
├── install   网站的安装目录
├── api       接口文件目录
├── data     系统处理数据相关目录
├── include  用来包含的全局文件
└── template  模板

看到以下函数也需要注意:

1) 函数集文件,通常命名中包含functions或者common等关键字,这些文件里面是一些公共的函数,提供给其他文件统一调用,所以大多数文件都会在文件头部包含到它们,寻找这些文件一个非常好用的技巧就是去打开index.php或者一些功能性文件,在头部一般都能找到。

2) 配置文件,通常命名里面包括config这个关键字,配置文件包括Web程序运行必须的功能性配置选项以及数据库等配置信息,从这个文件里面可以了解程序的小部分功能,另外看这个文件的时候注意观察配置文件中参数值是用单引号还是用的双引号包起来,如果是双引号,则很大可能会存在代码执行漏洞。

当然不一样的CMS,会有不同的目录结构,但大多文件夹的名称和对应的功能是不会有多大变化的,谁想在开发的时候整一堆乱起的文件名,到时自己测试都头疼。

0x01:从首页获取信息

了解文件目录后,就先从index.php文件入手,index.php一般是整个程序的入口,通过index文件可以知道程序的架构、运行流程、包含那些配置文件,包含哪些过滤文件以及包含那些安全过滤文件,了解程序的业务逻辑,所以从首页入手是很有必要的。

但index.php这么多行,都要看岂不是太累了,而且没什么用,因为index.php往往不需要获取用户输入,那我们就看这个文件引入了哪些文件,逐层递进。

引入了这两个文件,我们上面提到过一定要注意含有common关键字的文件,打开common.inc.php观察一下

在30多行发现了addslashes() 函数对全局数组POST,GET,COOKIES,REQUEST都进行了转义处理,所以如果我们对包含该文件的文件进行SQL注入就要注意单引号、双引号等会被转义。

又观察到会ban IP,可以了解这个文件主要是写一些通用防护,其他文件引用即可使用

该文件包含了这几个文件,如果到后面遇到看不懂的函数,可以通过跟踪函数名在这些文件中搜索,就这样先浏览一下大致的结构。

当然这里写的不全,只是列出一点,但起码这个层次关系还是多少搞懂点了。include目录下的文件都是通用,就是让文件进行引用减少不需要的代码,从而提高效率,接下来写其他页面就相当于单独写,当需要引用这些文件时,只需引入即可,所以只要知道这些通用文件,当你在查看其他文件时有不懂的函数溯源查看即可明白这些函数的用途,从而继续审计。

0x02:挖掘漏洞

跟踪输入变量

当看到一堆代码时,会有那种不知所措的感觉,那就不妨想象一下一般网站出现漏洞的地方都是在哪里?比如SQL注入、XSS、RCE等会发现有一个共同点,就是用户可以进行输入,有输入的地方就可能存在漏洞,所以这样就有的放矢,在繁多的代码中,就先去找一下那些用户可以控制输入的代码。

从根目录开始,就按照顺序来,先看ad_js.php

$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';

发现ad_id这个参数是可控的,再往下看发现SQL语句

$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

ad_js.php包含有common.inc.php文件,所以我们输入的单、双引号会被转义,但是这里的sql语句中$ad_id是没有单或双引号包裹的,所以根本不需要去关注过滤,很明显这里就存在了sql注入漏洞,先拿小本本记录一下,这个文件含有SQL注入漏洞。

再来查看ann.php,90多行,但我们只去找用户可以进行输入的地方

$ann_id = !empty($_REQUEST['ann_id']) ? intval($_REQUEST['ann_id']) : '';
 $cid = !empty($_REQUEST['cid']) ? intval($_REQUEST['cid']) : 1;

但是经过intval()函数的处理后,便没办法进行SQL注入了,那就换下一个文件

查看news_cat.php文件,发现变量没单双引号但因为intval()函数无法进行SQL注入

再来查看user.php文件中也可能存在SQL注入漏洞,查看一下

同样也是没单双引号而且没进行过滤,应该是可以的,看一下$id是如何传参的

因为intval()函数的处理所以这个SQL注入没办法利用了

利用工具去寻找漏洞

审计PHP代码常用的工具有Seay源代码审计系统rips等,工具有时也会发现一些我们漏掉的地方,所以有时手工和工具同时使用效率会更高,利用Seay源代码审计系统工具发现这么多漏洞,但要注意只是可能存在,有的不一定就是可以利用的。

还是去查找用户能够进行输入的,毕竟一般漏洞都存在于输入的地方,这个工具当你需要溯源的函数,只需全局搜索即可找到

查找危险函数

命令执行 system、shell_exec、passthru、popen、proc_open
文件包含 require、include、require_once、include_once
变量覆盖 parse_str 、mb_parse_str
代码执行 eval、assert、preg_replace
文件操作 file_get_contents 、file_put_contents 、move_uploaded_file 、unlink & delete

这里列举一些各个漏洞对应的危险函数,我们找漏洞无法就是RCE、SQL、文件包含等,那么直接查找这些函数,观察这些函数是否可以利用,不就可以判断出是否存在对应的漏洞了,比如查询一下unlink函数

看到了一个$_POST,进行查看一下内容

存在可以利用的变量$_POST['lit_pic'],追踪一下该变量

发现除了这四个文件含有这个变量,其他文件没有包含有这个变量,除了开头包含文件的转义处理以外,没用其他过滤地方,那就可以通过利用这个变量进行网站根目录下任意文件删除的操作。

0x03:分析漏洞

sql注入漏洞——UNION查询注入

刚才在跟踪输入变量的时候,发现ad_js.php存在一个SQL注入漏洞,现在就来看如何利用这个漏洞

仔细观察这段代码,发现参数是没有任何单双引号,再去查找一下前面包含的这个SQL语句的getone函数,看看我们传入的参数会不会因为这个函数而变化或转义什么的,追踪getone函数,发现在mysql.class.php文件中,功能用于封装为sql语句,并没有什么过滤等

这里啰嗦一下,之所以ad_js.php能调用这个函数,因为包含了common.inc.php,而common.inc.php并非在开头引入了这个文件,而是在62行才引入,所以有的引入不一定就在开头,最好使用工具去查找。

接下来再回到ad_js.php,发现这段代码

echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n";

内容直接回显,这不就是CTF常见的联合查询注入吗?试一下

利用order by查询出一共八列,接下来就联合查询

数据库出来了,7是回显位,这接下来按照联合查询的套路继续走就可以了,这里就不再详细写了

任意文件删除漏洞

这里就涉及到了灰盒测试

在上面提到了user.php文件中存在可控的参数,现在就来详细的来看一下

发现lit_pic这个参数是可以通过POST来进行控制而且没有包括其他的条件,但前面有一个BLUE_ROOT,需要去搞懂它所代表的意思,在文件开头发现:

只是定义一个常量,并没有过滤什么的,所以是可以利用的,那接下来就去利用这个参数,但还有一个问题是在user.php文件下直接POST这个参数吗?还是在来看看源码吧,继续查找发现这个参数是在提交编辑后的分类信息中的


那只需满足该页面下需要传入的参数(填入必须的参数)即可

这里我先创建一个实验的文件text.txt

进行测试

再来看下text.txt,发现已经被删除了

反射型XSS

有的时候工具检测不出来不代表就没有漏洞,有的也需要自己去手动查看,比如在guest_book.php便存在一个反射型的XSS漏洞,但是工具并没有检测出来

在页面发现了用户可以进行留言的地方

查看一下源码发现有点东西的

page_id是通过POST直接传入的,而且查看showmsg这个函数的定义也没有对内容进行任何处理

所以这个漏洞是绝对可以利用的,传入必要的参数即可引起反射型XSS

至于为什么常规的<script>alert(/xss/)</script>不行,观察代码,要想我们的语句起作用,就需要把前面的<input>标签给闭合掉,所以才加上了">

所以工具没测出来的,并不代表就没有漏洞,还是遵循那个原则,有用户可以输入的地方一定要看

总结:

当然还有很多其他的漏洞,这一篇主要是学习代码审计的一些流程步骤,下一篇就专心来审计代码。挖掘漏洞,利用漏洞!

参考博客

Somnus


文章来源: http://xz.aliyun.com/t/7992
如有侵权请联系:admin#unsafe.sh