/pekja

SRC情报收集管理系统

Primary LanguageJavaScript

pekja

SRC 情报收集管理系统。

测试中,Bug 很多,请谨慎使用。。。

简介

在 SRC 漏洞挖掘中情报至关重要,且需要进行持续的情报收集,以达到新资产一上线就被感知的效果。新增的资产往往最容易出现漏洞。 目前已经有了各种各样的情报收集工具,有些专注于某一种情报的收集,如只进行子域名收集,有些则可以收集多种不同的情报。 但不同工具的输出格式五花八门,缺乏一种简单的方式将不同工具的输出整理汇总,并准确找出新增资产。

为了解决这些问题设计开发了 pekja。pekja 可以通过 Web 界面调度运行各个情报收集工具,解析他们的输出,将结果以统一的格式保存到数据库中; 支持将一个工具的输出作为另一个工具的输入;支持通过邮件发送每天新增资产的报告,并提供一些用于查看数据概况和进行调试的Web页面。

技术栈

截图

Web 界面截图

Web界面截图

邮件报告截图

邮件报告截图

支持的工具

在 pekja 中,一个工具只专注于收集一种情报。 若某个工具通过添加不同的参数可以收集不同的情报,则在 pekja 中将它视作多个工具。

不同格式的工具输出格式各不相同,支持一个工具便要有能解析该工具输出的解析类。 目前支持的工具如下表所示。

工具名 收集的情报类型 解析类名 工具项目链接 版本
Nmap SYN 扫描 TCP 端口 NmapSynScanParser Nmap 7.7.0
Nmap UDP 端口扫描 UDP 端口 NmapUdpScanParser Nmap 7.7.0
Censys 邮箱采集 邮箱 CensysEnumerationEmail censys-enumeration 10d42fa3
Sublist3r 域名 Sublist3rParser Sublist3r 61ebf36
OneForAll 子域名收集 域名 OneForAllParser OneForAll 0.3.0
CTFR 域名 CTFRParser CTFRParser 86a804a
lijiejie/subDomainsBrute 域名 LijiejieSubDomainsBrute subDomainsBrute bac5eb3
Censys 子域名采集 域名 CensysEnumerationDomain censys-enumeration 10d42fa3
Nmap 子域名爆破 域名 NmapDnsBruteParser Nmap 7.7.0
Nmap HTTP 扫描 网站 NmapHTTPScanParser Nmap 7.7.0

名词解释

  • SRC:Security Response Center,安全应急响应中心。
  • 记录:一条资产或情报,如一个子域名,一个开放的端口等都可以称做一条记录。

安装

pekja 在 Python 3.8.0 下进行开发和测试。

在调度工具时使用了 Crontab,故不支持 Windows 操作系统。 在 Windows 操作系统中可以正常运行 Web 服务,也可以添加任务。 但只是将需要按时执行的命令写入到data/windows_crontab.txt文件中,并不会真正执行。

有两种安装方法:

  • 使用 Docker 安装:简单快捷。但由于运行在 Docker 中,对服务器配置有一定要求
  • 手工安装:自行手工安装。除了安装 pekja 外还需要逐个安装支持的工具, 安装后还需要逐个核对、修改工具表中各个工具的调用命令(详情见后文),较为耗时耗力,但由于不需要 Docker,对服务器配置要求较低。

方法一:使用 Docker

下载项目代码并进入项目目录:

git clone https://github.com/Werneror/pekja.git
cd pekja

构建 Docker 容器:

docker build -t pekja .

创建数据持久化目录:

mkdir -p /opt/pekja

复制配置文件:

cp docker/env.example docker/env

编辑配置文件env,按实际情况修改其中的配置:

vim docker/env

建议至少修改初始化用户的密码。 若想要使用邮件报告功能,还需修改初始化用户的邮箱地址为真实有效的邮箱地址。 因为邮件报告会发到每个用户的邮箱中。 当然也需要修改用于发送邮件报告的邮箱的相关配置。

