记录一次tp框架下的代码审计

一、审计前的踩坑记录

1.要在php版本中安装一个sg11的拓展,否则是打不开。另一个是网站想正常显示需要增加一个控制器域名,但是呢我是搭建在本地不允许出现数字。所以要去数据库中web_domain表里加上就行。

  1. 因为后面想查看sql语句,想布一个mysql数据库监控,将数据库权限改为可远程连接。

改了也是不行,后来猜测是端口放行问题。

成功解决,可以使用navicat连接,但是数据库监控工具还是连不上。换了好几款也没有用。


在配置文件加上开启日志保存功能吧,也可以直观看到SQL语句的执行情况。

general_log
general_log_file = /tmp/fy.log

  1. 最后一个就是路由问题啦,这个我推荐是黑盒白盒一起看,在网站随便抓个包然后再去app下的目录观察即可得知第一层是app下的目录然后是xxxControl.php的名字,最后一层是代码里的方法。

二、前台SQL注入漏洞

在这套tp框架里传参是靠$x=post('x');传进来的,而且搜了下没有get方式传参。直接全局过滤寻找可控点。

因为经验不足并不太懂thinkphp,通过观察监控的日志发现where方法会对单双引号就行转义处理,但是在测试的时候app\user\OrderController.php的getData方法中的$where['raw']并未对字符进行转义,通过查询资料获知在 ThinkPHP 的 Db 类或其他类似的数据库查询构建器中,当你使用 ['raw' => ...] 的形式时,你实际上是在告诉查询构建器:“这个部分是一个原始的 SQL 片段,不要对其进行任何额外的处理或转义。

$orderData = post('orderData');
$orderValue = post('orderValue');
$orderCode = post('orderCode');
$goodsId = post('goodsId');
$date = post('date/a');

$where['tb.web_id'] = request()->webId;
$where['tb.order_uid'] = $userInfo['id'];
//    $where['tb.pay_status'] = 1;
if (!empty($orderId)) {
    $where['tb.order_id'] = $orderId;
}
if (!empty($orderValue)) {
    $where['order_value'] = ['like', '%' . $orderValue . '%'];

}
if ($orderCode != '') {
    $where['order_code'] = $orderCode;
}
if ($goodsId) {
    $where['order_gid'] = $goodsId;
}
if (!empty($date) && count($date) > 1) {
    $where['tb.create_time'] = ['between time', [$date[0], $date[1]]];
}
if ($orderData) {
    $where['raw'] = 'tb.order_id= "' . $orderData . '" or tb.order_value like "%' .

直接使用报错注入即可。

刚开始审的时候其实没那么顺利,不明白为啥代码里是双引号闭合但是实际还需要括号,通过翻查手册和日志得以解惑。

知道这个之后直接过滤存在可控点的部分,又得到两处前台SQL注入

第二处在app\im\LayimController.php的getMessagePage方法,不过这个要稍微看下源码,它需要一个type参数走进friend判断才行

第三处在app\index\chadan\ChadanController.php的queryOrderPage方法

通过SQL注入得到的密码是加密的,找到登陆处追踪encrypt()方法

发现在这个方法中实例化了SM4(),而且得到了加密的key

直接在调用下解密的decrype()方法就可以了

$ssm4 = new SM4();
$keykey = "xiaoyewl";
$pass_sm4 = $_GET['pass'];
echo "明文密码是: ".$ssm4->decrypt($keykey,$pass_sm4);

三、后台任意文件上传漏洞

通过Seay工具定位到VersionController.php处存在file_put_contents()文件写入函数。此功能点是解压上传的压缩包,通过观察是网站的升级功能。

是将上传的升级压缩包解压,可以看到第343行获取到了压缩包内文件的路径和名称,$path可以忽略因为调用的时候就没有被传入参数,然后在357行写入。

因为tp框架的运行目录在public目录下,所以新建一个名为public的文件夹,里面放一个马子,马子这里我用的冰蝎马,常规的webshell会被检测。

本套源码处理上传都使用了FileService类去处理,这里处理上传的方式基本都如下,使用了白名单的后缀名和MIME类型检测,符合要求才可以上传。

$file = request()->file($fileTypeName);

if ($checkFileVailDate) {
    try {
        $fileExt = ['doc', 'docx', 'xls', 'xlsx', 'zip', 'txt', 'jpeg', 'jpg', 'png', 'gif', 'pdf', 'mp4' . 'mp3', 'exe', 'apk'];
        $fileMime = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/x-zip-compressed', 'text/plain', 'image/jpeg', 'image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'video/mp4' . 'audio/x-mpeg', 'application/octet-stream', 'application/vnd.android.package-archive'];
        validate(['imgFile' => ['fileExt' => implode(",", $fileExt), 'fileMime' => $fileMime]])->check(['imgFile' => $file]);
    } catch (\Exception $e) {
        alert_error($e->getMessage());
    }
}
1 条评论
某人
表情
可输入 255
目录