This repository was archived by the owner on Dec 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 282
/
Copy pathviews.py
142 lines (125 loc) · 5.34 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#coding=utf-8
from scanner.serializers import SqliScanTaskSerializer
from scanner.models import SqliScanTask
from rest_framework import viewsets, filters
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from scanner.tasks import SqlScanTask
import redis
import os
import json
import re
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return
@method_decorator(login_required, name='dispatch')
class SqliScanTaskViewSet(viewsets.ModelViewSet):
"""
查看所有 SQLi 扫描任务
"""
queryset = SqliScanTask.objects.all()
serializer_class = SqliScanTaskSerializer
authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('vulnerable', 'target_host')
@login_required
@csrf_exempt
def addtaskbyhar(request):
if request.method == 'POST' and str(request.FILES['file']).split('.')[-1] == 'har':
handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))
return HttpResponse("done")
return HttpResponse("error")
def handle_uploaded_file(file, filename):
if not os.path.exists('upload/'):
os.mkdir('upload/')
with open('upload/' + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
parse_uploaded_file(filename)
def parse_uploaded_file(filename):
"""
解析 har 文件中的请求,并按照 url 类型处理后提交给任务节点进行扫描
parse uploaded file and scan the target in file
"""
with open('upload/' + filename, 'r') as harf:
scan_url = []
scan_url_path = []
entries = json.loads(harf.read())['log']['entries']
for entrie in entries:
status_code = entrie['response']['status']
scan_options = {}
scan_options['level'] = 1
scan_options['url'] = entrie['request']['url']
scan_options['method'] = entrie['request']['method']
target = scan_options['url'].split('/')
target_path = "/".join(target[3:])
try:
target_path = target_path.split('?')[0]
except:
pass
if status_code != 404 and scan_options['method'] in ['POST', 'GET'] and entrie['request'][
'url'] not in scan_url and target_path not in scan_url_path:
if 'https' in scan_options['url']:
scan_options['forceSSL'] = True
if entrie['request']['cookies']:
scan_options['cookie'] = ";".join(
"{}={}".format(i['name'], i['value']) for i in entrie['request']['cookies'])
if entrie['request']['headers']:
scan_options['headers'] = ";".join(
"'{}':'{}'".format(i['name'], i['value']) for i in entrie['request']['headers'])
for i in entrie['request']['headers']:
if i['name'] == 'Referer':
scan_options['referer'] = i['value']
if scan_options['method'] == 'GET':
scan_options = handle_get_request_entrie(entrie, scan_options)
else:
scan_options = handle_post_request_entrie(entrie, scan_options)
try:
sqli = SqliScanTask.objects.create(target_url=scan_options['url'], scan_options=scan_options)
s = SqlScanTask(sqli)
s.run.delay(s)
scan_url.append(entrie['request']['url'])
scan_url_path.append(scan_url_path)
except:
pass
def handle_get_request_entrie(entrie, scan_options):
if not entrie['request']['queryString']:
nodes = scan_options['url'].split('/')
for node in nodes:
if '.' not in node and re.findall('(\d+)', node):
scan_options['url'] = scan_options['url'].replace(node, node + '*')
elif '.html' in node and re.findall('(\d+)', node):
scan_options['url'] = scan_options['url'].replace(node, node.replace('.', '*.'))
else:
pass
return scan_options
def handle_post_request_entrie(entrie, scan_options):
try:
scan_options['data'] = "&".join(
"{}={}".format(i['name'], i['value']) for i in entrie['request']['postData']['params'])
except:
pass
return scan_options
@login_required
@csrf_exempt
def taskstat(request):
stat_db = redis.Redis(host='localhost', port=6379, db=0)
if not stat_db.exists('tasks'):
hosts = []
for target in SqliScanTask.objects.all():
s = {'name': target.target_host, 'value': len(SqliScanTask.objects.filter(target_host=target.target_host))}
if s not in hosts:
hosts.append(s)
else:
pass
stat_db.set('tasks', json.dumps(hosts), ex=500)
else:
pass
data = stat_db.get('tasks')
return HttpResponse(data)
def index(request):
return render_to_response('index.html')