运行容器:

docker run -d -p 8000:8000 --env-file docker/env -v /opt/pekja:/opt/pekja/data --restart=always --name pekja pekja:latest

如果需要更新,可运行自动更新脚本:

./docker/update.sh

第一次运行该脚本前可能需要赋予该脚本可执行权限:

chmod +x docker/update.sh

若某次更新改动过大直接使用自动更新脚本可能会失败。 这时需要先通过 Web 界面管理后台的批量导出功能备份数据,然后删除数据目录/opt/pekja中的所有文件,最后再运行更新脚本。 重新导入数据时需按照工具->项目->任务->批量任务->记录的顺序进行。

方法二:手动安装

安装 pekja

下载项目代码并进入项目目录:

git clone https://github.com/Werneror/pekja.git
cd pekja

参考Dockerfile文件安装所有依赖。

复制配置文件:

cp docker/env.example docker/env

编辑配置文件env,按实际情况修改其中的配置:

vim docker/env

运行 Web 服务:

第一次运行该脚本前可能需要赋予该脚本可执行权限:

chmod +x docker/start.sh
nohup ./docker/start.sh &

若安装成功,在浏览器中访问http://127.0.0.1:8000可以看到登录页面,用写在docker/env中的用户可以登录进入 Web 界面。 点击 Web 界面右上角的用户名,在弹出菜单中点击管理后台按钮,可进入到管理后台。

修正工具路径

在管理后台的首页Pekja工具中可以看到目前支持的所用工具。若想使用其中的某个工具, 需根据工具实际路径修改调用命令,确保在 Crontab 中可以成功调用。

工具中各个字段的含义和作用说明如下:

  • 工具名:工具的名字
  • 项目地址:该工具的项目地址
  • 记录类型:该工具收集何种类型的情报
  • 输出解析类:解析该工具输出结果的解析类
  • 调用命令:调用该工具的命令,必须包含{input}{output_file}两个占位符
  • 输入参数类型:
    • 若输入参数类型为文件,则{input}会被替换成文件路径
    • 若输入参数类型为参数,则{input}会被替换为参数本身(后文中有进一步的解释)
  • 版本:推荐的工具版本
  • 备注:备注信息

使用

添加项目

项目用于组织任务记录,每个任务记录都属于且仅属于一个项目

在管理后台的首页Pekja项目中可以查看和添加项目,各个字段的含义和作用说明如下:

  • 项目名:项目的名字,可以是一家公司的名字
  • SRC链接:该项目对应的 SRC 的链接
  • 备注:一些备注信息

添加任务

一个任务是按特定调度以一定输入调用特定工具。

在管理后台的首页Pekja任务中可以查看和添加任务,各个字段的含义和作用说明如下:

  • 任务名:任务名称
  • 所属项目:该任务属于哪个项目
  • 工具:该任务调用的是哪个工具
  • 输入:该任务的输入是什么
  • 输入文件类型:仅工具输入参数类型文件时有效
  • 调度:Crontab 格式的字符串,以说明该任务应该在何时被执行
  • 是否生效:可以选择否以替代删除

每新增一条任务,pekja 都会在 Crontab 中新增一条对应的定时任务, 定时任务的内容是替换了占位符的对应工具调用命令和输入、输出处理命令。 每次保存任务时都会更新 Crontab 定时任务。每次更新工具(表)中工具时也会自动更新所有使用该工具的任务在 Crontab 中对应的定时任务。 但需特别注意通过导入批量导入时不会更新 Crontab 定时任务。

工具输入参数类型参数时,会直接用任务输入替换工具调用命令中的{input}

工具输入参数类型文件时:

  • 任务输入文件类型静态,则将任务输入写入到输入文件中
  • 任务输入文件类型动态,则在每次任务实际运行时查询记录表中属于该项目的所有类型为任务输入的记录,将记录内容写入到输入文件中

