安全攻防
morning
pocsuite3安全工具源码分析
2026-05-08
1 阅读
蚁景网安实验室
pocsuite3 是由 知道创宇 404实验室 开发维护的开源远程漏洞测试和概念验证开发框架。为了更好理解其运行逻辑,本文将从源码角度分析该项目的初始化,多线程函数,poc模板等等源码。 项目结构 api:对要导入的包重命名,方便后续导入调用data:存储用户需要使用的文档数据lib:项目核心代码modules:存储用户自定义的模块plugins:存储用户自定义的插件pocs:存储poc文件shellcodes:存储生成php,java,python等脚本语言的利用代码,以及反弹shell的利用代码cli.py:项目的入口console.py:命令行界面 进入项目入口:/pocsuite3/cli.py check_environment() #检查当前工作目录是否符合当前系统set_paths(). #设置后续需要用到的数据,目录信息banner() #打印命令行页面的横幅 init_options(cmd_line_parser(). dict ) # 命令行参数处理跟进cmd_line_parser()查看: 此处注意一个参数-c target.add_argument("-c", dest="configFile", help="Load options from a configuration INI file") 可以先在pocsuite.ini配置好参数,通过pocsuite -c pocsuite.ini 运行 双重跟进init_options(),找到命令行存储参数: 可见采用了类似字典的形式存储,避免了重复数据且还有其它四个参数也采用了该形式存储,五个参数贯穿整个项目 conf:存储基本配置信息kb:存储了目标地址、加载的PoC、运行模式、输出结果、加载的PoC文件地址、多线程信息等cmd_line_options:是存储命令行输入的参数值merged_options:存储输入值与默认值合并后的结果paths:存储数据、插件、poc等目录地址 参数获取处理完后,进入项目初始化,init()函数,一下对部分函数进行注解分析: def init(): """ Set attributes into both configuration and knowledge base singletons based upon command line and configuration file options. """ set_verbosity() #日志输出级别设置 _adjust_logging_formatter() #调整日志格式器 _cleanup_options() #将各个配置项格式化,并校验合法性 _basic_option_validation() #校验seebug,zoomeye等api,token的合法性 _create_directory() #检测文件路径是否存在,不存在则创建 _init_kb_comparison() update() _set_multiple_targets() #读取目标 _set_user_pocs_path() _set_pocs_modules() #动态加载poc _set_plugins() #动态加载插件 _init_targets_plugins() _init_pocs_plugins() _set_task_queue() #初始化多线程设置 _init_results_plugins() #初始化输出插件 AttribDict类解析 前文也提到过以下五个全局变量,它们均通过创建AttribDict类的实例进行使用,现在我们跟进类详细分析: AttribDict()类: 自定义类,继承自python内建的OrderedDict类,扩展访问方式,简化了对字典键的访问。主要存在三个方法: getattr (), setattr (), delattr ()这三个方法在if判断逻辑均相同:1:以双下划线 __ 开头(例如,Python 的内置属性,如 dict )。2:以 _OrderedDict__ 开头(因为 OrderedDict在内部实现中使用的名称)。3:名字存在于 exclude_keys 集合中(排除的键)。如果任一条件成立,说明这个属性不应该通过 obj.attr访问,所以跳过使用自定义的 getattr 处理,直接调用父类对应的方法访问。例: getattr ()就调用父类的 getattribute ()访问 如果属性名不满足,则通过字典的方式,添加或者删除AttribDict中 地址处理代码分析 先查看存储初始数据,存在则进行下一步。通过set()创建集合方便去重,再遍历conf.url数据,通过parde_target()进行