一、审计前的踩坑记录
1.要在php版本中安装一个sg11的拓展,否则是打不开。另一个是网站想正常显示需要增加一个控制器域名,但是呢我是搭建在本地不允许出现数字。所以要去数据库中web_domain表里加上就行。
- 因为后面想查看sql语句,想布一个mysql数据库监控,将数据库权限改为可远程连接。
改了也是不行,后来猜测是端口放行问题。
成功解决,可以使用navicat连接,但是数据库监控工具还是连不上。换了好几款也没有用。
在配置文件加上开启日志保存功能吧,也可以直观看到SQL语句的执行情况。
general_log
general_log_file = /tmp/fy.log
- 最后一个就是路由问题啦,这个我推荐是黑盒白盒一起看,在网站随便抓个包然后再去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());
}
}