tornado+celery快速搭建分布式被动漏扫框架
in 原创项目 with 0 comment

tornado+celery快速搭建分布式被动漏扫框架

in 原创项目 with 0 comment

漏扫是做安全绕不开的一个话题,每个白帽子都希望能有一个属于自己的扫描器,把自己收集的各种手法,姿势集成到一起,做到自动化挖洞。

写这个系列的初衷就是希望和大家分享自己写扫描器过程中的一些收获和遇到的一些坑,共同学习,因为是打造自己的漏扫,所以和企业级的产品肯定无法相提并论的。

这是打造属于自己的漏扫系列(1),第一篇文章,讲讲如何通过tornado+celery快速搭建一个分布式漏扫任务框架

整个系列会完全从代码层分享被动式扫描器和主动式扫描器的编写过程,先从比较简单的被动式漏扫入手。

主动式漏扫和被动式漏扫区别大家应该都所了解,在我看来,两种漏扫的主要区别是收集request的方法不一样:

我们先从被动式扫描说起,首先需要一个代理,或者使用流量镜像,拿到到用户正常的流量,然后把流量导入漏扫引擎,由漏扫引擎做扫描

图片 1.png

这里我们是tornado做代理服务器,用celery打扫分布式漏扫引擎

一.tornado做代理服务器

代理服务器的作用是抓取到用户的正常上网请求,把请求加入扫描队列,并且代理服务器不能影响用户的正常浏览
那么代理服务器则需要转发http和https的流量,对https流量暂时还未做扫描,只能做转发,对http流量进行转发和扫描

这里为什么选用tornado来实现,其实我也纠结了很久,首先我把目光放在高性能上,于是我有两种方案:

  1. 用python的socket模块写代理服务器,然后自己解析http请求
  2. 直接用tornado

最后经过测试对比发现,选择tornado有一下几个理由:

  1. tornado作为一个成熟的框架,帮我们完成了http协议的解析,可以很方便的使用
  2. tornado提供了一个基于框架本身的异步HTTP客户端AsyncHTTPClient,跟同步的HTTP客户端如requests相比,异步的HTTP客户端整体性能会好很多
  3. 对于个人扫描器来说,代理服务器并不会成为扫描速度的瓶颈,使用tornado已经绰绰有余了。

那么我们梳理一下代理服务器要做的事情

  1. 抓取用户的http请求,送到后端的漏洞扫描引擎中
  2. 转发用户的http请求和https请求

说写就写,首先把tornado作为server启动
图片 2.png

所有的http请求都会给到ProxyHandler类中的get和post方法中处理,https请求会交给connect处理
图片 3.png

关键函数是handle_response和fetch_request,fetch_request做了两件事

  1. 服务端发送请求,handle_response作为callback
  2. 把请求放到celery borker中

图片 4.png

AsyncHTTPClient是一个异步非阻塞的http请求客户端,它发送完reqeust之后,程序就可以去做其他的事情了,不用等着response
等response回来之后,会调用callback处理response,就是handle_respons来处理response,其中scan_task.delay是把请求送到celery的broker中

对于https请求,这里只做转发的功能,在connect函数中主要代码如下
图片 5.png

二.celery打造分布式扫描引擎

celery就是为分布式任务而生,用起来实在是非常方便,这里用最熟悉的redis作为broker,初始化代码如下
celery_app.py
图片 6.png
会去读取confg.py中的配置
config.py
图片 7.png

要在不同的机器运行扫描引擎的话只用把broker_url和celery_result_backend的url值修改为主机器的url即可
涉及到redis当然安全问题要注意,不要自己被搞了,如果只是本地使用的话,redis可以设置只允许本地访问,然后使用非root权限运行,如果要分布式运行扫描引擎的话,redis一定要设置密码,非root运行
我们将扫描任务放到tasks.py中
task.py
图片 8.png
可以在任何地方,都可以通过这样的方式添加任务

from celery_study.tasks import scan_task
scan_task.delay(request_dict)

这样会把scan_task送到redis中,然后celery的worker会去redis中自动去取任务执行

在scan_task中的scan_engine则是我们的对requst的扫描类,所有的扫描都从这个类开始
代码结构如下
├── init.py
├── celery_study
│   ├── init.py
│   ├── celery_app.py
│   ├── config.py
│   ├── network-server.log
│   └── tasks.py
├── proxy.py
└── scan_engine
├── init.py
├── bloom.py
├── scan_base.py
├── scan_plugin
│   ├── init.py
│   ├── plugin_scan_cmd_exec.py
│   └── plugin_scan_xss.py
└── scan_rules
├── init.py
├── scan_cmd_inject_rules.py
└── scan_xss_rules.py

我这里的示例代码只做了命令注入和xss的扫描

到此,一个简单的分布式的被动扫描框架已经搭建好了,接下来,我们需要对每一个request进行通用漏洞扫描,对每种漏洞的扫描都有它的技巧,包括替换的参数,payload,正则的效率,在之后慢慢讲

下一期准备写写,关于reques的去重问题和payload的格式到底怎么写才方便维护

参考链接:python搭建代理服务器

Comments are closed.