mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-09-18 15:57:44 +02:00
365 lines
14 KiB
Python
365 lines
14 KiB
Python
from django.shortcuts import render, get_object_or_404
|
|
from django.contrib import messages
|
|
from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
|
|
from django.urls import reverse
|
|
from startScan.models import ScanHistory, ScannedHost, ScanActivity, WayBackEndPoint, VulnerabilityScan
|
|
from django_celery_beat.models import PeriodicTask, IntervalSchedule, ClockedSchedule
|
|
from notification.models import NotificationHooks
|
|
from targetApp.models import Domain
|
|
from scanEngine.models import EngineType, Configuration
|
|
from django.utils import timezone
|
|
from django.conf import settings
|
|
from datetime import datetime
|
|
from reNgine.tasks import doScan
|
|
from reNgine.celery import app
|
|
import os
|
|
import requests
|
|
|
|
|
|
def scan_history(request):
|
|
host = ScanHistory.objects.all().order_by('-last_scan_date')
|
|
context = {'scan_history_active': 'true', "scan_history": host}
|
|
return render(request, 'startScan/history.html', context)
|
|
|
|
|
|
def detail_scan(request, id=None):
|
|
if id:
|
|
subdomain_count = ScannedHost.objects.filter(scan_history__id=id).count()
|
|
alive_count = ScannedHost.objects.filter(
|
|
scan_history__id=id).exclude(
|
|
http_status__exact=0).count()
|
|
scan_activity = ScanActivity.objects.filter(
|
|
scan_of__id=id).order_by('time')
|
|
endpoint_count = WayBackEndPoint.objects.filter(url_of__id=id).count()
|
|
endpoint_alive_count = WayBackEndPoint.objects.filter(
|
|
url_of__id=id, http_status__exact=200).count()
|
|
subdomain_takeover_count = ScannedHost.objects.filter(
|
|
scan_history__id=id, takeover__isnull=False).count()
|
|
history = get_object_or_404(ScanHistory, id=id)
|
|
info_count = VulnerabilityScan.objects.filter(
|
|
vulnerability_of__id=id, severity=0).count()
|
|
low_count = VulnerabilityScan.objects.filter(
|
|
vulnerability_of__id=id, severity=1).count()
|
|
medium_count = VulnerabilityScan.objects.filter(
|
|
vulnerability_of__id=id, severity=2).count()
|
|
high_count = VulnerabilityScan.objects.filter(
|
|
vulnerability_of__id=id, severity=3).count()
|
|
critical_count = VulnerabilityScan.objects.filter(
|
|
vulnerability_of__id=id, severity=4).count()
|
|
total_vulnerability_count = info_count + low_count + \
|
|
medium_count + high_count + critical_count
|
|
context = {'scan_history_active': 'true',
|
|
'scan_history': scan_history,
|
|
'scan_activity': scan_activity,
|
|
'alive_count': alive_count,
|
|
'scan_history_id': id,
|
|
'subdomain_count': subdomain_count,
|
|
'endpoint_count': endpoint_count,
|
|
'endpoint_alive_count': endpoint_alive_count,
|
|
'history': history,
|
|
'subdomain_takeover_count': subdomain_takeover_count,
|
|
'info_count': info_count,
|
|
'low_count': low_count,
|
|
'medium_count': medium_count,
|
|
'high_count': high_count,
|
|
'critical_count': critical_count,
|
|
'total_vulnerability_count': total_vulnerability_count,
|
|
}
|
|
else:
|
|
context = {}
|
|
return render(request, 'startScan/detail_scan.html', context)
|
|
|
|
|
|
def detail_vuln_scan(request, id=None):
|
|
if id:
|
|
history = get_object_or_404(ScanHistory, id=id)
|
|
context = {'scan_history_id': id, 'history': history}
|
|
else:
|
|
context = {'vuln_scan_active': 'true'}
|
|
return render(request, 'startScan/detail_vuln_scan.html', context)
|
|
|
|
|
|
def detail_endpoint_scan(request, id=None):
|
|
if id:
|
|
history = get_object_or_404(ScanHistory, id=id)
|
|
context = {'scan_history_id': id, 'history': history}
|
|
else:
|
|
context = {}
|
|
return render(request, 'startScan/detail_endpoint_scan.html', context)
|
|
|
|
|
|
def start_scan_ui(request, host_id):
|
|
domain = get_object_or_404(Domain, id=host_id)
|
|
if request.method == "POST":
|
|
# get engine type
|
|
engine_type = request.POST['scan_mode']
|
|
scan_history_id = create_scan_object(host_id, engine_type)
|
|
# start the celery task
|
|
celery_task = doScan.apply_async(
|
|
args=(host_id, scan_history_id, 0, None))
|
|
ScanHistory.objects.filter(
|
|
id=scan_history_id).update(
|
|
celery_id=celery_task.id)
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Scan Started for ' +
|
|
domain.domain_name)
|
|
return HttpResponseRedirect(reverse('scan_history'))
|
|
engine = EngineType.objects.order_by('id')
|
|
custom_engine_count = EngineType.objects.filter(
|
|
default_engine=False).count()
|
|
context = {
|
|
'scan_history_active': 'true',
|
|
'domain': domain,
|
|
'engines': engine,
|
|
'custom_engine_count': custom_engine_count}
|
|
return render(request, 'startScan/start_scan_ui.html', context)
|
|
|
|
|
|
def start_multiple_scan(request):
|
|
# domain = get_object_or_404(Domain, id=host_id)
|
|
domain_text = ""
|
|
if request.method == "POST":
|
|
if request.POST.get('scan_mode', 0):
|
|
# if scan mode is available, then start the scan
|
|
# get engine type
|
|
engine_type = request.POST['scan_mode']
|
|
list_of_domains = request.POST['list_of_domain_id']
|
|
for domain_id in list_of_domains.split(","):
|
|
# start the celery task
|
|
scan_history_id = create_scan_object(domain_id, engine_type)
|
|
celery_task = doScan.apply_async(
|
|
args=(domain_id, scan_history_id, 0, None))
|
|
ScanHistory.objects.filter(
|
|
id=scan_history_id).update(
|
|
celery_id=celery_task.id)
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Scan Started for multiple targets')
|
|
return HttpResponseRedirect(reverse('scan_history'))
|
|
else:
|
|
# this else condition will have post request from the scan page
|
|
# containing all the targets id
|
|
list_of_domain_name = []
|
|
list_of_domain_id = []
|
|
for key, value in request.POST.items():
|
|
if key != "style-2_length" and key != "csrfmiddlewaretoken":
|
|
domain = get_object_or_404(Domain, id=value)
|
|
list_of_domain_name.append(domain.domain_name)
|
|
list_of_domain_id.append(value)
|
|
domain_text = ", ".join(list_of_domain_name)
|
|
domain_ids = ",".join(list_of_domain_id)
|
|
engine = EngineType.objects
|
|
custom_engine_count = EngineType.objects.filter(
|
|
default_engine=False).count()
|
|
context = {
|
|
'scan_history_active': 'true',
|
|
'engines': engine,
|
|
'domain_list': domain_text,
|
|
'domain_ids': domain_ids,
|
|
'custom_engine_count': custom_engine_count}
|
|
return render(request, 'startScan/start_multiple_scan_ui.html', context)
|
|
|
|
|
|
def export_subdomains(request, scan_id):
|
|
subdomain_list = ScannedHost.objects.filter(scan_history__id=scan_id)
|
|
domain_results = ScanHistory.objects.get(id=scan_id)
|
|
response_body = ""
|
|
for subdomain in subdomain_list:
|
|
response_body = response_body + subdomain.subdomain + "\n"
|
|
response = HttpResponse(response_body, content_type='text/plain')
|
|
response['Content-Disposition'] = 'attachment; filename="subdomains_' + \
|
|
domain_results.domain_name.domain_name + '_' + \
|
|
str(domain_results.last_scan_date.date()) + '.txt"'
|
|
return response
|
|
|
|
|
|
def export_endpoints(request, scan_id):
|
|
endpoint_list = WayBackEndPoint.objects.filter(url_of__id=scan_id)
|
|
domain_results = ScanHistory.objects.get(id=scan_id)
|
|
response_body = ""
|
|
for endpoint in endpoint_list:
|
|
response_body = response_body + endpoint.http_url + "\n"
|
|
response = HttpResponse(response_body, content_type='text/plain')
|
|
response['Content-Disposition'] = 'attachment; filename="endpoints_' + \
|
|
domain_results.domain_name.domain_name + '_' + \
|
|
str(domain_results.last_scan_date.date()) + '.txt"'
|
|
return response
|
|
|
|
|
|
def export_urls(request, scan_id):
|
|
urls_list = ScannedHost.objects.filter(scan_history__id=scan_id)
|
|
domain_results = ScanHistory.objects.get(id=scan_id)
|
|
response_body = ""
|
|
for url in urls_list:
|
|
if url.http_url:
|
|
response_body = response_body + url.http_url + "\n"
|
|
response = HttpResponse(response_body, content_type='text/plain')
|
|
response['Content-Disposition'] = 'attachment; filename="urls_' + \
|
|
domain_results.domain_name.domain_name + '_' + \
|
|
str(domain_results.last_scan_date.date()) + '.txt"'
|
|
return response
|
|
|
|
|
|
def delete_scan(request, id):
|
|
obj = get_object_or_404(ScanHistory, id=id)
|
|
if request.method == "POST":
|
|
delete_dir = obj.domain_name.domain_name + '_' + \
|
|
str(datetime.strftime(obj.last_scan_date, '%Y_%m_%d_%H_%M_%S'))
|
|
delete_path = settings.TOOL_LOCATION + 'scan_results/' + delete_dir
|
|
os.system('rm -rf ' + delete_path)
|
|
obj.delete()
|
|
messageData = {'status': 'true'}
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Scan history successfully deleted!')
|
|
else:
|
|
messageData = {'status': 'false'}
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Oops! something went wrong!')
|
|
return JsonResponse(messageData)
|
|
|
|
|
|
def stop_scan(request, id):
|
|
obj = get_object_or_404(ScanHistory, celery_id=id)
|
|
if request.method == "POST":
|
|
# stop the celery task
|
|
app.control.revoke(id, terminate=True, signal='SIGKILL')
|
|
obj.scan_status = 3
|
|
obj.save()
|
|
messageData = {'status': 'true'}
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Scan successfully stopped!')
|
|
else:
|
|
messageData = {'status': 'false'}
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Oops! something went wrong!')
|
|
return JsonResponse(messageData)
|
|
|
|
|
|
def schedule_scan(request, host_id):
|
|
domain = Domain.objects.get(id=host_id)
|
|
if request.method == "POST":
|
|
# get engine type
|
|
engine_type = int(request.POST['scan_mode'])
|
|
engine_object = get_object_or_404(EngineType, id=engine_type)
|
|
task_name = engine_object.engine_name + ' for ' + \
|
|
domain.domain_name + \
|
|
':' + \
|
|
str(datetime.strftime(timezone.now(), '%Y_%m_%d_%H_%M_%S'))
|
|
if request.POST['scheduled_mode'] == 'periodic':
|
|
# periodic task
|
|
frequency_value = int(request.POST['frequency'])
|
|
frequency_type = request.POST['frequency_type']
|
|
if frequency_type == 'minutes':
|
|
period = IntervalSchedule.MINUTES
|
|
elif frequency_type == 'hours':
|
|
period = IntervalSchedule.HOURS
|
|
elif frequency_type == 'days':
|
|
period = IntervalSchedule.DAYS
|
|
elif frequency_type == 'weeks':
|
|
period = IntervalSchedule.DAYS
|
|
frequency_value *= 7
|
|
elif frequency_type == 'months':
|
|
period = IntervalSchedule.DAYS
|
|
frequency_value *= 30
|
|
|
|
schedule, created = IntervalSchedule.objects.get_or_create(
|
|
every=frequency_value,
|
|
period=period,)
|
|
PeriodicTask.objects.create(interval=schedule,
|
|
name=task_name,
|
|
task='reNgine.tasks.doScan',
|
|
args=[host_id, 0, 1, engine_type])
|
|
elif request.POST['scheduled_mode'] == 'clocked':
|
|
# clocked task
|
|
schedule_time = request.POST['scheduled_time']
|
|
clock, created = ClockedSchedule.objects.get_or_create(
|
|
clocked_time=schedule_time,)
|
|
PeriodicTask.objects.create(clocked=clock,
|
|
one_off=True,
|
|
name=task_name,
|
|
task='reNgine.tasks.doScan',
|
|
args=[host_id, 0, 1, engine_type])
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Scan Scheduled for ' +
|
|
domain.domain_name)
|
|
return HttpResponseRedirect(reverse('scheduled_scan_view'))
|
|
engine = EngineType.objects
|
|
custom_engine_count = EngineType.objects.filter(
|
|
default_engine=False).count()
|
|
context = {
|
|
'scan_history_active': 'true',
|
|
'domain': domain,
|
|
'engines': engine,
|
|
'custom_engine_count': custom_engine_count}
|
|
return render(request, 'startScan/schedule_scan_ui.html', context)
|
|
|
|
|
|
def scheduled_scan_view(request):
|
|
scheduled_tasks = PeriodicTask.objects.all().exclude(name='celery.backend_cleanup')
|
|
context = {
|
|
'scheduled_scan_active': 'true',
|
|
'scheduled_tasks': scheduled_tasks,
|
|
}
|
|
return render(request, 'startScan/schedule_scan_list.html', context)
|
|
|
|
|
|
def delete_scheduled_task(request, id):
|
|
task_object = get_object_or_404(PeriodicTask, id=id)
|
|
if request.method == "POST":
|
|
task_object.delete()
|
|
messageData = {'status': 'true'}
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Scheduled Scan successfully deleted!')
|
|
else:
|
|
messageData = {'status': 'false'}
|
|
messages.add_message(
|
|
request,
|
|
messages.INFO,
|
|
'Oops! something went wrong!')
|
|
return JsonResponse(messageData)
|
|
|
|
|
|
def change_scheduled_task_status(request, id):
|
|
if request.method == 'POST':
|
|
task = PeriodicTask.objects.get(id=id)
|
|
task.enabled = not task.enabled
|
|
task.save()
|
|
return HttpResponse('')
|
|
|
|
|
|
def create_scan_object(host_id, engine_type):
|
|
'''
|
|
create task with pending status so that celery task will execute when
|
|
threads are free
|
|
'''
|
|
# get current time
|
|
current_scan_time = timezone.now()
|
|
# fetch engine and domain object
|
|
engine_object = EngineType.objects.get(pk=engine_type)
|
|
domain = Domain.objects.get(pk=host_id)
|
|
task = ScanHistory()
|
|
task.scan_status = -1
|
|
task.domain_name = domain
|
|
task.scan_type = engine_object
|
|
task.last_scan_date = current_scan_time
|
|
task.save()
|
|
# save last scan date for domain model
|
|
domain.last_scan_date = current_scan_time
|
|
domain.save()
|
|
return task.id
|