赞
踩
Django 很适合用来写安全小工具,因为很多安全工具都是 Python 编写的,
所以 Django 集成的话就可以少走很多弯路,又因为 Django 的官方文档比较全,
目前 Django 最新的版本都已经到 Django3 了,很适合新手上手使用。
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 图表插件, 使用的 ECharts 图表插件, 很强大, 简直是福利。
登录界面
中规中矩的界面
漏洞检测的算法 看上去 NB 哄哄的 Web 漏扫,发现 检测的效果也就是 just soso。但是一个扫描器还是要有漏洞检测功能的, 这个功能 把 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_exempt
点击资产名称的跳转到漏洞细节:
点击对应的漏洞 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 素材
域名探测功能 发现比较流行的子域名探测功能 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 可能开启公私钥登录,这个时候如果直接丢到类似 超级弱口令爆破工具 理论批量爆破的话 就会很浪费时间。所以最好爆破之前批量检测一下是否支持密码爆破。下面是简单的 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 等技术实现前后端分离
代码变量、数据库结构优化
实用功能完善
总之不论是开发还是安全都有很长的路要走,路漫漫其修远兮,吾将上下而求索,共勉 !
https://blog.csdn.net/weixin_43047908/article/details/119772225
SQL注入漏洞
CVE-2020-7471
CVE-2021-35042 CVE-2021-35042 Django SQL注入漏洞
StringAgg(分隔符)实现利用的潜在 sql注入
0x00:漏洞内容概述
攻击者可通过构造分隔符传递给聚合函数contrib.postgres.aggregates.StringAgg,
从而绕过转义符号(\)并注入恶意SQL语句。
漏洞影响版本
漏洞原理分析
在 Github 仓库查找 django 的 commit 记录,发现官方对其的修复:
从这里我们知道几个信息,漏洞函数位于下面的模块之中:
from django.contrib.postgres.aggregates import StringAgg
官方对 delimiter 使用Value(str(delimiter))处理后进行防御,
Value处理过的参数会被加到sql的参数列表里,
之后会被diango内置的过滤机制过滤,从而防范SQL漏洞。
poc:https://github.com/Saferman/CVE-2020-7471
initdb()函数
给管理器添加初始测试数据[(‘li’,‘male’),(‘zhao’,‘male’),(‘zhang’,‘female’)];
query()函数
进行模糊测试,
当delimiter 的值为哪些字符时,会让程序运行出现错误
(即使用哪些字符可能会干扰SQL语句的执行,将delimiter 输入的字符带入了SQL语句,破坏原有语句)
测试结果得出是单引号和百分号
query_with_evil()函数
进行注入点证明测试时,
payload前后两个不同的赋值,是为了得到两个不同的结果,
前一个使用正确的分隔符-,
后一个是使用同样的分隔符-,但是后面带有构造的SQL语句
') AS "mydefinedname" FROM "vul_app_info" GROUP BY "vul_app_info"."gender" LIMIT 1 OFFSET 1 --
真实执行的语句:
SELECT "vul_app_info"."gender", STRING_AGG("vul_app_info"."name", '-') AS "mydefinedname" FROM "vul_app_info" GROUP BY "vul_app_info"."gender" LIMIT 1 OFFSET 1 --
这里的payload = ‘-\’) AS … LIMIT 1 OFFSET 1 – ‘中的\’,
反斜杠的作用只是在payload字符串赋值时转义单引号,即payload中的-’),
使得STRING_AGG(“vul_app_info”.“name”, ‘-’)右括号闭合了,
导致了后面的SQL语句的执行,因为输出只出现一条,是因为使用了LIMIT,证明该SQL语句确实被执行了。
4.创建测试数据库test,初次安装postgres 数据库,
系统会创建一个数据库超级用户 postgres,密码为空。
使用命令(sudo -i -u postgres)进入postgres数据库,并创建测试数据库(test)。
5.修改配置文件
修改文件…/CVE-2020-7471/sqlvul_projects/settings.py 里面的第78列下的数据库配置,
如果之前安装postgres数据库使用的默认配置(包括密码),就无需修改任何任何配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'test', # 数据库名称
'USER': 'postgres',
'PASSWORD': 'aming', # 数据库用户密码
'HOST': '127.0.0.1', # 数据库地址
'PORT': '5432',
}
}
利用CVE中的代码初始化测试数据库test中的表
python3 manage.py migrate
python3 manage.py makemigrations vul_app
python3 manage.py migrate vul_app
运行 POC 脚本(CVE-2020-7471.py)查看结果
注入后的输出只出现一条,是因为使用了LIMIT,证明注入成功,实际正常应该输出两条
pip install django-summernote pip install pillow # 上传图片时需要 INSTALLED_APPS里去,如下所示: INSTALLED_APPS = [ ... 'django_summernote', # 注意下划线 ] django_summernote.urls 加入到项目的 urls.py from django.urls import include # ... urlpatterns = [ ... path('summernote/', include('django_summernote.urls')), ... ] 还需要在settings.py中设置MEDIA相关选项,如下所示。如果你Django的版本是3.x的,你还需设置X_FRAME_OPTIONS选项。 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') # Django 3.X用户还需增加如下配置 X_FRAME_OPTIONS = 'SAMEORIGIN' debug=True, 你还需要使用django自带static静态文件服务器才能正确显示上传的图片。修改项目的urls.py, 添加如下代码: from django.conf import settings from django.conf.urls.static import static if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
https://www.bilibili.com/video/BV1vK4y1o7jH?from=search&seid=7358572781939588281
flask 轻
手机游戏
请求响应 路由
MTV设计结构
HTTP状态的 cookie session
解释器 版本
完善的 内部组件
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。