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

本系统通过 旁站探测 和 域名探测 功能对待检测网站进行资产收集,通过 端口扫描、指纹识别、目录识别 和 信息泄露检测 功能对待检测网站进行信息收集,通过收集的信息分析评估网站存在哪些安全隐患,然后使用 漏洞检测 功能揭示网站存在的漏洞以及危害等级并给出修复建议。通过这一系列的步骤,可以对 Web 应用进行全面检测,从而发现网站存在的安全隐患,因此用户可以针对相应的网络威胁做出应急响应,进而提升站点的安全性。
相关技术
| 名称 | Python | Django | SQLite | ECharts | Tabler | Layer | Docsify | SimpleUI | Boostrap Table |
|---|---|---|---|---|---|---|---|---|---|
| 版本 | 3.7.0 | 3.1.4 | 3.35.2 | 5.0.1 | 1.0.0 | 3.2.0 | 4.11.6 | 2021.1.1 | 1.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<document.getElementsByName("scan_type").length; i++) {
if (document.getElementsByName("scan_type")[i].checked) {
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>.*)$” 接收传入的 target_id,在 views 里对应函数的第二个形参名必须和 <> 里的值一致才有效。核心代码如下:
path('vulnscan', views.vulnscan, name="vulnscan"),
for target_id in target_ids:
#使用正则匹配获取第二个参数:taget_id
urlpatterns.append(url(r'^vuln_result/(?P<target_id>.*)$', 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 %}
……………
# 这个只展示了扫描目标列,其他列类似
<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/(?P<vuln_id>.*)$', views.vuln_detail, name='vuln_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'], features="html.parser").findAll('span')
request_list = BeautifulSoup(data['details'], features="html.parser").findAll('li')
data_dict = {
'affects_url': data['affects_url'],
'last_seen': re.sub(r'T|\..*$', " ", 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('class="bb-dark"','style="color: #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_key=True)
url = models.CharField(max_length=100, null=True)
status = models.CharField(max_length=20, null=True)
result = models.CharField(max_length=100, null=True)
CVE_id = models.CharField(max_length=100, null=True)
time = models.CharField(max_length=100, null=True, unique=True)
在添加目标和开始检测的时候我们需要插入数据库和查询数据库,这里使用 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, result=None, status="runing"):
try:
Middleware_vuln.objects.create(url=url, status=status, result=result, CVE_id=CVE_id, time=Time)
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(url=url, status='runing', CVE_id=CVE_id, time=Time).update(status="completed", result=result)
print("update success")
except:
print("data updata error")
在 views.py 里定义 Middleware_scan() 获取用户输入,并插入到数据库中,其中时间戳 Time 为全局变量,作为后面开始扫描部分查询数据库的条件,在插入数据成功就返回 success(),否侧返回 error(),这里返回的函数时返回的状态码,success()返回的是 200,error()返回 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(url=url, status='runing', CVE_id=CVE_id, time=Time)
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_workers=THREADNUM) as executor:
executor.map(self.socket_scan, hosts)
except EOFError:
pass
端口查询表
端口查询表功能通过收集网上端口信息建立端口查询库,涉及到的端口数据是存储在数据库中,包括端口 ID、端口号、端口对应服务、端口对应协议和端口所属状态。端口查询表结构如下表所示。
| 字段名 | 字段类型 | 允许空 | 是否主键 | 备注 |
|---|---|---|---|---|
| id | integer | Not null | True | 端口 ID |
| num | bigint | Not null | False | 端口号 |
| service | text | Not null | False | 端口对应服务 |
| protocol | Varchar(20) | Not null | False | 端口对应协议 |
| status | Varchar(10) | Not null | False | 端口所属状态 |
端口查询数据库采用 Django Model 进行建立,字段包含端口号、服务、协议、和状态。实现代码如下:
class PortList(models.Model):
'''端口查询表'''
num=models.BigIntegerField(verbose_name='端口号')
service=models.TextField(max_length=100,verbose_name='服务')
protocol=models.CharField(max_length=20,verbose_name='
协议',blank=True,default='未知')
status=models.CharField(max_length=10,verbose_name='
状态',blank=True,default='未知')
class Meta:
# 后台表头设置
verbose_name=verbose_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 和 TIMR,URL 下又分为 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_width
class Item(models.Model):
'''导航条目'''
title = models.CharField(max_length=50,verbose_name='名称')
desc = models.TextField(max_length=100,verbose_name='描述')
url = models.URLField(verbose_name='网址',blank=True)
img = models.URLField(default='https://jwt1399.top/favicon.png',verbose_name='logo')
img_width = models.IntegerField(default=45, verbose_name='图片宽度')
category = models.ForeignKey(Category, blank=True, null=True, verbose_name='分类', on_delete=models.CASCADE)
class Meta:
verbose_name=verbose_name_plural='导航条目'
#后台条目图片预览
def img_admin(self):
return format_html( '<img src="{}" width="50px" height="50px" style="border-radius: 50%;" />',self.img,)
img_admin.short_description = 'logo预览'
def __str__(self):
return self.title
条目分类-Category
名称 name 排序 sort 是否添加到导航栏 add_menu 图标 icon
class Category(models.Model):
"""条目分类"""
name = models.CharField(max_length=20, verbose_name='名称')
sort = models.IntegerField(default=1, verbose_name='显示顺序')
add_menu = models.BooleanField(default=True, verbose_name='添加到导航栏')
icon = models.CharField(max_length=30, default='fas fa-home',verbose_name='图标')
class Meta:
verbose_name_plural=verbose_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('<h1><i class="{}"></i></h1>',self.icon) #转化为<i class="{self.icon}"></i>
icon_data.short_description = '图标预览'
def __str__(self):
return self.name
这两年,IT行业面临经济周期波动与AI产业结构调整的双重压力,确实有很多运维与网络工程师因企业缩编或技术迭代而暂时失业。
很多人都在提运维网工失业后就只能去跑滴滴送外卖了,但我想分享的是,对于运维人员来说,即便失业以后仍然有很多副业可以尝试。
网工/运维/测试副业方向
运维网工,千万不要再错过这些副业机会!
第一个是知识付费类副业:输出经验打造个人IP
在线教育平台讲师
操作路径:在慕课网、极客时间等平台开设《CCNA实战》《Linux运维从入门到精通》等课程,或与培训机构合作录制专题课。
收益模式:课程销售分成、企业内训。
技术博客与公众号运营
操作路径:撰写网络协议解析、故障排查案例、设备评测等深度文章,通过公众号广告、付费专栏及企业合作变现。
收益关键:每周更新2-3篇原创,结合SEO优化与社群运营。
第二个是技术类副业:深耕专业领域变现
企业网络设备配置与优化服务
操作路径:为中小型企业提供路由器、交换机、防火墙等设备的配置调试、性能优化及故障排查服务。可通过本地IT服务公司合作或自建线上接单平台获客。
收益模式:按项目收费或签订年度维护合同。
远程IT基础设施代维
操作路径:通过承接服务器监控、日志分析、备份恢复等远程代维任务。适合熟悉Zabbix、ELK等技术栈的工程师。
收益模式:按工时计费或包月服务。
网络安全顾问与渗透测试
操作路径:利用OWASP Top 10漏洞分析、Nmap/BurpSuite等工具,为企业提供漏洞扫描、渗透测试及安全加固方案。需考取CISP等认证提升资质。
收益模式:单次渗透测试报告收费;长期安全顾问年费。
比如不久前跟我一起聊天的一个粉丝,他自己之前是大四实习的时候做的运维,发现运维7*24小时待命受不了,就准备转网安,学了差不多2个月,然后开始挖漏洞,光是补天的漏洞奖励也有个四五千,他说自己每个月的房租和饭钱就够了。

为什么我会推荐你网安是运维和网工测试人员的绝佳副业&转型方向?
1.你的经验是巨大优势: 你比任何人都懂系统、网络和架构。漏洞挖掘、内网渗透、应急响应,这些核心安全能力本质上是“攻击视角下的运维”。你的运维背景不是从零开始,而是降维打击。
2.越老越吃香,规避年龄危机: 安全行业极度依赖经验。你的排查思路、风险意识和对复杂系统的理解能力,会随着项目积累而愈发珍贵,真正做到“姜还是老的辣”。
3.职业选择极其灵活: 你可以加入企业成为安全专家,可以兼职“挖洞“获取丰厚奖金,甚至可以成为自由顾问。这种多样性为你提供了前所未有的抗风险能力。
4.市场需求爆发,前景广阔: 在国家级政策的推动下,从一线城市到二三线地区,安全人才缺口正在急剧扩大。现在布局,正是抢占未来先机的黄金时刻。

网工运维测试转行学习网络安全路线

(一)第一阶段:网络安全筑基
1. 阶段目标
你已经有运维经验了,所以操作系统、网络协议这些你不是零基础。但要学安全,得重新过一遍——只不过这次我们是带着“安全视角”去学。
2. 学习内容
**操作系统强化:**你需要重点学习 Windows、Linux 操作系统安全配置,对比运维工作中常规配置与安全配置的差异,深化系统安全认知(比如说日志审计配置,为应急响应日志分析打基础)。
**网络协议深化:**结合过往网络协议应用经验,聚焦 TCP/IP 协议簇中的安全漏洞及防护机制,如 ARP 欺骗、TCP 三次握手漏洞等(为 SRC 漏扫中协议层漏洞识别铺垫)。
**Web 与数据库基础:**补充 Web 架构、HTTP 协议及 MySQL、SQL Server 等数据库安全相关知识,了解 Web 应用与数据库在网安中的作用。
**编程语言入门:**学习 Python 基础语法,掌握简单脚本编写,为后续 SRC 漏扫自动化脚本开发及应急响应工具使用打基础。
**工具实战:**集中训练抓包工具(Wireshark)、渗透测试工具(Nmap)、漏洞扫描工具(Nessus 基础版)的使用,结合模拟场景练习工具应用(掌握基础扫描逻辑,为 SRC 漏扫工具进阶做准备)。
(二)第二阶段:漏洞挖掘与 SRC 漏扫实战
1. 阶段目标
这阶段是真正开始“动手”了。信息收集、漏洞分析、工具联动,一样不能少。
熟练运用漏洞挖掘及 SRC 漏扫工具,具备独立挖掘常见漏洞及 SRC 平台漏扫实战能力,尝试通过 SRC 挖洞搞钱,不管是低危漏洞还是高危漏洞,先挖到一个。
2. 学习内容
信息收集实战:结合运维中对网络拓扑、设备信息的了解,强化基本信息收集、网络空间搜索引擎(Shodan、ZoomEye)、域名及端口信息收集技巧,针对企业级网络场景开展信息收集练习(为 SRC 漏扫目标筛选提供支撑)。
漏洞原理与分析:深入学习 SQL 注入、CSRF、文件上传等常见漏洞的原理、危害及利用方法,结合运维工作中遇到的类似问题进行关联分析(明确 SRC 漏扫重点漏洞类型)。
工具进阶与 SRC 漏扫应用:
-
系统学习 SQLMap、BurpSuite、AWVS 等工具的高级功能,开展工具联用实战训练;
-
专项学习 SRC 漏扫流程:包括 SRC 平台规则解读(如漏洞提交规范、奖励机制)、漏扫目标范围界定、漏扫策略制定(全量扫描 vs 定向扫描)、漏扫结果验证与复现;
-
实战训练:使用 AWVS+BurpSuite 组合开展 SRC 平台目标漏扫,练习 “扫描 - 验证 - 漏洞报告撰写 - 平台提交” 全流程。
SRC 实战演练:选择合适的 SRC 平台(如补天、CNVD)进行漏洞挖掘与漏扫实战,积累实战经验,尝试获取挖洞收益。
恭喜你,如果学到这里,你基本可以下班搞搞副业创收了,并且具备渗透测试工程师必备的「渗透技巧」、「溯源能力」,让你在黑客盛行的年代别背锅,工作实现升职加薪的同时也能开创副业创收!
如果你想要入坑黑客&网络安全,笔者给大家准备了一份:全网最全的网络安全资料包需要保存下方图片,微信扫码即可前往获取!
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
(三)第三阶段:渗透测试技能学习
1. 阶段目标
全面掌握渗透测试理论与实战技能,能够独立完成渗透测试项目,编写规范的渗透测试报告,具备渗透测试工程师岗位能力,为护网红蓝对抗及应急响应提供技术支撑。
2. 学习内容
渗透测试核心理论:系统学习渗透测试流程、方法论及法律法规知识,明确渗透测试边界与规范(与红蓝对抗攻击边界要求一致)。
实战技能训练:开展漏洞扫描、漏洞利用、电商系统渗透测试、内网渗透、权限提升(Windows、Linux)、代码审计等实战训练,结合运维中熟悉的系统环境设计测试场景(强化红蓝对抗攻击端技术能力)。
工具开发实践:基于 Python 编程基础,学习渗透测试工具开发技巧,开发简单的自动化测试脚本(可拓展用于 SRC 漏扫自动化及应急响应辅助工具)。
报告编写指导:学习渗透测试报告的结构与编写规范,完成多个不同场景的渗透测试报告撰写练习(与 SRC 漏洞报告、应急响应报告撰写逻辑互通)。
(四)第四阶段:企业级安全攻防(含红蓝对抗)、应急响应
1. 阶段目标
掌握企业级安全攻防、护网红蓝对抗及应急响应核心技能,考取网安行业相关证书。
2. 学习内容
护网红蓝对抗专项:
-
红蓝对抗基础:学习护网行动背景、红蓝对抗规则(攻击范围、禁止行为)、红蓝双方角色职责(红队:模拟攻击;蓝队:防御检测与应急处置);
-
红队实战技能:强化内网渗透、横向移动、权限维持、免杀攻击等高级技巧,模拟护网中常见攻击场景;
-
蓝队实战技能:学习安全设备(防火墙、IDS/IPS、WAF)联动防御配置、安全监控平台(SOC)使用、攻击行为研判与溯源方法;
-
模拟护网演练:参与团队式红蓝对抗演练,完整体验 “攻击 - 检测 - 防御 - 处置” 全流程。
应急响应专项: -
应急响应流程:学习应急响应 6 步流程(准备 - 检测 - 遏制 - 根除 - 恢复 - 总结),掌握各环节核心任务;
-
实战技能:开展操作系统入侵响应(如病毒木马清除、异常进程终止)、数据泄露应急处置、漏洞应急修补等实战训练;
-
工具应用:学习应急响应工具(如 Autoruns、Process Monitor、病毒分析工具)的使用,提升处置效率;
-
案例复盘:分析真实网络安全事件应急响应案例(如勒索病毒事件),总结处置经验。
其他企业级攻防技能:学习社工与钓鱼、CTF 夺旗赛解析等内容,结合运维中企业安全防护需求深化理解。
证书备考:针对网安行业相关证书考试内容(含红蓝对抗、应急响应考点)进行专项复习,参加模拟考试,查漏补缺。
运维网工测试转行网络攻防知识库分享
网络安全这行,不是会几个工具就能搞定的。你得有体系,懂原理,能实战。尤其是从运维转过来的,别浪费你原来的经验——你比纯新人强多了。
但也要沉得住气,别学了两天Web安全就觉得自己是黑客了。内网、域渗透、代码审计、应急响应,要学的还多着呢。
如果你真的想转,按这个路子一步步走,没问题。如果你只是好奇,我劝你再想想——这行要持续学习,挺累的,但也是真有意思。
关于如何学习网络安全,笔者也给大家整理好了全套网络安全知识库,需要的可以扫码获取!
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
1、网络安全意识

2、Linux操作系统

3、WEB架构基础与HTTP协议

4、Web渗透测试

5、渗透测试案例分享

6、渗透测试实战技巧

7、攻防对战实战

8、CTF之MISC实战讲解

关于如何学习网络安全,笔者也给大家整理好了全套网络安全知识库,需要的可以扫码获取!
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取


被折叠的 条评论
为什么被折叠?



