分析版本:pocsuite3-1.9.6
pip直接安装会附带两个可执行文件,pocsuite
对应CLI方式启动,poc-console
对应msf类型的console方式启动
可以从setup.py
和可执行文件源码中发现其实就是运行对应的python文件的方法
分析CLI模式,大概流程非常简单清晰,检查环境->初始化配置->start开始扫描任务
初始化配置
检查环境这个其实就是判断下是否安装在非全英文目录
pocsuite
模仿sqlmap
使用了AttribDict
来存储配置,更改了配置字典的使用方法,方便配置和更改
1 | This class defines the sqlmap object, inheriting from Python data |
原来的字典的用法:dict1["key"]
,现在的自定义字典的用法:dict1.key
配置文件在pocsuite3/lib/core/data.py
这里使用了模块实现了单例模式,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc
文件,当第二次导入时,就会直接加载 .pyc
文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了
set_paths(root_path)
设置路径信息
通过argparse
解析参数,AttribDict
传递配置
这里的配置在其注释里描述的已经很清晰,conf
存储共享的配置和对象,kb
存储目标、注册的POC、扫描的模式、扫描结果等。cmd_line_options
存储原始的命令行配置,merged_options
对应覆盖后参数配置,paths
对应路径信息
自定义了一个输出函数,会根据quiet
的设置判断是否输出,同时做了字符编码、添加颜色的处理,输出使用的是sys.stdout.write
而不是print
这里查了一下print
会多输出一个\n
,这样输出的样式会更好控制一点
init()
里关键的_set_pocs_modules
,pocsuite3/lib/core/option.py
遍历pocs目录加载poc,并判断poc是否匹配条件,最后是调用load_file_to_module
去加载poc。这里可以看到之后pocsuite想要直接从pyc文件加载poc,同时这里有从seebug漏洞库加载poc的提示,但是只是提示,实际的实现逻辑并不是在这
pocsuite3能够从本地和远程网站上加载poc,可以直接用__import__()
来加载,但是如果要远程加载,需要自己实现”查找器”与”加载器”,可以参考
https://docs.python.org/zh-cn/3/reference/import.html
这里加载了名为pocs_xxx
的模块
加载的过程,obj
即对应poc文件的源代码,每个poc文件最后都执行register_poc(xxx)
,这里其实就是实例化poc模块,然后放在kb.registered_pocs
里
远程加载的逻辑以poc_from_seebug.py
插件为例从seebug漏洞库加载poc的逻辑大概即获取到poc的源代码后通过load_string_to_module
加载
开始扫描
遍历target和注册的poc存入task队列
这里多线程使用生产者/消费者模型,多个线程来消费一个队列,并没有使用Python线程中推荐的join()
来阻塞线程,因为使用join()
的话,python将无法响应用户输入的消息了,会导致Ctrl+C退出时没有任何响应,所以以while循环的方式来阻塞线程
task
run** 函数里最终会调用poc模块父类POCBase的execute 方法,execute 调用**_execute
最后即调用到poc里对应的方法
最后output
是一个AttribDict
,存于kb.results