Web应用渗透测试系统(Python) 您所在的位置:网站首页 web应用扫描器 Web应用渗透测试系统(Python)

Web应用渗透测试系统(Python)

2023-12-28 06:17| 来源: 网络整理| 查看: 265

项目介绍 系统简介

本项目命名为 Sec-Tools,是一款基于 Python-Django 的多功能 Web 应用渗透测试系统,包含漏洞检测、目录识别、端口扫描、指纹识别、域名探测、旁站探测、信息泄露检测等功能。

项目功能

在这里插入图片描述

本系统通过 旁站探测 和 域名探测 功能对待检测网站进行资产收集,通过 端口扫描、指纹识别、目录识别 和 信息泄露检测 功能对待检测网站进行信息收集,通过收集的信息分析评估网站存在哪些安全隐患,然后使用 漏洞检测 功能揭示网站存在的漏洞以及危害等级并给出修复建议。通过这一系列的步骤,可以对 Web 应用进行全面检测,从而发现网站存在的安全隐患,因此用户可以针对相应的网络威胁做出应急响应,进而提升站点的安全性。

相关技术 名称PythonDjangoSQLiteEChartsTablerLayerDocsifySimpleUIBoostrap Table版本3.7.03.1.43.35.25.0.11.0.03.2.04.11.62021.1.11.18.2 项目首页

首页采用 ECharts 对漏洞扫描的漏洞等级、指纹识别组件、安全导航数据做了可视化图表展示,图表的风格没有统一,凑合看吧

在这里插入图片描述

身份验证

新用户想要使用系统功能必须要注册登录,游客只能访问部分页面。本系统有普通用户和超级用户。普通用户可以使用本系统的所有功能,但是不能登录后台管理系统。超级用户不仅可以使用所用功能还可以登录后台管理系统中所有的用户权限和数据。

设计思路: 登录和注册模块在 Django 自带的认证模块的基础上进行实现,因此在 后台-->用户与授权 就可对注册用户进行权限分配和相应管理。我们使用 Django 自带的数据库 SQLite 来存放账户信息,重构了数据库表 auth_user 表,增加了用户邮箱字段,auth_user 中密码字段是加了 salt 的 sha256 值再经过 base64 编码之后的值,保障了用户的信息安全。

| 登录页 |在这里插入图片描述 | | ------ | -------------------------------------------------------------------- | | 注册页 | 在这里插入图片描述 |

重设密码功能调用第三方包 django-password-reset 进行实现

| 步骤一 | 在这里插入图片描述 | | ------ | -------------------------------------------------------------------- | | 步骤二 | 在这里插入图片描述 |

漏洞检测

该模块主要是对目标 Web 系统进行安全漏洞扫描,包括 SQL 注入、跨站脚本攻击(XSS)、弱密码、中间件漏洞。中间件漏洞扫描包括对 Weblogic、Struts2、Tomcat 、Jboss、Drupal、Nexus 的已知漏洞进行检测,用户提供目标 URL 并选择 CVE 漏洞编号。

设计思路

该模块的全扫描、SQL 注入漏洞扫描、XSS 漏洞扫描、弱口令扫描、仅爬取是调用 AWVS API 进行实现。中间件漏洞扫描是基于脚本模拟网络请求实现。根据漏洞形成的原因,生成一些测试 payload 发送到目标系统,再由返回的状态码和数据来判断 payload 是否有效。

实现效果

在这里插入图片描述

点击扫描目标跳转到漏洞结果页:

在这里插入图片描述

再点击扫描目标的跳转到漏洞详情页:

在这里插入图片描述

详细实现 添加扫描目标

漏洞扫描最开始的工作是添加扫描目标到 AWVS 的扫描队列中。AWVS 提供了一个 API 接口: /api/v1/targets,使用 POST 请求, POST 请求参数为:{"address":"XXXX.XXXX.XXXX","description":"xxxx","criticality":"10"}。

当目标添加成功后会返回一个 target_id ,这个值在所有扫描中是唯一的。通过 target_id 判断目标是否添加成功。添加完目标后并没有开始扫描,需要使用另一个 API 接口:/api/v1/scans,使用 POST 请求,传入刚刚添加目标生成的 target_id 和用户选择的扫描类型,POST 请求参数为:{"target_id":"xxxxxxx","profile_id":"xxxxxxx"}。开始扫描将会返回状态码 200。

使用 Python 的第三方库 requests 来实现 API 接口访问。核心代码如下:

# Target: POST请求/api/v1/targets try: #data包含目标URL和类型,auth_headers包含API_KEY response = requests.post(targets_api, auth_headers, data, False) result = response.json() target_id = result.get('target_id') return target_id except Exception: return None # Scan: POST请求/api/v1/scans try: response = requests.post(scan_api, data, auth_headers, False) status_code = 200 except Exception: status_code = 404 return status_code

API 接口已经实现,还需要获取用户输入的数据。由于本系统是基于 Django 实现的,所以使用 HTML+JavaScript 提供用户界面和接受和发送数据到后端,后端使用 Python 实现。首先在 urls.py 里面加入添加访问路径

path('vuln_scan', views.vuln_scan, name='vuln_scan')

在 views.py 中定义 vuln_scan() 函数接收前端的用户输入,并调用已经写好的 API 函数。用户输入的 url 为扫描的目标,扫描类型包括 SQL 注入、XSS 漏洞、弱口令和全扫描,其中全扫描就是扫描所有类型的漏洞,如果添加成功后返回的 target_id 不是 None,说明添加成功,就可以开始调用开始扫描的 API,开始扫描后返回状态码,为 200 则开始扫描,返回成功否则返回失败。核心代码如下:

