Django初次尝试编写Web漏洞扫描器挖坑记录 – 作者:国光

Django 很适合用来写安全小工具,因为很多安全工具都是 Python 编写的,所以 Django 集成的话就可以少走很多弯路,又因为 Django 的官方文档比较全,目前 Django 最新的版本都已经到 Django3 了,很适合新手上手使用。本文的项目暂时还没有开源,这个只是国光初次尝试写的第一个版本,代码很多地方都需要重构,功能上也有很多待完善,目前写这篇文章只是想理一下思路,证明自己可以写扫描器,因为之前立过写扫描器的 Flag ,国光建议大家也可以尝试用 Django 之类的 Web 框架整合自己的小工具。

相关技术

Python 3.8.0

Python 3.8 支持许多高级特性,在 Web 漏扫这一块 Python 的编写也十分灵活。

Django 3

使用了最新的 Django 版本,Django 是 Python 语言中文档比较全的一个 Web 框架,因为文档比较全,适合新手上手,所以这里选了 Django。

MySQL

经典的关系型数据库,实际上因为 Django 可以完美的支持各种数据库,一般我们不需要对数据库进行直接操作,所以换其他的数据库也是可以的,因为对 MySQL 比较熟悉,就选择了MySQL 了。

H+ 4.1

H+ 是一个功能全面的收费框架,基于 Bootstrap3.3.6 码云上有人开源出来了,因为 Bootstrap 容易上手,所以国光这里就白嫖了这个框架,然后在此基础上进行了深度修改。

ECharts

ECharts 是百度开源的一个数据可视化的 JS 图表插件,之前国光我使用 Django 重写我的 Hexo 博客的时候,发现我那个主题就是使用的 ECharts 图表插件,所以这次写 Web 漏扫的时候也就轻车熟路的直接使用了,ECharts 很强大,对于我们这种前端一般般的开发者来说,简直是福利。

漏洞检测

漏洞检测:实际上国光我一开始是不打算写的,因为我对漏洞检测的算法没有信心,另外国光也看了网上那些看上去 NB 哄哄的 Web 漏扫,发现漏洞检测的效果也就是 just so so。但是一个扫描器还是要有漏洞检测功能的,所以国光在写这个功能前把 AWVS 13 APi 全部亲自测试了一遍,然后把长亭科技的 xray 的官方文档也过了一遍。

所以这个漏洞检测功能最终就是使用 AWVS 13 爬虫来爬取目标资产信息,然后将获取到的信息转发给 xray 进行漏洞检测,直接用轮子效率真的高,新版本的 xray 支持 webhook 方便获取到漏洞信息,Demo 界面如下:

15898088299070.png Django写的对应的 xray webhook 接口,下面是这个接口简单的实现代码:

import json
from django.shortcuts import render
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt


class WebHook(View):
    @csrf_exempt
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        vul_data = json.loads(request.body)
        if 'detail' in str(request.body):
            print('漏洞插件:', vul_data['plugin'])
            print('漏洞位置:', vul_data['target']['url'])
            print('漏洞分类:', vul_data['vuln_class'])

        return render(request, 'test.html', {
        })

因为 Django 安全机制问题,xray post 提交请求到 Django 必须填写 CSRF Token才可以,解决方法就是手动关掉这个类的 CSRF 检测@csrf_exemp

点击资产名称的跳转到漏洞细节:

i

点击对应的漏洞 URL 会展开详细的漏洞细节:

总的来说功能上基本可以满足渗透测试人员的需求了。

端口扫描

端口扫描:国光我的扫描思路是先使用 masscan 进行网段粗略扫描,然后再用 nmap 进行详细扫描。比较舒服的事情是 Python 里面都有不错的相应的模块可以直接使用,这样代码写起来就更加得心应手了。

python-masscan 的扫描效果图:

IP 归属地查询使用的接口如下:

ip_api_url = f'http://freeapi.ipip.net/{ip_addr}'
r = requests.get(url=ip_api_url)
addr_list = literal_eval(r.text)
addr = ' '.join(addr_list[:3])

接着点击网段后的跳转页面如下图所示:

在这里可以继续发起扫描,这里就是调用的 nmap 扫描器,上方图标插件分别展示了端口和服务类别的饼状图,资产比较多的也会在右上侧列出来,总体效果还是可以的。

指纹识别

指纹识别:主要使用了 wappalyzer 做基本的指纹探测,这可以让结果看上去不会那么尴尬,毕竟不是每个资产都可以那么容易识别到 CMS 的;当然传统的指纹识别功能也集成了,这里使用的指纹库是:TideFinger,虽然这个指纹库比较老了,但是可以自己在这个基础上扩充,基本上也可以满足基本的指纹探测功能的,国光我整理出的 JSON 格式链接地址

指纹识别详情展示图:

当然一些古老的 CMS 也是可以识别出来的,这个就归功于 TideFinger 的功劳了:

不过这些 CMS 的名称和描述是需要自己建库的,然后对应的数据库 model 注册到 Django Admin 中:

@admin.register(Component)
class ComponentAdmin(admin.ModelAdmin):
    list_display = ('name', 'desc', 'category', 'icon_data')
    search_fields = ('name', 'desc')
    readonly_fields = ('icon_data',)
    list_per_page = 20

    fieldsets = (
        ('编辑组件', {
            'fields': ('name', 'desc', 'category', 'icon', 'icon_data')
        }),
    )

    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size': '59'})},
    }

