Pocsuite3源码实现浅析 插件调用流程
瞎看一通后发现了一篇文章:https://paper.seebug.org/913/
Pocsuite3 是由知道创宇404实验室打造的一款开源的远程漏洞测试框架,我之前并没有怎么使用过,这几天学习了一下它的源码,当然我非常菜,只是简单记录一下自己而已。
Pocsuite3核心功能就是加载插件并执行验证漏洞,当然它提供了丰富的执行模式,例如调用zoomeye,shodan、生成shellcode、调用api验证dns和http请求等,以及拥有一个强大的漏洞库和贡献poc的社区。
程序入口在pocsuite3/cli.py,也可以通过console.py实现命令行交互模式。
程序执行比较繁杂,我简化了执行逻辑如下。简化后的程序逻辑十分直观。
from pocsuite3.lib.core.register import load_file_to_module from pocsuite3.lib.core.datatype import AttribDict from pocsuite3.lib.core.data import kb, conf kb.registered_pocs = AttribDict() conf.ipv6 = False load_file_to_module("pocs/thinkphp_rce2.py") poc_module = kb.registered_pocs["pocs_thinkphp_rce2"] result = poc_module.execute("http://127.0.0.1") output = AttribDict(result.to_dict()) print(output)
首先Pocsuite3模仿了sqlmap实现了AttribDict来存储和返回数据,加载的插件会存储在kb.registered_pocs里面。
加载插件的方法位于pocsuite3/lib/core/register.py的load_file_to_module方法
加在插件通过importlib类实现,示例如下。
import importlib.util def import_source(module_name): module_file_path = module_name.__file__ module_name = module_name.__name__ module_spec = importlib.util.spec_from_file_location(module_name, module_file_path) module = importlib.util.module_from_spec(module_spec) module_spec.loader.exec_module(module) print(dir(module)) msg = 'The {module_name} module has the following methods: {methods}' print(msg.format(module_name=module_name, methods=dir(module))) if __name__ == '__main__': import os import_source(os)
加载插件后会执行末尾的register_poc方法,该方法将插件poc类实例化传入kb.registered_pocs里。
然后执行位于pocsuite3/lib/core/poc.py的插件父类POCBase的execute方法,execute调用_execute方法,通过传入参数判断执行payload的方式,验证漏洞或者是获取shell等。
def _execute(self): if self.mode == 'shell': if not hasattr(self, "_shell"): raise NotImplementedError output = self._shell() elif self.mode == 'attack': output = self._attack() else: output = self._verify() return output def execute(self, target, headers=None, params=None, mode='verify', verbose=True): self.target = target self.url = parse_target_url(target) if self.current_protocol == POC_CATEGORY.PROTOCOL.HTTP else self.build_url() self.headers = headers self.params = str_to_dict(params) if params else {} self.mode = mode self.verbose = verbose self.expt = (0, 'None') # TODO output = None try: output = self._execute() except NotImplementedError as e: self.expt = (ERROR_TYPE_ID.NOTIMPLEMENTEDERROR, e) logger.log(CUSTOM_LOGGING.ERROR, 'POC: {0} not defined "{1}" mode'.format(self.name, self.mode)) output = Output(self)
然后返回的原始结果如下。
AttribDict([('error_msg', (0, 'None')), ('result', {'VerifyInfo': {'URL': '/index.php?s=captcha', 'Postdata': '_method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=1'}}), ('status', 1), ('url', 'http://127.0.0.1'), ('mode', 'verify'), ('vul_id', '97767'), ('name', 'Thinkphp 5.0.x 远程代码执行漏洞'), ('app_name', 'thinkphp'), ('app_version', 'thinkphp5.0.23')])
接着看插件的编写,插件继承自POCBase类,开头定义poc各种信息,id、作者、时间、版本等。
_verify方法为实现漏洞验证的方法,_attack即为攻击,_shell即为反弹shell之类的操作
插件内register_poc方法为加载插件时候进行实例化类并传入定义的AttribDict的操作。
def register_poc(poc_class): module = poc_class.__module__.split('.')[0] if module in kb.registered_pocs: kb.current_poc = kb.registered_pocs[module] return kb.registered_pocs[module] = poc_class() kb.current_poc = kb.registered_pocs[module]
值得注意的是pocsuite3对一些引用包进行了简单修改,例如在pocsuite3/lib/request对requests删除了ssl验证和警告消息以及重写了一些方法实现Network request options功能,具体我也没仔细看。
最后简化代码,简单修改删除了AttribDict和插件内的register_poc方法等,自己基于Pocsuite3的逻辑代码实现了简单的插件调用执行验证漏洞返回python字典结果,当然这样做并没有什么意义。
标签: Pocsuite
你是衣冠楚楚的人 而我只是一个打满补丁的猴子
-
小博客一个,没必要伤害她
热门文章
存档
标签
最新评论
- yz
想想你喜欢什么,想做什么,找好一个自己的... - 小屿
@Jahan:testfun1024#p... - Jahan
Hello dear Xia0 i a... - brave
@万:你的手机应该是anroid7.0以... - jhsy
新版的cookie机制应该又变了. 而且... - 小屿
@janto:无兴趣 - janto
新版的这些好像不起作用了,deviceI... - hunk
正在研究,可否发一份新源码?todz$1... - miffy
请问可以加个好友咨询下吗? - vegetableChicken
@Snkrs:我也遇到和你一样的问题了,...
发表评论: