root/branch/UmitWeb/umitWeb/views/scan.py @ 3062

Revision 3062, 9.7 kB (checked in by rcarvalho, 5 years ago)

Added some more svg tests.

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (C) 2005 Insecure.Com LLC.
4#
5# Author: Rodolfo da Silva Carvalho <rodolfo.ueg@gmail.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21from types import *
22from umitWeb.Http import HttpResponse, Http404, Http500, Http403, HttpError
23from umitWeb.Auth import authenticate, ERROR
24from umitWeb.Server import UmitWebServer as server
25from umitWeb.WebLogger import getLogger
26from umitWeb.Json import ScanJsonParser
27from umitCore.NmapCommand import NmapCommand
28from umitCore.NmapParser import NmapParser, HostInfo
29from umitCore.UmitConf import CommandProfile
30from umitCore.UmitDB import Scans, UmitDB
31from urllib import quote
32from tempfile import mktemp
33import random
34import sys
35import os
36#from StringIO import StringIO
37import re
38import md5
39from threading import Thread
40from time import time
41import datetime
42
43
44logger = getLogger(__name__)
45
46@authenticate()
47def index(req):
48    response = HttpResponse()
49    response.loadTemplate("scans.html")
50    return response
51
52
53@authenticate(ERROR)
54def new(req):
55    response = HttpResponse()
56    response['Content-type'] = "text/plain"
57   
58    #Replace dangerous commands
59    command = re.sub(r"[\\;|`&]", "", req.POST['command'])
60    if req.session.user.is_permitted(command):
61        try:
62            nmapCommand = NmapCommand(command)
63            resourceID = server.currentInstance.addResource(nmapCommand)
64            server.currentInstance.fireResourceEvent(resourceID, "run_scan")
65           
66            req.session['command_' + resourceID] = command
67            req.session['profile_' + resourceID] = req.POST['profile_name']
68            req.session['target_' + resourceID] = req.POST['target']
69            response.write("{'result': 'OK', 'status': 'RUNNING', 'id': '%s'}" % resourceID)
70        except Exception, e:
71            response.write("{'result': 'FAIL', 'status': '%s'}" % str(e).replace("'", "\\'"))
72        return response
73    else:
74        raise Http403
75
76
77@authenticate(ERROR)
78def check(req, resource_id):
79    response = HttpResponse()
80    response['Content-type'] = "text/javascript"
81   
82    nmapCommand = server.currentInstance.getResource(resource_id)
83   
84    if nmapCommand is None:
85        raise Http404
86   
87    try:
88        output = nmapCommand.get_output()
89        if nmapCommand.scan_state():
90            response.write("{'result': 'OK', 'status': 'RUNNING', " + \
91                           "'output': {'text': '%s'}}" % output.replace("'", "\\'").replace("\n", "\\n' + \n'"))
92        else:
93            profile = CommandProfile()
94            parser = NmapParser()
95            parser.set_xml_file(nmapCommand.get_xml_output_file())
96            parser.parse()
97
98            parser.profile_name = req.session['profile_' + resource_id]
99            parser.target = req.session['target_' + resource_id]
100            parser.nmap_command = req.session['command_' + resource_id]
101            parser.profile = profile.get_command(parser.profile_name)
102            parser.profile_hint = profile.get_hint(parser.profile_name)
103            parser.profile_description = profile.get_description(parser.profile_name)
104            parser.profile_annotation = profile.get_annotation(parser.profile_name)
105            parser.profile_options = profile.get_options(parser.profile_name)
106            try:
107                parser.nmap_output = nmapCommand.get_raw_output()
108            except:
109                parser.nmap_output = "\\n".join(self.scan_result.get_nmap_output().split("\n"))
110            parsed_scan = ScanJsonParser(parser).parse()
111            text_out = nmapCommand.get_output().replace("'", "\\'").replace("\n", "\\n' + \n'")
112            response.write("{'result': 'OK', 'status': 'FINISHED', 'output':" + \
113                           " {'full': %s, 'plain': '%s'}}" % (parsed_scan, text_out))
114            server.currentInstance.removeResource(resource_id)
115            fname = mktemp()
116            fresult = open(fname, "w", 0)
117            parser.write_xml(fresult)
118            req.session['scan_result_' + resource_id] = open(fname, 'r').read()
119    except Exception, e:
120        if "running" in str(e).lower():
121            response.write("{'result': 'OK', 'status': 'RUNNING', " + \
122                           "'output': {'text': ''}}")
123        else:
124            raise Http500("Nmap command raised an exception!\n%s" % str(e))
125    return response
126
127
128@authenticate(ERROR)
129def upload_result(req):
130    if req.POST:
131        if req.POST['type'] == "file":
132            try:
133                parser = NmapParser()
134                parser.set_xml_file(req.FILES['scan_result']['temp_file'])
135                parser.parse()
136                parsed_scan = ScanJsonParser(parser).parse()
137                junk = r"odpojfsdkjfpisudŕij208u-0w9rsdnfkdfçwrtwqr/fsasd~/???çds"
138                key = md5.new(str(random.randint(0, sys.maxint-1)) \
139                                  + str(random.randint(1, sys.maxint-1)//2) \
140                                  + junk).hexdigest()
141                req.session['scan_result_' + key] = open(req.FILES['scan_result']['temp_name'], 'r').read()
142                text_out = parser.nmap_output.replace("'", "\\'").replace("\r", "").replace("\n", "\\n' + \n'")
143                parsed_scan = str(parsed_scan).replace("\n", "\\n' + \n'")
144                return HttpResponse(("{'result': 'OK', 'id': '%s', 'output': " + \
145                                    "{'plain': '%s', 'full': %s}}") % \
146                                    (key, text_out, parsed_scan), "text/plain")
147            except Exception, ex:
148                return HttpResponse("{'result': 'FAIL', 'output': '%s'}" % str(ex).replace("'", "\\'"), "text/plain")
149        else:
150            scan_id = req.POST['scanId']
151            db = UmitDB()
152            if scan_id not in [str(sid) for sid in db.get_scans_ids()]:
153                return HttpResponse("{'result': 'FAIL', 'output': 'Scan not found!'}")
154           
155            scan = Scans(scans_id=scan_id)
156            ftemp = open(mktemp(), "w", 0)
157            ftemp.write(scan.nmap_xml_output)
158            ftemp.flush()
159            parser = NmapParser(ftemp.name)
160            parser.parse()
161            json_parser = ScanJsonParser(parser)
162            return HttpResponse("{'result': 'OK', 'output': {'plain': '%s', 'full': %s}}" % \
163                                (parser.get_nmap_output().replace("'", "\\'").\
164                                replace("\r", "").replace("\n", "\\n' + \n'"),
165                                json_parser.parse()), 
166                                "text/plain")
167    else:
168        raise HttpError(400, "Invalid GET request.")
169
170@authenticate(ERROR)
171def save_result(req, scan_id):
172    print req.POST
173    if req.POST:
174        scan = req.session.get("scan_result_" + scan_id, None)
175        parser = NmapParser()
176        fname = mktemp()
177        ftemp = open(fname, "a", 0)
178        ftemp.write(scan)
179        ftemp.close()
180        parser.set_xml_file(fname)
181        parser.parse()
182        parser.scan_name = req.POST['filename']
183        parser.write_xml(open(fname, "w", 0))
184        ftemp = open(fname, "r")
185        scan = ftemp.read()
186        if not scan:
187            raise Http404
188       
189        if req.POST['destination'] == "database":
190            Scans(scan_name=parser.scan_name,
191                    nmap_xml_output=scan,
192                    date=time())
193            return HttpResponse("{'result': 'OK'}", "text/plain")
194        else:
195            response = HttpResponse(scan, "text/xml")
196            response['Content-disposition'] = "attachment; filename=" + quote(req.POST['filename'].replace(" ", "_")) + ".usr"
197            return response
198    else:
199        raise HttpError(400, "Invalid GET request.")
200   
201
202@authenticate(ERROR)
203def get_saved_scans(req):
204    db = UmitDB()
205    data = [{"id": str(s.scans_id), 
206             "name": str(s.scan_name).replace("'", "\\'"),
207             "date": datetime.datetime.fromtimestamp(s.date).strftime("%Y-%m-%d %H:%M:%S")}
208             for s in db.get_scans() if req.POST.get("search", "").lower() in s.scan_name.lower()]
209    return HttpResponse(str(data))
210
211
212@authenticate(ERROR)
213def get_scan(req, scan_id):
214    db = UmitDB()
215    if scan_id not in [str(sid) for sid in db.get_scans_ids()]:
216        raise Http404
217   
218    scan = Scans(scans_id=scan_id)
219    ftemp = open(mktemp(), "w", 0)
220    ftemp.write(scan.nmap_xml_output)
221    ftemp.flush()
222    parser = NmapParser(ftemp.name)
223    parser.parse()
224    return HttpResponse("{'result': 'OK', 'output': '%s', 'xml': '%s'}" % \
225                        (parser.get_nmap_output().replace("'", "\\'").\
226                        replace("\r", "").replace("\n", "\\n' + \n'"),
227                        open(ftemp.name).read().replace('"', "'").\
228                        replace("'", "\\'").\
229                        replace("\n", "\\n' + \n'")), 
230                        "text/plain")
231
232
233@authenticate(ERROR)
234def delete_scan(req, scan_id):
235    db = UmitDB()
236    cursor = db.cursor
237    if int(scan_id) not in db.get_scans_ids():
238        raise Http404
239   
240    try:
241        cursor.execute("DELETE FROM scans WHERE scans_id=%d" % int(scan_id))
242    except Exception, e:
243        return HttpResponse("{'result': 'FAIL', 'error': '%s'}" % str(e))
244   
245    return HttpResponse("{'result': 'OK'}")
Note: See TracBrowser for help on using the browser.