其中 icon 是图片,这里需要我们在对应的 Model 里面编写好对应的 HTML:

class Component(models.Model):
    name = models.CharField(max_length=200, verbose_name='组件名称')
    desc = models.CharField(max_length=200, verbose_name='组件描述')
    icon = models.FileField(upload_to='icons/', verbose_name='组件logo', max_length=100)
    category = models.CharField(max_length=100, verbose_name='组件类别', blank=True)

    def icon_data(self):
        return format_html(
            '<img src="/media/{}" width="50px" height="50px" />',
            self.icon,
        )

    icon_data.short_description = 'Logo'

实际上在 Django Admin中添加编辑起来的话效率也比较高,国光这里使用的是目前比较流行的 Django Admin:Simple Ui ,下图是具体的效果:

这里国光我打包了对应的数据库以及 icon 素材,方便大家直接使用:CMS组件描述-蓝奏云

域名深测

域名探测:功能国光我发现比较流行的子域名探测功能 one for all 用的也是很多 API 接口,于是国光我也打算使用第三方服务来获取子域名,这样获取的速度会很快。

为什么不用传统的暴力破解子域名呢?因为现在很多 SRC 的子域名都已经到 3 级甚至 4 级了,这个时候用暴力破解子域名的话效率是及其低下的,要等到天荒地老。接口的话,国光我筛选了 6 个还算不错和稳定接口,基本上覆盖面是有的了:

因为这些子域名是存入数据库的,所以也就顺便增加了域名监控功能,每次扫描可以统计出新增的域名数量。域名探测所使用的 6 个接口分别如下,大家也可以直接拿去使用,做好对应的数据提取就可以了:

# 爱站
https://baidurank.aizhan.com/baidu/{domain}/

# 百度云观测
http://ce.baidu.com/index/getRelatedSites?site_address={domain}

# hackertarget
https://api.hackertarget.com/hostsearch/?q={domain}

# IP138
https://site.ip138.com/{domain}/domain.htm

# crt.sh SSL 证书反查
https://crt.sh/?q=%25.{domain}

# 千寻
url = 'https://www.dnsscan.cn/dns.html'
datas = {"ecmsfrom": '8.8.8.8', "show": 'none', "keywords": domain}

域名探测细节效果图:

域名访问超时直接丢弃结果的,然后再获取网页标题,这个在实际的信息收集中比较实用的,一些 404 403资产的可以跳过,减少无意义的浪费时间。

目录扫描

目录扫描:国光这里直接强行把 Dirsearch 给集成到 Django 中了,附上罗永浩那句话:“又不是不能用”

为什么是强行呢,因为代码实在不优雅,等后面正式开源这里再好好重写一下。又因为前端比较菜,所以 Web 目录扫描这一块和之前的模板外观看上去是差不多的:

点击目录扫描细节可以看到详细的目录扫描结果:

这里没有啥亮点,Dirsearch 本身就很强大,后期打算集成 top 1000 字典,每次目录命中的话,计数 + 1,然后把高命中的字典保存下载下来,这样实战中应该会更实用。

小工具

目前小工具集成的功能如下:IP 提取、文本对比、批量获取网页标题、SSH批量爆破验证……这些都是比较常用的小功能,写起来也比较简单:

这些小工具实际上就是一些小脚本的整合,建议大家也尝试使用 Django 去集成一些,这样平时使用的时候就会更加方便了,不需要翻来覆去地导出找脚本了。

SSH 批量爆破验证

众所周知,SSH 可能开启公私钥登录,这个时候如果直接丢到类似 超级弱口令爆破工具 理论批量爆破的话,就会很浪费时间。所以最好爆破之前批量检测一下是否支持密码爆破。下面是简单的 Python Demo:

import os
import pexpect
import progressbar

with open('22.txt') as f:
    lines = f.readlines()

attack_ips = []
p = progressbar.ProgressBar()
for line in p(lines):
    ssh = pexpect.spawn('ssh root@{ip}'.format(ip=line))
    try:
        flag = ssh.expect(['continue', 'password:'], timeout=3)
        if str(flag).isnumeric():
            attack_ips.append(line)
    except pexpect.EOF:
        ssh.close()
    except pexpect.TIMEOUT:
        ssh.close()

for ip in attack_ips:
    with open('ssh.txt','a') as f:
        f.write(ip)

类似的还可以写 MySQL 批量爆破验证,因为 MySQL 不一定都是开启外连的,所以爆破前的检测是很有必要的,这样可以在后面的爆破节省大量的时间。

总结

总的来说,使用 Django 写一个漏扫虽然难度不高(用了轮子了,让我写一个 xray 这种强大的扫描器还差的很远呢…羞愧地低下了头),但是要做的细致好用的话难度还是很高的。这里给自己挖个坑,待以后有精力了重写这个扫描器:

 Redis 缓存加速

WebSocket 通信

Django 配合 React、Vue 等技术实现前后端分离

代码变量、数据库结构优化

实用功能完善

总之不论是开发还是安全都有很长的路要走,路漫漫其修远兮,吾将上下而求索,共勉 !

*本文作者:国光,转载请注明来自FreeBuf.COM

来源:freebuf.com 2020-06-11 08:00:21 by: 国光

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论