@csrf_exempt def vuln_scan(request): #通过POST请求获取用户输入的URL和扫描类型 url = request.POST.get('ip') scan_type = request.POST.get('scan_type') t = Target(API_URL, API_KEY) #将目标URL添加到扫描队列中 target_id = t.add(url) #如果target_id不为None,则开始扫描 if target_id is not None: s = Scan(API_URL, API_KEY) status_code = s.add(target_id, scan_type) if status_code == 200: return success() return error()

最后使用 JavaScript 来实现发送用户输入的数据,选择通过 POST 方法发送数据,并在发送之前判断用户输入的合法性,核心代码如下:

function get_scan_info(ip , scan_type) { # 使用POST请求发送用户输入 $.post('/vuln_scan', { ip: ip , scan_type: scan_type }, function (data) { if (data.code !== 200) { ...... } else { ...... } ......}); } var domain = $('input[name=scan_url]').val(); # 使用循环判断用户选择的扫描类型 for(var i=0; i var scan_type=document.getElementsByName("scan_type")[i].value; } } if(domain){ get_scan_info(domain,scan_type) }else{ ...... }

总体来说,通过上述的代码实现,实现了将用户输入通过 JavaScript 传输给后台,后台接收数据后将调用 AWVS API,然后 AWVS 开始根据用户输入开始扫描目标 URL,扫描结束后将结果保存在数据库中。实现效果如下:

在这里插入图片描述

获取扫描结果

在上一小节中,将目标扫描的结果保存到数据库中,我们需要得到所有的扫描目标,‘/api/v1/scans‘,请求方式为 GET,请求成功后会返回所有扫描目标的信息,利用这个 API 可以实现展示所有扫描目标。要实现展示每个扫描目标的所有漏洞的功能,需要按照 target_id 来在所有扫描目标中搜索。AWVS 也提供了相应的 API,我们需要用到的 API 为:/api/v1/vulnerabilities

?q=severity:{int};criticality:{int};status:{string};cvss_score:{logicexpression};cvss_score:{logicexpression};target_id:{target_id};group_id:{group_id}。请求方式为 GET。利用 target_id 搜索每个扫描目标。这也解决了漏洞细节页面的 URL 问题。当使用 target_id 搜索扫描目标成功时将会返回这个目标的所搜漏洞信息,包括这个目标包含的漏洞个数、每个漏洞的危险等级、扫描时间、扫描类型、扫描状态等信息。

具体实现步骤和添加扫描目标大体相似,首先第一步使用 requests 来实现 API 请求。核心代码如下:

# 获取所有扫描目标 response=requests.get(scan_api, self.auth_headers, False) scan_response=response.json().get('scans') for scan in scan_response: scan['request_url'] = request_url scan_list.append(scan) return scan_list # 搜索状态为“open“,对应target_id的扫描目标 vuln_search_api=f'{vuln_api}?q=status:{status};target_id:{target_id}' try: # 使用get方式请求 response = requests.get(vuln_search_api, auth_headers, False) # 返回搜索结果目标的所有漏洞信息 return response.text except Exception: return None

在 urls.py 中加入用户访问的 url ,这个需要提供一个 target_id 方便后续功能的实现,先获取所有目标的 target_id,然后使用循环将所有 target_id 加入到 urlpatterns 列表中。因为在 Django 中 views 函数通常只能使用一个 request 参数,由于这里需要将 target_id 传入到 views 函数中,使用正则匹配的 “(?P.*)$” 接收传入的 target_id,在 views 里对应函数的第二个形参名必须和 里的值一致才有效。核心代码如下:

path('vulnscan', views.vulnscan, name="vulnscan"), for target_id in target_ids: #使用正则匹配获取第二个参数:taget_id urlpatterns.append(url(r'^vuln_result/(?P.*)$', views.vuln_result, name='vuln_result/'+target_id))

在 views.py 里定义函数 vulnscan(request) 获取所有对应的目标漏洞信息。使用 API 得到返回的漏洞危险等级、扫描目标 URL、每个漏洞唯一标识的 vuln_id、扫描类型、扫描处理时间,API 返回的扫描处理时间不是标准的时间格式,使用正则匹配的方式,将其转换为 “%Y-%m-%d %H:%M:%S“ 的格式,再定义函数 vuln_result(request,target_id),根据 target_id 获取扫描目标中所有漏洞信息,包括存在漏洞的 URL、漏洞类型、状态和处理时间等信息。核心代码如下:

@login_required def vuln_result(request, target_id): d = Vuln(API_URL, API_KEY) data = [] vuln_details = json.loads(d.search(None,None, "open", target_id=str(target_id))) id = 1 for target in vuln_details['vulnerabilities']: item={ 'id': id, 'severity': target['severity'], 'target': target['affects_url'], 'vuln_id':target['vuln_id'], 'vuln_name': target['vt_name'], 'time': re.sub(r'T|\..*$', " ", target['last_seen']) } id += 1 data.append(item) return render(request,'vuln-reslut.html',{'data': data})

在这个子功能中,前端的数据展示使用的是 Bootstrap Table。这个模板有很多实用的功能,比如表格的搜索功能、分页展示功能等等,增加了用户体验。表格的数据在 HTML 中使用双花括号来接收,在 views.py 函数中返回的到相应的 HTML 页面时,将 data 字典一起返回。这样的返回方式可以将使用字典中的 key 值获取对应的 values 值。还可以是使用 if-else、for 等语句来分类展示数据。核心代码如下:

{% for item in data %} …………… # 这个只展示了扫描目标列,其他列类似


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有