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 界面如下:
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
点击资产名称的跳转到漏洞细节:
点击对应的漏洞 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: 国光
请登录后发表评论
注册