用输入文件的路径替换工具调用命令中的{input}

用输出文件的路径替换工具调用命令中的{output_file}。 要求工具将有效输出写入到该文件中,pekja会从该文件中解析有效内容。 还要求工具返回有意义的返回码。

占位符可以出现多次,将都被替换。

输入文件的文件名是input-{任务ID}.txt,输出文件的文件名是output-{任务ID}.txt。 输出文件解析完毕后就会被重命名为output-{任务ID}-{yyyy-MM-d-HH-mm-ss}.txt,不会被自动删除。

所有输出文件和输入文件的路径由pekja/settings.py中的DATA_DIRS定义,默认值是项目目录中data文件夹。

添加批量任务

有时我们希望多个任务能依次执行,但由于我们不知道每个任务执行完毕需要花费多少时间,通过精心设置任务表中的调度也难以实现。 故提供批量任务功能以实现此需求。

在管理后台的首页Pekja批量任务中可以查看和添加批量任务,各个字段的含义和作用说明如下:

  • 批量任务名: 批量任务名
  • 任务1~10: 需要依次执行的任务,最多可添加 10 个
  • 调度:Crontab 格式的字符串,以说明该批量任务应该在何时被执行
  • 是否生效:可以选择否以替代删除

批量任务中的每个任务都是任务(表)中的一个任务。需先在任务(表)中添加任务,才能在批量任务中选择它。 若某个任务只在批量任务中运行,可以在任务表中将它的是否生效设置为否。

每新增一个批量任务,pekja 都会在 Crontab 中新增一条对应的定时任务, 每次保存批量任务时都会更新 Crontab 定时任务。每次更新任务(表)中的任务工具(表)中工具时也会自动更新对应的批量任务在 Crontab 中对应的定时任务。 同样地,需要注意通过导入批量导入时不会更新 Crontab 定时任务。

Web界面

在登录状态下访问http://127.0.0.1:8000/可打开 Web 界面。 Web界面分为前端页面和管理后台两部分。前面介绍了管理后台相关操作,这里介绍各个前端页面。

  • 数据展示
    • 数据面板:显示当前数据概览和过去一周里每日各种类型的记录新增数量曲线图。
    • 时间线:显示每日新增记录,可按项目或记录类型进行全匹配过滤。
  • 系统设置
    • 邮件报告:显示邮件报告的收件邮箱地址和发送定时任务,并可设置发送定时任务。
  • 高级调试
    • Crontab:显示 Crontab 中所有定时任务。
    • Input:显示所有任务的输入文件,可查看内容,并可按任务ID过滤。
    • Output:显示所有任务的输出文件,可查看内容,并可按任务ID过滤。
    • Mail:显示 /var/mail/mail 文件的内容。当定时任务执行出错时错误信息会写在该文件中。
    • Process:显示系统中当前所有的进程。
    • Killer:按进程号结束某个进程。

邮件报告

若想要定时收到邮件报告,请在Web界面前端页面的系统设置-邮件报告中设置 Crontab 定时任务。

备份数据

只备份工具表数据:

python manage.py dumpdata entities.tool --format=json > docker/tool.json

备份数据库中所有数据:

python manage.py dumpdata --format=json > backup.json

导入备份的数据:

python manage.py loaddata docker/tool.json

也可以在Web界面管理后台通过批量导出备份数据。

高级

这部分的操作将编写代码,需要读者掌握 Python 3 编程语言。

新增对某工具的支持

下面将以工具Censys子域名采集为例演示如何新增对某工具的支持。

安装和试运行

工具Censys子域名采集使用的是censys-enumeration,下载安装并尝试运行, 弄清楚命令参数和输出文件格式,并获得输出文件样本。

创建输出解析类

输出解析类必须是parse.parser.Parser的子类,该类的file_path是待解析文件(工具输出结果)的路径, 必须实现方法parse,在parse中需解析工具输出结果,并调用该类的add_record方法将解析出的结果保存到数据库中。 add_record会处理记录重复问题,故在解析工具输出结果时不用特别处理重复的记录。

