使用Django框架开发nmap扫描接口,实现自动化扫描,并将扫描结果存入数据库。
首先使用Pycharm创建Django项目
之后使用命令django-admin.py startapp NmapAPI 创建Nmap API app
1 django-admin.py startapp NmapAPI
编写扫描代码,命名为do_scan
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import subprocess 4 import Analysis_xml 5 import os 6 7 8 def scan(target, options, task_id): 9 task_id = str(task_id) 10 11 child = subprocess.Popen(\'nmap %s %s -oX /root/nmap_scan/%s\' % (options, target, target), 12 shell=True)#使用nmap扫描,将扫描结果保存为xml格式 13 pid = child.pid#获取进程ID 14 xml = Analysis_xml.xml_db(task_id, pid, target) 15 child.wait() 16 xml.parse_xml()#解析xml格式数据 17 18 19 def scan_status(target): 20 21 return os.path.exists(\'/root/nmap_scan/%s\' % target)#检查文件是否存在,若存在表示程序正常执行,反之则执行失败
接下来编写入口程序,使用多进程扫描,命名为view
# coding:utf-8 from django.shortcuts import render from django.http import HttpResponse import json import do_scan import time import multiprocessing import random def index(request): return render(request, "scan.html") def scan(request): if request.method == "GET": return render(request, "scan.html") if request.method == "POST": scan_target = request.POST.get("target", None) scan_options = request.POST.get("config1", None) scan_task_id = random.randint(1000000000, 9999999999) pool = multiprocessing.Pool(processes=10)#使用进程池,同时可执行10个进程 i = scan_target.split()#对多个目标地址进行分割 for target in i: pool.apply_async(do_scan.scan, (target, scan_options, scan_task_id)) # pool.close() # pool.join() success_data = {"errcode": "0", "errmsg": "ok", "info": { "taskid": scan_task_id, } } fail_data = {"errcode": "1", "errmsg": "fail", "info": { "taskid": None } } time.sleep(0.5) status = do_scan.scan_status(i[0]) if status: return HttpResponse(json.dumps(success_data)) else: return HttpResponse(json.dumps(fail_data))
nmap扫描结果保存为xml格式,接着编写xml格式解析模块,并进行入库
1 #!/usr/bin/env python 2 # -*- coding=utf-8 -*- 3 4 from xml.etree import ElementTree 5 from NmapAPI import models 6 import os 7 8 9 class xml_db: 10 def __init__(self, task_id, pid, targets): 11 12 self.args = None 13 self.timestr = None 14 self.hostname = [] 15 self.Version = [] 16 self.ports_list = [] 17 self.state_list = [] 18 self.service_list = [] 19 self.info_list = [] 20 self.task_id = task_id 21 self.targets = targets 22 self.pid = pid 23 24 def parse_xml(self): 25 26 filepath = \'/root/nmap_scan/\' + self.targets 27 with open(filepath, \'rt\') as f: 28 tree = ElementTree.parse(f) 29 30 for ele in tree.iter("nmaprun"): 31 self.args = ele.attrib.get(\'args\') 32 33 for time in tree.iter("finished"): 34 self.timestr = time.attrib.get(\'timestr\') 35 36 for names in tree.iter("hostname"): 37 name = names.attrib.get("name") 38 self.hostname.append(name) 39 self.hostname = self.hostname[0] 40 41 for versions in tree.iter("service"): 42 version = versions.attrib.get("product") 43 self.Version.append(version) 44 45 for ports in tree.iter("port"): 46 port = ports.attrib.get("portid") 47 self.ports_list.append(port) 48 49 for states in tree.iter("state"): 50 state = states.attrib.get(\'state\') 51 self.state_list.append(state) 52 53 for services in tree.iter("service"): 54 service = services.attrib.get(\'name\') 55 self.service_list.append(service) 56 57 for i in range(len(self.ports_list)): 58 add = models.scan_info(task_id=self.task_id, pid=self.pid, hostname=self.hostname, port=self.ports_list[i], 59 version=self.Version[i], state=self.state_list[i], service=self.service_list[i], 60 args=self.args, timestr=self.timestr) 61 add.save() 62 os.system(\'rm -rf /root/nmap_scan/%s\' % self.hostname) 63 i += 1
数据库模块
1 from __future__ import unicode_literals 2 from django.db import models 3 4 5 class scan_info(models.Model): 6 7 task_id = models.CharField(max_length=10) 8 pid = models.CharField(max_length=10) 9 hostname = models.CharField(max_length=50) 10 port = models.CharField(max_length=5) 11 version = models.CharField(max_length=50, null=True) 12 state = models.CharField(max_length=5) 13 service = models.CharField(max_length=10) 14 args = models.CharField(max_length=100) 15 timestr = models.CharField(max_length=100) 16 17 def __unicode__(self): 18 return self.task_id
和数据库进行连接前需执行两条命令
1 python manage.py makemigrations 2 python manage.py migrate
配置settings文件
增加database配置
1 DATABASES = { 2 \'default\': { 3 \'ENGINE\': \'django.db.backends.mysql\', 4 \'NAME\': \'Data_information\', 5 \'USER\': \'root\', 6 \'PASSWORD\': \'\', 7 \'HOST\': \'\', 8 \'PORT\': \'\', 9 } 10 }
注释csrf并且允许外部主机访问
1 ALLOWED_HOSTS = [\'*\']#允许所有主机进行访问 2 3 4 # Application definition 5 6 INSTALLED_APPS = [ 7 \'django.contrib.admin\', 8 \'django.contrib.auth\', 9 \'django.contrib.contenttypes\', 10 \'django.contrib.sessions\', 11 \'django.contrib.messages\', 12 \'django.contrib.staticfiles\', 13 \'NmapAPI\', 14 \'HydraAPI\', 15 ] 16 17 MIDDLEWARE = [ 18 \'django.middleware.security.SecurityMiddleware\', 19 \'django.contrib.sessions.middleware.SessionMiddleware\', 20 \'django.middleware.common.CommonMiddleware\', 21 # \'django.middleware.csrf.CsrfViewMiddleware\',#注释csrf模块 22 \'django.contrib.auth.middleware.AuthenticationMiddleware\', 23 \'django.contrib.messages.middleware.MessageMiddleware\', 24 \'django.middleware.clickjacking.XFrameOptionsMiddleware\', 25 ]