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

张开发
2026/4/21 11:34:19 15 分钟阅读

分享文章

Web应用渗透测试系统(Python)
Web应用渗透测试系统Python项目介绍系统简介本项目命名为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_codeAPI 接口已经实现还需要获取用户输入的数据。由于本系统是基于 Django 实现的所以使用 HTMLJavaScript 提供用户界面和接受和发送数据到后端后端使用 Python 实现。首先在urls.py里面加入添加访问路径path(vuln_scan, views.vuln_scan, namevuln_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[namescan_url]).val(); # 使用循环判断用户选择的扫描类型 for(var i0; idocument.getElementsByName(scan_type).length; i) { if (document.getElementsByName(scan_type)[i].checked) { var scan_typedocument.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?qseverity:{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 请求。核心代码如下# 获取所有扫描目标 responserequests.get(scan_api, self.auth_headers, False) scan_responseresponse.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_apif{vuln_api}?qstatus:{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 函数中使用正则匹配的“(?Ptarget_id.*)$”接收传入的 target/_id在 views 里对应函数的第二个形参名必须和里的值一致才有效。核心代码如下path(vulnscan, views.vulnscan, namevulnscan), for target_id in target_ids: #使用正则匹配获取第二个参数taget_id urlpatterns.append(url(r^vuln_result/(?Ptarget_id.*)$, views.vuln_result, namevuln_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_idstr(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(rT|/..*$, , 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 %} …………… # 这个只展示了扫描目标列其他列类似 a href/vuln_detail/{{ item.vuln_id }} {{ item.target }}/a …………… {% endfor %}最后实现的效果如下图所示根据每个扫描状态不同有不同的显示使用红黄蓝绿来分类高危、中危、低危、info 等级的漏洞。最后展示了扫描的处理时间。表格中扫描目标列可以点击进入查看目标的所有漏洞信息如下图所示展示了特定的扫描目标每个漏洞的危险等级、存在漏洞的 URL、漏洞的类型。获取漏洞细节在实现漏洞扫描和结果展示后还需要获取每个漏洞的细节。包括导致漏洞的请求参数、测试的 payload、数据请求包、简要的修复建议等等。因为每个漏洞也存在一个唯一的标识 vuln/_id可以根据这个值查询指定漏洞的所有信息。使用的 API 为/api/v1/vulnerabilities/{vuln_id}请求方式为 GET。同样地首先使用 requests 来实现 API 的调用传入 vuln/_id 来查询指定漏洞的所有信息代码如下# 获取指定漏洞的相关信息 def get(self, vuln_id): vuln_get_api f{self.vuln_api}/{vuln_id} try: #使用GET请求将vuln_id传给API结果以json格式返回 response requests.get(vuln_get_api, auth_headers, False) return response.json() except Exception: return None在urls.py中添加漏洞细节的 url这里与上一节展示扫描目标的所有漏洞类似都用正则匹配的形式接收views.py里函数的第二个形参但是这里不在使用 target/_id 而是使用 vuln/_id。代码如下for vuln_id in vuln_ids: urlpatterns.append(url(r^vuln_detail/(?Pvuln_id.*)$, views.vuln_detail, namevuln_detail/ vuln_id))在views.py里面定义vuln_details(request,vuln_id)函数根据 vuln/_id 查询指定漏洞的相关信息。该函数将 API 返回的值中有用的信息提取出来到字典 data 里返回给 vuln-details.html 页面使用 双花括号 来接收该漏洞的受影响的 URL、处理时间、漏洞类型、漏洞测试参数、数据请求包、简要的修复建议等信息。实现效果如下图所示。login_required def vuln_detail(request,vuln_id): d Vuln(API_URL,API_KEY) data d.get(vuln_id) print(data) parameter_list BeautifulSoup(data[details], featureshtml.parser).findAll(span) request_list BeautifulSoup(data[details], featureshtml.parser).findAll(li) data_dict { affects_url: data[affects_url], last_seen: re.sub(rT|/..*$, , data[last_seen]), vt_name: data[vt_name], details: data[details].replace( ,).replace(/p,), request: data[request], recommendation: data[recommendation].replace(br/,/n) } try: data_dict[parameter_name] parameter_list[0].contents[0] data_dict[parameter_data] parameter_list[1].contents[0] except: pass num 1 try: Str for i in range(len(request_list)): Str str(request_list[i].contents[0])str(request_list[i].contents[1]).replace(strong, ).replace(/strong, )/n num 1 except: pass data_dict[Tests_performed] Str data_dict[num] num data_dict[details] data_dict[details].replace(classbb-dark,stylecolor: #ff0000) return render(request, vuln-detail.html, {data: data_dict})基于 POC 验证的中间件漏洞扫描本系统使用 POC 脚本实现对一些中间件的漏洞扫描[7]包括 Weblogic、Tomcat、Drupal、JBoss、Nexus、Struts2 等等。通过每个漏洞的特点使用 Python 编写不同的 POC 脚本验证目标是否存在该漏洞。首先这里的用户界面和基于 AWVS 的漏洞扫描共用单独加入了中间件漏洞 CVE 编号的选择。使用 JavaScript 发送用户输入的数据到后端。核心代码如下# 使用POST请求提交用户的输入 function get_Middleware_scan(ip , CVE_id) { $.post(/Middleware_scan, { ip: ip , #目标URL CVE_id: CVE_id #选择的CVE编号 }, function (data) { # 处理返回结果 ……… ………}); }将目标添加到数据库后再查询数据库开始扫描通过 AJAX 来访问 start/_Middleware/_scan 调用开始扫描的函数由于扫描时间可能会很长需要设置足够的 timeout 来等待扫描的结果返回。核心代码如下$.ajax({ # 使用POST请求发送目标URL和CVE编号设置超时为1秒 type: POST, url: /start_Middleware_scan, timeout: 10000, data: { ip: ip, CVE_id: CVE_id } });在urls.py里加入中间件漏洞扫描的访问路径需要加入两个路径’Middleware_scan‘‘start_Middleware_scan’。前者是用户添加扫描目标时的路径用于接收用户输入的目标和 CVE 编号之后将其插入数据库。后者是将目标插入数据库之后通过时间戳、状态、目标 URL 以及 CVE 编号查询出来开始扫描。当扫描结束时更新数据库中对应扫描目标的状态。这样的设计可以实时的看到扫描的状态。数据库使用的是 SQLite在models.py里创建一个数据库表 Middleware/_vuln 字段包括 ID、目标 URL、状态、结果、CVE 编号、时间戳。在 Django 里定义这个类表示我们需要创建的数据库在 modles.py 里创建好之后使用命令python manage.py makemigrations来记录 modles.py 的所有改动并且将这个改动迁移到 migrations 这个文件下生成一个文件例如0001 文件如果你接下来还要进行改动的话可能生成就是另外一个文件不一定都是 0001 文件但是这个命令并没有作用到数据库再使用命令python manage.py migrate将根据刚刚检测到的改动来创建数据库表和字段属性。核心代码如下class Middleware_vuln(models.Model): # 类名为数据库表名变量名为字段名字段属性定义如下 id models.AutoField(primary_keyTrue) url models.CharField(max_length100, nullTrue) status models.CharField(max_length20, nullTrue) result models.CharField(max_length100, nullTrue) CVE_id models.CharField(max_length100, nullTrue) time models.CharField(max_length100, nullTrue, uniqueTrue)在添加目标和开始检测的时候我们需要插入数据库和查询数据库这里使用 Django 的函数来处理数据库的增删查改。对于 Middleware/_vule 的插入使用Middleware_vuln.objects.create(url, status, result, CVE_id, time)更新使用Middleware_vuln.objects.filter(time).update(status, result)。还需要使用 try-except 来处理异常情况并打印出错信息。def insert_Middleware_data(url, CVE_id, Time, resultNone, statusruning): try: Middleware_vuln.objects.create(urlurl, statusstatus, resultresult, CVE_idCVE_id, timeTime) print(insert success) return True except: print(data insert error) return False def update_Middleware_data(url, CVE_id, Time, result): try: Middleware_vuln.objects.filter(urlurl, statusruning, CVE_idCVE_id, timeTime).update(statuscompleted, resultresult) print(update success) except: print(data updata error)在views.py里定义Middleware_scan()获取用户输入并插入到数据库中,其中时间戳 Time 为全局变量作为后面开始扫描部分查询数据库的条件在插入数据成功就返回 success(),否侧返回 error()这里返回的函数时返回的状态码success()返回的是 200error()返回 404通过上面 JavaScrip t 接收后做出判断并弹出相应的提示框核心代码如下Time 0.0 csrf_exempt login_required def Middleware_scan(request): #使用POST请求获取用户输入并将其插入数据库中。 #Time作为全局变量插入到数据库中作为查询目标信息的条件。 global Time try: url request.POST.get(ip) CVE_id request.POST.get(CVE_id).replace(-,_) Time time.time() # time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(t))时间戳转日期格式 if insert_Middleware_data(url, CVE_id, Time): return success() except: return error()又定义函数start_Middleware_scan(),实现将数据库中时间戳为 Time状态为 run 的目标查询出来根据 CVE 编号调用对应的 POC 脚本。最后更新数据库的扫描结果和扫描状态由于在上一步中将数据插入数据库中可能会花费一点时间所以需要使用 sleep() 等待数据插入后再进行查询工作和扫描工作保证不遗漏扫描目标。csrf_exempt login_required def start_Middleware_scan(request): try: url request.POST.get(ip) ip, port urlparse(url).netloc.split(:) CVE_id request.POST.get(CVE_id).replace(-, _) time.sleep(5) #等待数据插入成功后在查询出来扫描 msg Middleware_vuln.objects.filter(urlurl, statusruning, CVE_idCVE_id, timeTime) print(msg) #扫描条目可能不止一条需要使用循环来扫描 for target in msg: result POC_Check(target.url, target.CVE_id) #将扫描结果和状态更新 update_Middleware_data(target.url, target.CVE_id, Time, result) return success() except: return error()端口扫描本系统端口扫描当用户指定了目标 IP 地址后系统正式工作IP 传入后台对目标进行扫描扫描完成后将开放端口和对应服务显示到前端界面上。在“按端口分布划分”和“按协议类型划分”两个栏目中对端口划分进行讲解使用户免于查询的繁琐。同时该模块还将内置常见端口查询表在此可进行端口及其对应服务和功能的相关查询和筛选通过这一系列功能用户能够更加清晰的认识到目标主机开放了哪些服务以此来分析可能存在漏洞的服务。设计思路本系统端口扫描的实现方法是利用 Python 提供的库函数 Socket 进行调用通过 TCP 三次握手与目标计算机的端口建立连接。当完成一次完整的三次握手时则可以推断出端口和对应服务是开放的反之则没有开放为了提高了扫描的效率本系统引入多线程扫描机制。实现效果详细实现端口扫描通过 Python 直接定义 socket尝试与目标端口进行连接。本程序中使用sock socket.socket(socket.AF_INET,socket.SOCK_STREAM);的方式进行 TCP 连接调用sock.connect_ex((ip,port))来尝试连接端口如果端口开放则返回 0否则返回错误代码。使用 try 语句来捕获异常如果 socket 连接超时则返回异常处理信息。核心代码如下def socket_scan(self, hosts): 端口扫描核心代码 global PROBE socket.setdefaulttimeout(1) ip, port hosts.split(:) try: if len(self.port) 25: # 创建套接字 sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP/IP三次握手建立连接 result sock.connect_ex((ip, int(port))) # 调用socket.connect_ex((ip, port))端口开放返回0否则返回错误代码 # 实现和nmap的全连接扫描类似的功能。 if result 0: # 成功建立TCP链接 self.port.append(port) # 结果集中增加端口 for i in PROBE: # 通过HTTP1.1刺探 sock.sendall(i.encode()) # 发送完整的TCP数据包 response sock.recv(256) # 接受最大256byte sock.close() if response: break if response: for pattern in SIGNS: pattern pattern.split(b|) if re.search(pattern[-1],response, re.IGNORECASE): # 正则匹配banner信息与字典中的服务 proto {}:{}.format(pattern[1].decode(), port) self.out.append(proto) # 添加至输出结果 break else: self.num 1 except (socket.timeout, ConnectionResetError): # 异常处理 pass except: pass如果这样单线程串行阻塞运行会耗费大量时间因此通过并发的方式并发请求提升扫描速度通过对比扫描 300 个端口单线程需要 30s 左右多线程仅需 10s 左右。本端口扫描功能中采用了并发 64 条线程来进行扫描因此在定义 run 方法时每个线程扫描的两个端口号间差数为 64在程序中使用 concurrent.futures 来实现。concurrent.futures 模块提供了一个高水平的接口用于异步执行调用。异步执行可以使用线程实现使用 ThreadPoolExecutor或者独立的进程使用 ProcessPoolExecutor 实现。两者都实现相同接口都是由抽象 Executor 类定义的。THREADNUM 64 # 线程数 def run(self, ip): #多线程扫描 hosts [] global PORTS, THREADNUM for i in PORTS: hosts.append({}:{}.format(ip, i)) try: with concurrent.futures.ThreadPoolExecutor( max_workersTHREADNUM) as executor: executor.map(self.socket_scan, hosts) except EOFError: pass端口查询表端口查询表功能通过收集网上端口信息建立端口查询库涉及到的端口数据是存储在数据库中包括端口 ID、端口号、端口对应服务、端口对应协议和端口所属状态。端口查询表结构如下表所示。字段名字段类型允许空是否主键备注idintegerNot nullTrue端口 IDnumbigintNot nullFalse端口号servicetextNot nullFalse端口对应服务protocolVarchar(20)Not nullFalse端口对应协议statusVarchar(10)Not nullFalse端口所属状态端口查询数据库采用 Django Model 进行建立字段包含端口号、服务、协议、和状态。实现代码如下class PortList(models.Model): 端口查询表 nummodels.BigIntegerField(verbose_name端口号) servicemodels.TextField(max_length100,verbose_name服务) protocolmodels.CharField(max_length20,verbose_name 协议,blankTrue,default未知) statusmodels.CharField(max_length10,verbose_name 状态,blankTrue,default未知) class Meta: # 后台表头设置 verbose_nameverbose_name_plural端口列表数据库建立后需要进行后台注册这样可以进入后台对数据进行管理实现代码如下admin.register(PortList) class PortListAdmin(ImportExportModelAdmin): # 设置哪些字段显示在后台 list_display (num, service, protocol, status,) # 设置num字段进入编辑界面 list_display_links (num,) search_fields (num, service,) # 过滤器按字段进行筛选 list_filter (protocol,status) # 设置num为默认排序字段 ordering (num, ) list_per_page 15 #设置每页显示数据条数指纹识别该模块采用提取指纹特征码特征信息来识别 Web 指纹系统通过构造大量特殊的 HTTP 请求与 Web 服务器交互从其响应数据包信息中提取提取指纹特征信息然后通过与指纹数据库进行比对从而获取到 Web 服务器及应用的组件信息和版本信息。通过发现这些特征信息并对它进行识别可以帮助我们快速地制定渗透策略是渗透环节中关键的一步。设计思路国内外对 Web 服务器及应用指纹的研究主要都是通过构造大量特殊的 HTTP 请求与 Web 服务器交互从其响应数据包信息中提取提取指纹特征信息然后通过与指纹数据库进行比对从而获取到 Web 服务器及应用的组件信息和版本信息。本文采用基于关键字特征匹配的方法实现指纹识别功能为了使检测结果更加准确对比网上一些主流的指纹数据库对本系统的数据库进行了一系列优化。实现效果详细实现指纹识别流程中最关键的就是提取指纹特征这一步骤。提取指纹特征首先需要确定应该提取响应数据报文中的哪些数据。因此需要设计特征提取算法对响应数据报文进行分析响应数据包是由响应行、响应头、响应体三部分构成。响应行由 HTTP 版本、状态码、状态码描述构成。响应头用于指示客户端如何处理响应体响应头里面包含很多的组件信息用于告诉浏览器响应的类型、字符编码服务器类型和字节大小等信息。响应体则是服务器根据客户端的请求返回给客户端的具体数据。响应头和响应体中包含了能够识别 Web 指纹组件的字段内容因此对响应头和响应体中关键字段的提取是实现指纹识别技术的核心。指纹识别技术分为信息收集阶段和 Web 指纹识别阶段。(I)信息收集阶段:通过用户输入的 URL收集 Web 应用的特定字段信息返回页面关键字或者特殊文件和路径等这些特征。收集的关键数据越多对接下来的指纹识别结果越准确。(2)Web 指纹识别阶段:该阶段包含两部分一部分是指纹库的建立该部分主要负责从已知的 Web 应用程序中收集特征信息并且建立指纹特征库本文通过分析 HTTP 响应数据报文设计了网站指纹的提取规则通过分析响应头字段和响应体内容构建了一个指纹组件信息库信息库采用 JSON 格式进行存储。指纹信息是从 Wappalyzer 和 FOFA 等平台上进行收集归纳的。另一部分从待测的 Web 应用程序中收集特征信息并与指纹特征库中的数据进行比较从而识别出待测的 Web 应用程序。目录扫描目录识别参照 dirsearch 实现包含 PHP、asp、JSP 等网站类型进行扫描还设置了递归扫描和自定义扫描选项。支持自定义前后缀或者子目录。设计思路Dirsearch 扫描的结果通过 JSON 的格式保存在对应的路径下因此我们可以减轻对数据库的依赖。获取的数据被分成 URL 和 TIMRURL 下又分为 content-length、path、redirect、starus 四个部分。因为在 JSON 格式中被不同类型括号的数据会被 Django 解析为列表、字典等格式因此我们需要对获得的 JSON 数据进行处理将其转换为 Django 可以识别的数据使之在前端进行读取。要正确解析数据需要先理解 Python 数据结构和 JSON 数据的转换方法。我们基于当前的固定的 JSON 格式去解析取得的数据。实现效果信息泄露该模块主要为用户提供常见的信息泄露检查。在前端直观的展示后台地址、配置文件等可能存在泄露的信息在结果列表中用户可以非常清晰的知道某个 Web 服务存在的信息泄露问题。旁站探测该模块主要对通过 IP 地址直接获取与当前 IP 所在服务器上的其它网站 本模块直接调用 API 实现域名探测该模块主要通过调用 API 来扫描网站的子域名安全导航安全导航页面的灵感来自于 Viggo 大佬开发的 Webstack 项目该项目是基于 Bootstrap 开发的纯前端页面因此前端我沿用了Webstack的风格并融合了Tabler UI风格并用Django写了后台管理可在线对分类和条目进行管理。前端页面后台管理页面数据库设计导航条目-Item标题 title 描述 desc 网址 url 分类 category(外键) 图片 img 图片宽度 img/_widthclass Item(models.Model): 导航条目 title models.CharField(max_length50,verbose_name名称) desc models.TextField(max_length100,verbose_name描述) url models.URLField(verbose_name网址,blankTrue) img models.URLField(defaulthttps://jwt1399.top/favicon.png,verbose_namelogo) img_width models.IntegerField(default45, verbose_name图片宽度) category models.ForeignKey(Category, blankTrue, nullTrue, verbose_name分类, on_deletemodels.CASCADE) class Meta: verbose_nameverbose_name_plural导航条目 #后台条目图片预览 def img_admin(self): return format_html( img src{} width50px height50px styleborder-radius: 50%; /,self.img,) img_admin.short_description logo预览 def __str__(self): return self.title条目分类-Category名称 name 排序 sort 是否添加到导航栏 add/_menu 图标 iconclass Category(models.Model): 条目分类 name models.CharField(max_length20, verbose_name名称) sort models.IntegerField(default1, verbose_name显示顺序) add_menu models.BooleanField(defaultTrue, verbose_name添加到导航栏) icon models.CharField(max_length30, defaultfas fa-home,verbose_name图标) class Meta: verbose_name_pluralverbose_name 分类 #统计分类对应条目数,并放入后台 def get_items(self): return len(self.item_set.all()) get_items.short_description 条目数 # 设置后台显示表头 #后台图标预览 def icon_data(self):#引入Font Awesome Free 5.11.1 return format_html(h1i class{}/i/h1,self.icon) #转化为i class{self.icon}/i icon_data.short_description 图标预览 def __str__(self): return self.name《网络安全从零到精通全套学习大礼包》96节从入门到精通的全套视频教程免费领取如果你也想通过学网络安全技术去帮助就业和转行我可以把我自己亲自录制的96节 从零基础到精通的视频教程以及配套学习资料无偿分享给你。网络安全学习路线图想要学习 网络安全作为新手一定要先按照路线图学习方向不对努力白费。对于从来没有接触过网络安全的同学我帮大家准备了从零基础到精通学习成长路线图以及学习规划。可以说是最科学最系统的学习路线大家跟着这个路线图学习准没错。配套实战项目/源码所有视频教程所涉及的实战项目和项目源码学习电子书籍学习网络安全必看的书籍和文章的PDF市面上网络安全书籍确实太多了这些是我精选出来的面试真题/经验以上资料如何领取9459b7a3d079371f.png)配套实战项目/源码所有视频教程所涉及的实战项目和项目源码学习电子书籍学习网络安全必看的书籍和文章的PDF市面上网络安全书籍确实太多了这些是我精选出来的面试真题/经验以上资料如何领取

更多文章