Censys子域名采集的输出文件示例如下:

{"testfire.net": {"domain": "testfire.net", "subdomains": ["demo.testfire.net", "ftp.testfire.net"]}}

下面将编写用于解析上述输出的解析类。在parse目录中创建文件censys_enumeration_domain.py,内容为:

from .parser import Parser    # 导入解析类父类
import json    # 这个工具的输出是json格式的,故导入json库


class CensysEnumerationDomain(Parser):    # 类名会出现在工具表输出解析类下拉选项中
    """python censys_enumeration.py --no-emails --outfile {output_file} {input}
       for censys_enumeration.py 10d42fa3"""    # 建议写明工具调用命令和编写解析类时的工具版本

    def parse(self):
        with open(self.file_path) as f:
            output = json.loads(f.read())    # 从待解析文件中读入数据
        for domain in output:
            sub_domains = domain.get('subdomains', list())
            for sub_domain in sub_domains:
                self.add_record(sub_domain)    # 将解析出的记录加入到数据库中

添加测试

Censys子域名采集的输出示例文件保存到parse/examples/censys_enumeration.json, 然后编辑parse/tests.py文件,在类ParserTest中新增方法test_censys_enumeration_domain,代码如下:

def test_censys_enumeration_domain(self):
    tool = Tool.objects.create(name='censys_enumeration_domain_tool', type='censys_enumeration_domain_type')
    task = Task.objects.create(name='censys_enumeration_domain_task', project=self.project, tool=tool)
    parser = CensysEnumerationDomain(task, os.path.join('parse', 'examples', 'censys_enumeration.json'))
    parser.parse()
    self.assertEqual(Record.objects.filter(type='censys_enumeration_domain_type').count(), 2)

运行如下命令进行测试:

python manage.py test parse

在工具表中添加工具

进入到 Web 管理后台,在工具表中新增一个工具,各个字段填写的内容如下:

  • 工具名: Censys子域名采集
  • 项目地址: https://github.com/0xbharath/censys-enumeration/
  • 记录类型: 域名
  • 输出解析类: CensysEnumerationDomain
  • 调用命令: python censys_enumeration.py --no-emails --outfile {output_file} {input}(需特别注意命令路径)
  • 输入参数类型: 文件
  • 版本:10d42fa3(没有明确版本号的可以写commit ID)
  • 备注:留空

添加完成后便可在任务中使用此工具。

自定义Django命令

此处给出所有自定义 Django 命令及其参数和说明。

命令 参数 说明
init_admin 用户名,邮箱,密码 创建初始化用户,仅在没有用户时有效
cron_all_task 把任务表中所有任务添加到 Crontab 中
parse 任务ID 解析指定ID任务的输出文件,将结果保存到数据库中
update_input 任务 ID 更新指定 I D任务的输入文件,只对输入文件类型为动态的任务有效
set_record_report_cron 文件路径 将文件路径所指文件的内容设置为发送邮件报告的时间
record_report 日期(可选) 通过邮件发送今日或某日(若有日期参数)的新增记录报告

自定义 Django 命令的用法如下:

python manage.py <命令> <参数1> <参数2> <...>

如:

python manage.py init_admin admin admin@example.com 123456 

常见问题

项目为何叫这个名字?

没有特别含义,是用UNIQ名生成器随机生成的。

有没有类似项目?

有。后文列出了笔者已知的类似项目。

为何要重复造轮子?

我想写的实际上是一个可以调用任意信息收集工具的通过框架,和所有我已知的项目都有所不同。

下一步计划

  • 添加对更多工具的支持。
  • 增加更轻量级的部署方式。测试发现 1G 内存的云服务器跑 Docker 有些吃力,因此希望增加更轻量级的部署方式,让 pekja 可以运行在最便宜的 VPS 上。

类似项目