Esempio n. 1
0
    def __init__(self,fichier):
        self.fichier=fichier

        #Variables de verification
        cursor=connection.cursor()
        cursor.execute('SELECT DISTINCT(nom) FROM application ORDER BY nom ASC')
        self.APPLIS=dictfetchall(cursor)

        cursor.execute('SELECT DISTINCT(ip) FROM hotes')
        temp=dictfetchall(cursor)
        self.LISTE_ADRESSES=[]

        for ip in temp:
            self.LISTE_ADRESSES.append(ip['ip'])

        cursor.execute('SELECT DISTINCT(mac) FROM hotes')
        temp=dictfetchall(cursor)
        self.LISTE_MAC=[]
        cursor.close()

        for mac in temp:
            self.LISTE_MAC.append(mac['mac'])

        BASE=settings.BASE_DIR+'/'
        Config = ConfigParser.ConfigParser()
        Config.readfp(codecs.open(BASE+"soc/default.cfg","r","utf-8"))
        self.LOCALISATION=[elem[0] for elem in Config.items('LOCALISATION')]
        self.TYPE_MACHINE=[elem[0] for elem in Config.items('TYPE')]
        self.LISTE_ENV=[elem[0] for elem in Config.items('ENVIRONNEMENT')]

        '''
        self.LISTE_ENV=('recette','pre-production','production')
        self.TYPE_MACHINE=('equipement-reseau','serveur','vm','appliance')
        self.LOCALISATION=('sarcelles','valence')
        '''
        self.dom = parse(fichier)


        #Liste des éléments pouvant être ajoutés en base pour une machine
        self.elements_hote=[{'nom':'ip','controle':self.valideAdresse},
        {'nom':'mac','controle':self.valideMacAdresse},
        {'nom':'hostname','controle':None},
        {'nom':'os','controle':None},
        {'nom':'type_machine','controle':self.valideTypeMachine},
        {'nom':'localisation','controle':self.valideLocalisation},
        {'nom':'environnement','controle':self.valideEnvironnement},
        {'nom':'commentaires','controle':None}]

        self.NB_ELEMENTS=len(self.elements_hote)
        self.tableau_erreurs=[]
Esempio n. 2
0
def initialiserPG(dump_file,host,port,database,login,password):
    '''
    Cette fonction permet d'initialiser une base de donnée POstgreSQL
    à partir d'un fichier de dump
    '''

    conn = psycopg2.connect(host=host,port=port,database='postgres',user=login,password=password)
    conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
    cursor=conn.cursor()

    cursor.execute("SELECT datdba FROM pg_database WHERE datname=%s",[database])
    base=dictfetchall(cursor)

    cursor.execute("SELECT rolcreatedb,oid FROM pg_roles WHERE rolname=%s",[login])    
    user=dictfetchall(cursor)

    #si la base n'existe pas
    #et si l'utilisateur possede le droit de creation de base
    if ((len(base)==0) and (user[0]['rolcreatedb']==True)):
        error=re.search('[;|<>]&"\'',str(database))

        if error!=None:
            raise Exception("Erreur de paramètre")

        cursor.execute('CREATE DATABASE '+str(database))


    cursor.close()

    if len(base)==1:
        conn = psycopg2.connect(host=host,port=port,database=database,user=login,password=password)
        conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
        cursor=conn.cursor()
        cursor.execute("SELECT tablename FROM pg_tables WHERE tableowner=%s AND schemaname='public'",[login])
        liste=dictfetchall(cursor)

        for table in liste:
            cursor.execute("DROP TABLE IF EXISTS "+str(table['tablename'])+" CASCADE")

    
    os.putenv('PGPASSWORD',password)

    #On recupère l'adresse IP si l'utilisateur nous envoie le hostname
    try:
        host=valideIP(host)
    except:
        host=getIP(host)

    subprocess.check_output('psql -h '+desatanize(host)+' -p '+str(port)+' -d '+desatanize(database)+' -U '+desatanize(login)+' < '+dump_file, shell=True)
Esempio n. 3
0
    def getScan(self,id_scan):
        for elem in self.scanListe:
            if int(elem['id'])==int(id_scan):
                return elem['scan']

        cursor=connection.cursor()
        cursor.execute('SELECT id_scans_status FROM scan_manuel_status WHERE id_scan_manuel=%s LIMIT 1',[str(id_scan)])
        temp=dictfetchall(cursor)
        id_scan=temp[0]['id_scans_status']

        for elem in self.scanListe:
            if int(elem['id'])==int(id_scan):
                return elem['scan']

        raise Exception('scan non présent en base')
Esempio n. 4
0
    def getScan(self, id_scan):
        for elem in self.scanListe:
            if int(elem['id']) == int(id_scan):
                return elem['scan']

        cursor = connection.cursor()
        cursor.execute(
            'SELECT id_scans_status FROM scan_manuel_status WHERE id_scan_manuel=%s LIMIT 1',
            [str(id_scan)])
        temp = dictfetchall(cursor)
        id_scan = temp[0]['id_scans_status']

        for elem in self.scanListe:
            if int(elem['id']) == int(id_scan):
                return elem['scan']

        raise Exception('scan non présent en base')
Esempio n. 5
0
def initialiserPG(dump_file, host, port, database, login, password):
    '''
    Cette fonction permet d'initialiser une base de donnée POstgreSQL
    à partir d'un fichier de dump
    '''

    conn = psycopg2.connect(host=host,
                            port=port,
                            database='postgres',
                            user=login,
                            password=password)
    conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
    cursor = conn.cursor()

    cursor.execute("SELECT datdba FROM pg_database WHERE datname=%s",
                   [database])
    base = dictfetchall(cursor)

    cursor.execute("SELECT rolcreatedb,oid FROM pg_roles WHERE rolname=%s",
                   [login])
    user = dictfetchall(cursor)

    #si la base n'existe pas
    #et si l'utilisateur possede le droit de creation de base
    if ((len(base) == 0) and (user[0]['rolcreatedb'] == True)):
        error = re.search('[;|<>]&"\'', str(database))

        if error != None:
            raise Exception("Erreur de paramètre")

        cursor.execute('CREATE DATABASE ' + str(database))

    cursor.close()

    if len(base) == 1:
        conn = psycopg2.connect(host=host,
                                port=port,
                                database=database,
                                user=login,
                                password=password)
        conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
        cursor = conn.cursor()
        cursor.execute(
            "SELECT tablename FROM pg_tables WHERE tableowner=%s AND schemaname='public'",
            [login])
        liste = dictfetchall(cursor)

        for table in liste:
            cursor.execute("DROP TABLE IF EXISTS " + str(table['tablename']) +
                           " CASCADE")

    os.putenv('PGPASSWORD', password)

    #On recupère l'adresse IP si l'utilisateur nous envoie le hostname
    try:
        host = valideIP(host)
    except:
        host = getIP(host)

    subprocess.check_output('psql -h ' + desatanize(host) + ' -p ' +
                            str(port) + ' -d ' + desatanize(database) +
                            ' -U ' + desatanize(login) + ' < ' + dump_file,
                            shell=True)
Esempio n. 6
0
def creerRapportSolutions(listeIP,group_by,titre='rapportSolutions',traduire=False):

    cursor=connection.cursor()

    if group_by=='vuln':
        cursor.execute('''SELECT DISTINCT(id),criticite,nom,solution,description,infos_complementaires,ip_hote FROM vulnerabilitees
            INNER JOIN vuln_hote_service ON vuln_hote_service.id_vuln=vulnerabilitees.id
            WHERE criticite!='Info' AND date_correction is NULL ORDER BY id ASC''')

    else:
        cursor.execute('''SELECT ip_hote,nom,description,solution,infos_complementaires,criticite FROM vuln_hote_service
            INNER JOIN vulnerabilitees ON id_vuln=id WHERE criticite!='Info' AND date_correction is NULL ORDER BY ip_hote ASC''')

    dict_vuln_temp=dictfetchall(cursor)


    dict_vuln=[]
    taille=len(dict_vuln_temp)
    #On selectionne uniquement les adresses demandees
    for i in range(0,taille):
        if (dict_vuln_temp[i]['ip_hote'] in listeIP):
            dict_vuln.append(dict_vuln_temp[i])


    if group_by=='vuln':
        dict_vuln_temp=[]
        taille=len(dict_vuln)
        id_vuln_precedent=-1
        indice=-1

        for i in range(0,taille):
            id_actuel=dict_vuln[i]['id']

            if id_actuel!=id_vuln_precedent:
                id_vuln_precedent=id_actuel
                indice=indice+1
                dict_vuln_temp.append(dict_vuln[i])
                dict_vuln_temp[indice]['ip_hote']=[dict_vuln[i]['ip_hote']]

            else:
                dict_vuln_temp[indice]['ip_hote'].append(dict_vuln[i]['ip_hote'])

        del dict_vuln

        vuln_critical=[]
        vuln_high=[]
        vuln_medium=[]
        vuln_low=[]

        for vuln in dict_vuln_temp:
            crit=vuln['criticite']

            if crit=='Critical':
                vuln_critical.append(vuln)
            elif crit=='High':
                vuln_high.append(vuln)

            elif crit=='Medium':
                vuln_medium.append(vuln)

            else:
                vuln_low.append(vuln)

        dict_vuln=vuln_critical+vuln_high+vuln_medium+vuln_low


        repartition_vuln={'critique':len(vuln_critical),'haute':len(vuln_high),'moyenne':len(vuln_medium),'faible':len(vuln_low)}


    else:
        repartition_vuln={'critique':0,'haute':0,'moyenne':0,'faible':0}


        for vuln in dict_vuln:
            crit=vuln['criticite']

            if crit=='Critical':
                repartition_vuln['critique']+=1
            if crit=='High':
                repartition_vuln['haute']+=1

            if crit=='Medium':
                repartition_vuln['moyenne']+=1

            else:
                repartition_vuln['faible']+=1


    #Mise en forme du titre
    #Rappel: en latex les caractères spéciaux (_,& doivent être échappés), sinon erreur de compilation
    titre=titre.replace('&','\&').replace('_','')


    copyfile(REP_TRAVAIL+'base.tex',REP_TRAVAIL+'temp/'+titre+'.tex')
    pageGarde('Actions correctrices\n"'+titre+'"',AUTEUR,SOCIETE,LOGO,REP_TRAVAIL+'temp/'+titre+'.tex')
    intro(repartition_vuln,listeIP,REP_TRAVAIL+'temp/'+titre+'.tex')
    tableauVulnerabilites(dict_vuln,group_by,REP_TRAVAIL+'temp/'+titre+'.tex')
    tableauSolutions(dict_vuln,group_by,REP_TRAVAIL+'temp/'+titre+'.tex')
    fichierLatex=open(REP_TRAVAIL+'temp/'+titre+'.tex','a')
    fichierLatex.write('''
\\end{document}''')
    fichierLatex.close()


    liste_arguments=[REP_TRAVAIL,titre]

    #Contrôle des arguments
    for arg in liste_arguments:
        desatanize(str(arg))


    titre_latex=titre
    titre_latex=titre_latex.replace(" ","\ ").replace("'","\\'")

    #Necessaire pour la creation des liens dans le sommaire vers les différentes parties
    for i in range(0,3):
        try:
            subprocess.check_output(['pdflatex -no-file-line-error -interaction=nonstopmode --output-directory '+REP_TRAVAIL+'temp/ '+REP_TRAVAIL+'temp/'+titre_latex+'.tex >/dev/null'],shell=True)
            time.sleep(2)
        except Exception as e:
            logger.error("Erreur generation rapport: "+str(e))
            pass


    f = open(REP_TRAVAIL+'temp/'+titre+'.pdf', 'r')
    pdf= f.read()
    f.close()

    subprocess.check_output(['rm '+REP_TRAVAIL+'temp/'+titre.replace(' ','\ ').replace("'","\\'")+'.* >/dev/null'],shell=True)

    return pdf
Esempio n. 7
0
def parserNmapXml(fichierXML,scans_status_id):
    '''
    fonction permet de parser le rapport csv dun scan nmap
    et de l'importer dans une BDD
    La fonction met aussi a jour la table service
    Les anciens services seront toujours present mais avec une date de suppression non NULL  
    '''

    cursor=connection.cursor()
    dom = parse(fichierXML)

    cursor.execute('SELECT date_lancement FROM scans_status WHERE id=%s LIMIT 1',[scans_status_id])
    rep=dictfetchall(cursor)
    date_scan=rep[0]['date_lancement']

    #On recupere dans un premier temps les arguments
    args=dom.getElementsByTagName('nmaprun')[0].getAttribute('args')
    
    #Rappel, le scan nmap est lance a partir d'une fonction
    #On connait donc la forme exact de la commande
    #ex: nmap -A -sS -sU -&#45;privileged -oX exemple.xml
    liste_args=args.split('-&')[0].split('nmap ')[1].split(' ')
    [ liste_args.remove(elem) for elem in liste_args if len(elem)==0]


    #Dans le cas ou on effectue un scan nmap uniquement sur certains ports
    #Ces 2 listes permettront de gérer la suppression des services dans la base
    #ex ne pas supprimer un service en base si on n'a pas scanné le port en question
    table_srv=[]

    for element in dom.getElementsByTagName('scaninfo'):
        dic={"protocole":None,'ports':None}
        dic["protocole"]=element.getAttribute('protocol')
        dic["ports"]=element.getAttribute('services')
        table_srv.append(dic)

    ports_udp_scannes,ports_tcp_scannes=getPlagePorts(table_srv)


    for host in dom.getElementsByTagName('host'):
    
        #On recupere les attributs de l'hôte
        host_dict={}

        for addr in host.getElementsByTagName('address'):
            if addr.getAttribute('addrtype')=='ipv4':
                host_dict['ip']=addr.getAttribute('addr')

            elif addr.getAttribute('addrtype')=='mac':
                host_dict['mac']=addr.getAttribute('addr')

        host_dict['hostname']=None

        for hostname in host.getElementsByTagName('hostnames'):
            for name in hostname.getElementsByTagName('hostname'):
                host_dict['hostname']=str(name.getAttribute('name'))


        host_dict['os']=''
        host_dict['famille_os']=''

        #dans le cas ou l'utilisateur a demandé une detection d'OS (-O)
        #ou une detection de version et d'OS (-A)
        if '-A' in liste_args or '-O' in liste_args:
            try:
                host_dict['os']=host.getElementsByTagName('osmatch')[0].getAttribute('name')
                host_dict['famille_os']=host.getElementsByTagName('osclass')[0].getAttribute('osfamily')

            except:
                pass    
             


            #On s'assure que le nom de l'os ne soit pas trop grand
            #En effet, dans le cas où plusieurs possibilitées existe, nmap les mets les unes a la suite des autres
            #ex: Microsoft Windows 7 SP0 - SP1, Windows Server 2008 SP1, Windows 8, or Windows 8.1 Update 1
            if len(host_dict['os'])>40:
                host_dict['os']=host_dict['os'].split(',')[0]

                if len(host_dict['os'])>40:
                    host_dict['os']=host_dict['os'].split('or')[0]
            
        #On verifie si une entree pour cet hote existe deja dans la base                        
        cursor.execute('SELECT count(ip) from hotes WHERE ip=%s',[host_dict['ip']])
        nb_hotes=dictfetchall(cursor)


        if(int(nb_hotes[0]['count'])>0):
            cursor.execute('SELECT id FROM services WHERE ip_hote=%s AND date_retrait is NULL',[host_dict['ip']])
            id_existant=dictfetchall(cursor)
            id_initiaux=[]

            for id in id_existant:
                id_initiaux.append(id['id'])

            host_dict['nb_services']=0
        
            if '-A' in liste_args or '-O' in liste_args:
                if host_dict['os']!='' and host_dict['famille_os']!='':
                    cursor.execute('UPDATE hotes SET os=%s, famille_os=%s WHERE ip=%s',[host_dict['os'],host_dict['famille_os'],host_dict['ip']])
            

        else:
            continue

            #Possibilité d'ajouter automatiquement le nouvel hôte en base
            #Decommentez pour activer
            """
            id_initiaux=[]
            host_dict['nb_services']=0
                
            cursor.execute('INSERT INTO hotes (ip,mac,hostname,os,famille_os,nb_services) VALUES (%s,%s,%s,%s,%s,%s)',[host_dict['ip'],host_dict['mac'],host_dict['hostname'],host_dict['os'],host_dict['famille_os'],host_dict['nb_services']])
            """
            ####

        del nb_hotes
        #On cherche ensuite les services associes a la machine

        for service in host.getElementsByTagName('port'):
            dic={'etat':None,'nom':None,'type':None,'version':None}
            dic['protocole']=service.getAttribute('protocol')
            dic['port']=service.getAttribute('portid')
    
            for child in service.childNodes:
                if child.nodeName=='state':
                    dic['etat']=child.getAttribute('state')

                elif child.nodeName=='service':
                    dic['nom']=child.getAttribute('product')
                    dic['type']=child.getAttribute('name')
                    dic['version']=child.getAttribute('version')


            if dic['etat']=='closed':
                continue

            host_dict['nb_services']+=1


            #On verifie si le service est deja repertorie
            cursor.execute('SELECT count(id) from services WHERE protocole=%s AND port=%s AND etat=%s AND nom=%s AND type=%s AND version=%s AND ip_hote=%s AND date_retrait is NULL',[dic['protocole'],dic['port'],dic['etat'],dic['nom'],dic['type'],dic['version'],host_dict['ip']])
            nb_services=dictfetchall(cursor)


            if nb_services[0]['count']==0:
                cursor.execute('INSERT INTO services (protocole,port,etat,nom,type,version,ip_hote,date_ajout) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)',[dic['protocole'],dic['port'],dic['etat'],dic['nom'],dic['type'],dic['version'],host_dict['ip'],date_scan])

            else:
                cursor.execute('SELECT id from services WHERE protocole=%s AND port=%s AND etat=%s AND nom=%s AND type=%s AND version=%s AND ip_hote=%s AND date_retrait is NULL LIMIT 1',[dic['protocole'],dic['port'],dic['etat'],dic['nom'],dic['type'],dic['version'],host_dict['ip']])
                id=dictfetchall(cursor)
                id_initiaux.remove(id[0]['id'])


        #On met a jour la table 'services'
        #Si date_retrait est null cela veut dire que
        #le service est tjrs actif
        for srv in id_initiaux:
            cursor.execute("SELECT protocole,port FROM services WHERE id=%s LIMIT 1",[srv])
            rep=dictfetchall(cursor)

            if len(ports_tcp_scannes)!=0 or len(ports_udp_scannes)!=0:
                if int(rep[0]['port'])==0:
                    continue

                #Si le port en question fait parti des ports scannes
                if rep[0]['protocole']=='udp' and int(rep[0]['port']) in ports_udp_scannes:
                    cursor.execute('UPDATE services SET date_retrait=%s WHERE id=%s and ip_hote=%s',[date_scan,srv,host_dict['ip']])

                elif rep[0]['protocole']=='tcp' and int(rep[0]['port']) in ports_tcp_scannes:
                    cursor.execute('UPDATE services SET date_retrait=%s WHERE id=%s and ip_hote=%s',[date_scan,srv,host_dict['ip']])
        
            #Si le scan a été lancé sur tous les ports alors, on peut supprimer tous les ports présents dans la base 
            #qui n'ont pas été détecté lors de ce scan
            else:
                if int(rep[0]['port'])==0:
                    continue
    
                cursor.execute('UPDATE services SET date_retrait=%s WHERE id=%s and ip_hote=%s',[date_scan,srv,host_dict['ip']])


        #On met a jour la table hote
        cursor.execute("SELECT count(id) FROM services WHERE ip_hote=%s AND date_retrait is NULL",[host_dict['ip']])
        nb_services=dictfetchall(cursor)[0]['count']
        cursor.execute('UPDATE hotes SET nb_services=%s WHERE ip=%s',[nb_services,host_dict['ip']])
Esempio n. 8
0
def parserNessusCsv(fichierCSV,scans_status_id,modeStrict=False):
    '''
    Importe le rapport CSV d'un scan Nessus dans une base SQL
    
    Le mode restrictif permet de générer une erreur en cas de decouverte
    d'une vulnerabilite sur un service non présent en base
    '''

    csvfile=open(fichierCSV, 'r')
    spamreader = csv.reader(csvfile, delimiter=',')
    cursor=connection.cursor()

    cursor.execute('SELECT date_lancement FROM scans_status WHERE id=%s LIMIT 1',[scans_status_id])
    rep=dictfetchall(cursor)
    date_scan=rep[0]['date_lancement']

    #Gestion du mode restrict
    dict_raise={'ip':[],'ports_tcp':[],'ports_udp':[]}

    dict_vulns_hote={}
    entete=True

    #liste hotes existant
    cursor.execute('SELECT ip FROM hotes')
    dict_hotes_existant=dictfetchall(cursor)
    tableau_hotes_existant=[]
    dict_dns={}

    for elem in dict_hotes_existant:
        tableau_hotes_existant.append(elem['ip'])

    
    cve_a_interroger=[]
    
    for row in spamreader:
        #Pour ne pas recuperer la ligne dentete
        if entete==True:
            entete=False
            continue

        plugin_id=int(row[0])
        cve=str(row[1])
        cvss=str(row[2])
        criticite=str(row[3])
        protocole=str(row[5])
        port=str(row[6])
        nom=str(row[7])
        synopsis=str(row[8])
        description=str(row[9])
        solution=str(row[10])        
        a_lire=str(row[11])
        retour_plugin=str(row[12])

        if criticite =='None':
            criticite='Info'
        

        cursor.execute('SELECT id FROM vulnerabilitees WHERE plugin_id=%s AND criticite=%s AND nom=%s AND description=%s AND synopsis=%s LIMIT 1',[plugin_id,criticite,nom,description,synopsis])
        nb=dictfetchall(cursor)

        if len(nb)==0:
            #on ajoute la vulnerabilites a la base de donnee
            cursor.execute('INSERT INTO vulnerabilitees (plugin_id,nom,description,synopsis,solution,infos_complementaires,criticite) VALUES (%s,%s,%s,%s,%s,%s,%s)',[plugin_id,nom,description,synopsis,solution,a_lire,criticite])


        
        #On verifie s'il y a eu une MAJ au niveau de la solution ou des liens
        else:    

            cursor.execute('SELECT solution,infos_complementaires FROM vulnerabilitees WHERE id=%s LIMIT 1',[nb[0]['id']])
            info_scan=dictfetchall(cursor)

            if info_scan[0]['solution']!=solution:
                cursor.execute('UPDATE vulnerabilitees SET solution=%s WHERE id=%s',[solution,nb[0]['id']])

            if info_scan[0]['infos_complementaires']!=a_lire:
                cursor.execute('UPDATE vulnerabilitees SET infos_complementaires=%s WHERE id=%s',[a_lire,nb[0]['id']])



        #On recupere l'id de la vulnerabilite recemment ajoute ou correspondant
        cursor.execute('SELECT id FROM vulnerabilitees WHERE plugin_id=%s AND criticite=%s AND nom=%s AND description=%s AND synopsis=%s AND solution=%s AND infos_complementaires=%s',[plugin_id,criticite,nom,description,synopsis,solution,a_lire])
        temp=dictfetchall(cursor)
        id_vuln=temp[0]['id']


        #Gestion des références associées à la vulnérabilitée rencontrée (CVE)        
        for reference in cve.split(','):
            if reference !='':
                cursor.execute('SELECT id FROM refs WHERE nom=%s',[reference])
                temp=dictfetchall(cursor)

                #On ajoute la reference à un tableau si elle n'y est pas présente
                #A la fin de l'importation, chaque reference sera interrogé sur le site (cvedetails)
                # afin de récupérer diverse informations (facilité, impact sur la dispo,confidentialité,...)
                if reference not in cve_a_interroger:
                    cve_a_interroger.append(reference)

                #Si la reference n'existe pas on la cree
                if len(temp)==0:
                    cursor.execute('INSERT INTO refs (nom) VALUES(%s)',[reference])
                    cursor.execute('SELECT id FROM refs WHERE nom=%s',[reference])
                    temp=dictfetchall(cursor)
 
                id_ref=temp[0]['id']
    
                #On verifie si la vulnerabilite possede déjà une association avec la référence
                cursor.execute('SELECT vuln_id,ref_id FROM vulns_refs WHERE vuln_id=%s AND ref_id=%s',[str(id_vuln),str(id_ref)])
                nb=dictfetchall(cursor)
                
                if len(nb)==0:
                    cursor.execute('INSERT INTO vulns_refs (vuln_id,ref_id) VALUES (%s,%s)',[id_vuln,id_ref])
                
        
        #On parcourt l'ensemble des hotes affectes par la vulnerabilite
        #afin d'ajouter, si besoin, une correspondance dans la table vuln_hote_service
        
        for hote in str(row[4]).split(','):
            #Il arrive que Nessus mette le nom de la machine au lieu de son ip
            #Dans ce cas, on réalise une résolution DNS 
            #Le dictionnaire permet d'économiser le nombre de requêtes effectuées
            if re.search('([0-9]{1,3}\.){3}([0-9]{1,3})',str(hote))==None:
                if dict_dns.has_key(str(hote)):
                    hote=dict_dns[str(hote)]
                else:
                    try:
                        hostname=str(hote)
                        hote=getIP(hostname)
                        dict_dns[hostname]=hote
                    except:
                        continue
                             

            #On verifie que notre dictionnaire de travail contient une entree pour l'hote scanner
            #si ce n'est pas le cas on la cree avec comme valeur de cle la liste des vuln_id qu'il possede
            if dict_vulns_hote.has_key(hote)==False:
                cursor.execute('SELECT id_vuln,id_service FROM vuln_hote_service WHERE ip_hote=%s AND date_correction is NULL', [hote])
                rep=dictfetchall(cursor)
                tableau_vuln_service=[]

                for i in range(len(rep)):
                         tableau_vuln_service.append(rep[i])


                dict_vulns_hote[hote]=tableau_vuln_service


            #On selectionne l'id du service correpondant 
            cursor.execute('SELECT id FROM services WHERE ip_hote=%s AND protocole=%s AND port=%s AND date_retrait is NULL', [hote,protocole,port])
            rep=dictfetchall(cursor)


            #Dans le cas où le service n'est pas présent en base, on indique dans un dictionnaire le port correspondant
            #Une fois le CSV parcouru, on lévera une alerte indiquant les ports à scanner avec Nmap
            #Rappel: le modeStrict sur "OFF" permet de ne pas lever d'erreur en n'important pas la vulnérabilitée (mode dégradé)
            if len(rep)==0:
                #Cas d'une vulnerabilite systeme:
                if port=='0' and criticite!='Info':
                    cursor.execute("SELECT id  FROM services WHERE ip_hote=%s AND port=0 AND nom='OS' AND type='OS'",[hote])
                    rep=dictfetchall(cursor)

                    if len(rep)==0:
                        cursor.execute("INSERT INTO services (protocole,port,etat,nom,type,ip_hote,date_ajout) VALUES ('tcp',0,'open','OS','OS',%s,%s)",[hote,date_scan])

                        cursor.execute("SELECT id FROM services WHERE ip_hote=%s AND port=0 AND nom='OS' AND type='OS'", [hote])
                        rep=dictfetchall(cursor)


                elif modeStrict==True and str(port)!='0':
                    if (str(hote) not in dict_raise['ip']):
                        dict_raise['ip'].append(str(hote))

                    if (protocole=='udp' and (port not in dict_raise['ports_udp'])):
                        dict_raise['ports_udp'].append(str(port))

                    if (protocole=='tcp' and (port not in dict_raise['ports_tcp'])):
                        dict_raise['ports_tcp'].append(str(port))
                    continue
                else:
                    continue

            if port=="0":
                id_service=rep[0]['id']
                cursor.execute('SELECT id_vuln FROM vuln_hote_service WHERE ip_hote=%s AND id_service=%s AND id_vuln=%s AND date_correction is NULL',[hote,id_service,id_vuln])
                temp=dictfetchall(cursor)

            else:
                id_service=rep[0]['id']

                #On verifie si la table vuln_hote_service contient une entree pour le trio (service,ip,vuln)
                cursor.execute('SELECT id_vuln FROM vuln_hote_service WHERE ip_hote=%s AND id_service=%s AND id_vuln=%s AND date_correction is NULL',[hote,id_service,id_vuln])
                temp=dictfetchall(cursor)

            # 1)Il s'agit alors d'une nouvelle vulnérabilitée 
            if len(temp)==0:
                cursor.execute('INSERT INTO vuln_hote_service (ip_hote,id_service,id_vuln,date_detection,retour_vuln) VALUES (%s,%s,%s,%s,%s)',[hote,id_service,id_vuln,date_scan,retour_plugin])


            # 2) la vulnérabilitée était déjà présente en base (rien de nouveau donc)
            #on supprime donc l'entrée de notre dictionnaire de travail
            #Rappel dict_vulns_hote={'host1':[liste_vulnerabilitees]}
            else: 
                dict_a_supprimer={}
                dict_a_supprimer['id_vuln']=id_vuln
                dict_a_supprimer['id_service']=id_service
                try:
                    dict_vulns_hote[hote].remove(dict_a_supprimer)
                except ValueError:
                    #Il arrive que Nessus remonte la meme vulnerabilite pour un meme service mais avec 
                    #une syntaxe de sortie de plugin légérement différente (mais avec une information identique)
                    #dans ce cas note tableau_vuln initial ne contiendra qu'une iteration du couple service/vuln
                    #alors que le rapport en contient plusieurs, d'où l'erreur
                    pass


    for reference in cve_a_interroger:
        param=get_CVE_details(str(reference))
        cursor.execute("SELECT * FROM refs WHERE nom=%s",[str(reference)])
        temp=dictfetchall(cursor)

        if len(temp)==0:
            cursor.execute('''INSERT INTO refs (nom,cvss_score,confidentialite,integrite,disponibilite,complexite,authentification,type,acces_obtention) 
                            VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)''',
                            [reference,param['cvss_score'],param['confidentialite'],param['integrite'],param['disponibilite'],
                            param['complexite'],param['authentification'],param['type'],param['acces_obtention']])

        else:
            cursor.execute('''UPDATE refs
                            SET cvss_score=%s,
                            confidentialite=%s,
                            integrite=%s,
                            disponibilite=%s,
                            complexite=%s,
                            authentification=%s,
                            type=%s,
                            acces_obtention=%s WHERE nom=%s''',[param['cvss_score'],param['confidentialite'],param['integrite'],param['disponibilite'],
                                                      param['complexite'],param['authentification'],param['type'],param['acces_obtention'],reference])


    if modeStrict==True:
        if len(dict_raise['ip'])>0:
            raise ErreurScanNessus('Service(s) introuvable(s)',dict_raise)


    #Pour finir, on parcourt le dictionnaire de travail
    #Les vuln_id restantes correspondent à des vulnerabilitées qui ont été corrigées
    # On met donc a jour la table vuln_hote_service en fonction
    for hote in dict_vulns_hote.keys():
        for dic in dict_vulns_hote[hote]:
            cursor.execute('UPDATE vuln_hote_service SET date_correction=%s WHERE ip_hote=%s AND id_vuln=%s AND id_service=%s',[date_scan,hote,dic['id_vuln'],dic['id_service']])



        cursor.execute('SELECT count(id_vuln) FROM vuln_hote_service WHERE ip_hote=%s AND date_correction IS NULL',[hote])
        nb=dictfetchall(cursor)
        nb_vuln=nb[0]['count']

        cursor.execute('UPDATE hotes SET nb_vulnerabilites=%s WHERE ip=%s',[nb_vuln,hote])

    csvfile.close()
Esempio n. 9
0
    def addScan(self, tableau_ip, id_scan, type_scan):
        cursor = connection.cursor()

        if type_scan == 'manuel':
            cursor.execute('SELECT * FROM scans_manuels WHERE id=%s LIMIT 1',
                           [id_scan])
            dictScan = dictfetchall(cursor)

        else:
            cursor.execute(
                'SELECT * FROM scans_plannifies WHERE id=%s LIMIT 1',
                [id_scan])
            dictScan = dictfetchall(cursor)

        nmap = dictScan[0]['nmap']
        nessus = dictScan[0]['nessus']

        nmapOptions = dictScan[0]['nmap_options'] if nmap == True else None
        policy_id = dictScan[0]['nessus_policy_id'] if nessus == True else None

        tz = pytz.timezone('Europe/Paris')
        date_lancement = datetime.datetime.now()
        date_postgresql = tz.localize(date_lancement)
        date_lancement = datetime.datetime.now()

        cursor.execute(
            'INSERT INTO scans_status (date_lancement,etat,type) VALUES (%s,\'ready\',%s)',
            [date_postgresql, str(type_scan)])
        cursor.execute(
            'SELECT id FROM scans_status WHERE date_lancement=%s AND etat=%s AND type=%s LIMIT 1',
            [date_postgresql, 'ready',
             str(type_scan)])
        temp = dictfetchall(cursor)
        id_scan_status = temp[0]['id']

        #Le nom unique sera utilisé pour:
        #    - le nom du rapport PDF
        #    - l'instance de log
        nom_unique = str(id_scan_status) + '__' + str(date_lancement).replace(
            ' ', '_').split('.')[0]

        if type_scan == 'manuel':
            cursor.execute(
                'INSERT INTO scan_manuel_status (id_scans_status,id_scan_manuel) VALUES(%s,%s)',
                [str(id_scan_status), str(id_scan)])
            chemin_rapport = CHEMIN_RAPPORT + 'ScansManuels/' + str(
                id_scan_status) + '/'
            os.makedirs(chemin_rapport)

        else:
            for ip in tableau_ip:
                cursor.execute(
                    'INSERT INTO scan_hote (id_scan,ip) VALUES(%s,%s)',
                    [str(id_scan_status), ip])

            cursor.execute(
                'INSERT INTO scan_plannifie_status (id_scan_plannifie,id_scans_status) VALUES(%s,%s)',
                [id_scan, str(id_scan_status)])
            chemin_rapport = CHEMIN_RAPPORT + 'ScansPlannifies/' + str(
                id_scan) + '/' + str(id_scan_status) + '/'
            os.makedirs(chemin_rapport)

        cursor.close()

        #On instancie notre scan et on le place dans la liste
        scan = Scan(id_scan_status, nom_unique, type_scan, chemin_rapport,
                    tableau_ip, nmapOptions, policy_id)
        self.scanListe.append({'id': id_scan_status, 'scan': scan})

        #On ajoute reciproquement en observateur le scan et le serveur de tâche
        #Dans le premier cas pour pouvoir logger l'avancement du scan dans un fichier de log
        #   et lancer des commande Nessus (une seule instance Nessus pour n Scan)
        #Dans le second pour avertir le scan lorsque le scan Nessus est fini
        scan.add_observer(self, 'dispatcher')
        self.add_observer(scan, str(id_scan_status))

        if nessus == True:
            try:
                nessus_id = self.ScannerNessus.nouveauScan(
                    policy_id, tableau_ip, nom_unique, 'Scan DJANGO')
                scan.nessusSetID(int(nessus_id))
                self.ScannerNessus.lancerScan(int(nessus_id))
                self.log.ecrire(
                    '[' + str(id_scan_status) + ']= Demmarage du scan nessus',
                    'info')
            except Exception as e:
                self.attenteNessus.append({
                    'action': 'ajout_scan',
                    'id_scan_status': id_scan_status,
                    'scan': scan,
                    'policy_id': policy_id,
                    'tableau_ip': tableau_ip,
                    'nom_unique': nom_unique,
                    'info': 'Scan DJANGO'
                })
                self.log.ecrire(
                    "[" + str(id_scan_status) +
                    "]= Echec de l'ajout du scan Nessus, " + str(e), "error")
        if nmap == True:
            scan.demarrerScanNmap()
Esempio n. 10
0
    def addScan(self,tableau_ip,id_scan,type_scan):
        cursor=connection.cursor()

        if type_scan=='manuel':
            cursor.execute('SELECT * FROM scans_manuels WHERE id=%s LIMIT 1',[id_scan])
            dictScan=dictfetchall(cursor)

        else:
            cursor.execute('SELECT * FROM scans_plannifies WHERE id=%s LIMIT 1',[id_scan])
            dictScan=dictfetchall(cursor)


        nmap=dictScan[0]['nmap']
        nessus=dictScan[0]['nessus']

        nmapOptions=dictScan[0]['nmap_options'] if nmap==True else None
        policy_id=dictScan[0]['nessus_policy_id'] if nessus==True else None

        tz = pytz.timezone('Europe/Paris')
        date_lancement=datetime.datetime.now()
        date_postgresql=tz.localize(date_lancement)
        date_lancement=datetime.datetime.now()


        cursor.execute('INSERT INTO scans_status (date_lancement,etat,type) VALUES (%s,\'ready\',%s)',[date_postgresql,str(type_scan)])
        cursor.execute('SELECT id FROM scans_status WHERE date_lancement=%s AND etat=%s AND type=%s LIMIT 1',[date_postgresql,'ready',str(type_scan)])
        temp=dictfetchall(cursor)
        id_scan_status=temp[0]['id']

        #Le nom unique sera utilisé pour:
        #    - le nom du rapport PDF
        #    - l'instance de log 
        nom_unique=str(id_scan_status)+'__'+str(date_lancement).replace(' ','_').split('.')[0]


        if type_scan=='manuel':
            cursor.execute('INSERT INTO scan_manuel_status (id_scans_status,id_scan_manuel) VALUES(%s,%s)',[str(id_scan_status),str(id_scan)])
            chemin_rapport=CHEMIN_RAPPORT+'ScansManuels/'+str(id_scan_status)+'/'
            os.makedirs(chemin_rapport)


        else:
            for ip in tableau_ip:
                cursor.execute('INSERT INTO scan_hote (id_scan,ip) VALUES(%s,%s)',[str(id_scan_status),ip])

            cursor.execute('INSERT INTO scan_plannifie_status (id_scan_plannifie,id_scans_status) VALUES(%s,%s)',[id_scan,str(id_scan_status)])
            chemin_rapport=CHEMIN_RAPPORT+'ScansPlannifies/'+str(id_scan)+'/'+str(id_scan_status)+'/'
            os.makedirs(chemin_rapport)

        cursor.close()



        #On instancie notre scan et on le place dans la liste
        scan=Scan(id_scan_status,nom_unique,type_scan,chemin_rapport,tableau_ip,nmapOptions,policy_id)
        self.scanListe.append({'id':id_scan_status,'scan':scan})


        #On ajoute reciproquement en observateur le scan et le serveur de tâche
        #Dans le premier cas pour pouvoir logger l'avancement du scan dans un fichier de log
        #   et lancer des commande Nessus (une seule instance Nessus pour n Scan)
        #Dans le second pour avertir le scan lorsque le scan Nessus est fini
        scan.add_observer(self,'dispatcher')
        self.add_observer(scan,str(id_scan_status))

        if nessus==True:
            try:
                nessus_id=self.ScannerNessus.nouveauScan(policy_id,tableau_ip,nom_unique,'Scan DJANGO')
                scan.nessusSetID(int(nessus_id))
                self.ScannerNessus.lancerScan(int(nessus_id))
                self.log.ecrire('['+str(id_scan_status)+']= Demmarage du scan nessus','info')
            except Exception as e:
                self.attenteNessus.append({'action':'ajout_scan','id_scan_status':id_scan_status,'scan':scan,'policy_id':policy_id,'tableau_ip':tableau_ip,'nom_unique':nom_unique,'info':'Scan DJANGO'})
                self.log.ecrire("["+str(id_scan_status)+"]= Echec de l'ajout du scan Nessus, "+str(e),"error")
        if nmap==True:
            scan.demarrerScanNmap()
Esempio n. 11
0
def envoieMail(scan):
    '''
    Cette fonction permet d'envoyer un mail suite à la fin d'un scan
    '''

    #Entete
    fromaddr = ADRESSE_ENVOIE
    msg = MIMEMultipart()
    msg['From'] = fromaddr
    msg['Subject'] = "Rapport du scan N°"+str(scan['id'])
    msg['Charset'] = 'utf-8'

    cursor=connection.cursor()
    cursor.execute('SELECT type FROM scans_status WHERE id=%s LIMIT 1',[scan['id']])
    type_scan=dictfetchall(cursor)


    #Corps du texte
    body="""Bonjour,\n
    Le scan N°"""+str(scan['id'])+" s'est terminé avec l'état \""+str(scan['status'])+"\"."

    if scan['status']!="completed":
        body+="Les erreurs suivantes ont été rencontrés lors du scan:\n"

    for erreur in scan['erreurs']:
        body+="- "+str(erreur)+"\n"


    body+="\n\n Cordialement"
    msg.attach(MIMEText(body, 'plain', _charset='utf-8'))


    #Gestion des PJ
    CHEMIN_RAPPORT=BASE+'rapports/rapports/'

    if type_scan[0]['type']=="manuel":
        chemin=CHEMIN_RAPPORT+'ScansManuels/'+str(scan['id'])+'/'

    else:
        cursor.execute("SELECT id_scan_plannifie FROM scan_plannifie_status WHERE id_scans_status=%s LIMIT 1",[scan['id']])
        res=dictfetchall(cursor)
        chemin=CHEMIN_RAPPORT+'ScansPlannifies/'+str(res[0]['id_scan_plannifie'])+'/'+str(scan['id'])+'/'


    if scan['nessus']==True:
        liste_fichier=glob.glob(chemin+str(scan['id'])+"__*_nessus.pdf")

        if len(liste_fichier)!=0:
            nom_fichier=liste_fichier[0].split('/')[-1]
    	    attachment = open(str(chemin+nom_fichier), "rb")

    	    part = MIMEBase('application', 'octet-stream')
    	    part.set_payload((attachment).read())
    	    encoders.encode_base64(part)
    	    part.add_header('Content-Disposition', "attachment; filename= %s" % nom_fichier)
    	    msg.attach(part)


    liste_fichier=glob.glob(chemin+str(scan['id'])+"__*_evolution.pdf")

    if len(liste_fichier)!=0:
        nom_fichier=liste_fichier[0].split('/')[-1]
    	attachment = open(str(chemin+nom_fichier), "rb")

    	part = MIMEBase('application', 'octet-stream')
    	part.set_payload((attachment).read())
    	encoders.encode_base64(part)
    	part.add_header('Content-Disposition', "attachment; filename= %s" % nom_fichier)
    	msg.attach(part)


    #Connexion
    if SSL:
        server = smtplib.SMTP_SSL(SMTP,int(PORT),timeout=10)
    else:
        server = smtplib.SMTP(SMTP, int(PORT), timeout=10)

    server.login(fromaddr,PASSWORD)

    #Selection des adresses à contacter
    cursor.execute('SELECT email FROM auth_user')
    res=dictfetchall(cursor)

    for element in res:
        toaddr= element['email']
        msg['To']= toaddr
        text = msg.as_string().encode('utf-8')

        server.sendmail(fromaddr, toaddr, text)

    server.quit()
Esempio n. 12
0
def creerRapportSolutions(listeIP,
                          group_by,
                          titre='rapportSolutions',
                          traduire=False):

    cursor = connection.cursor()

    if group_by == 'vuln':
        cursor.execute(
            '''SELECT DISTINCT(id),criticite,nom,solution,description,infos_complementaires,ip_hote FROM vulnerabilitees
            INNER JOIN vuln_hote_service ON vuln_hote_service.id_vuln=vulnerabilitees.id
            WHERE criticite!='Info' AND date_correction is NULL ORDER BY id ASC'''
        )

    else:
        cursor.execute(
            '''SELECT ip_hote,nom,description,solution,infos_complementaires,criticite FROM vuln_hote_service
            INNER JOIN vulnerabilitees ON id_vuln=id WHERE criticite!='Info' AND date_correction is NULL ORDER BY ip_hote ASC'''
        )

    dict_vuln_temp = dictfetchall(cursor)

    dict_vuln = []
    taille = len(dict_vuln_temp)
    #On selectionne uniquement les adresses demandees
    for i in range(0, taille):
        if (dict_vuln_temp[i]['ip_hote'] in listeIP):
            dict_vuln.append(dict_vuln_temp[i])

    if group_by == 'vuln':
        dict_vuln_temp = []
        taille = len(dict_vuln)
        id_vuln_precedent = -1
        indice = -1

        for i in range(0, taille):
            id_actuel = dict_vuln[i]['id']

            if id_actuel != id_vuln_precedent:
                id_vuln_precedent = id_actuel
                indice = indice + 1
                dict_vuln_temp.append(dict_vuln[i])
                dict_vuln_temp[indice]['ip_hote'] = [dict_vuln[i]['ip_hote']]

            else:
                dict_vuln_temp[indice]['ip_hote'].append(
                    dict_vuln[i]['ip_hote'])

        del dict_vuln

        vuln_critical = []
        vuln_high = []
        vuln_medium = []
        vuln_low = []

        for vuln in dict_vuln_temp:
            crit = vuln['criticite']

            if crit == 'Critical':
                vuln_critical.append(vuln)
            elif crit == 'High':
                vuln_high.append(vuln)

            elif crit == 'Medium':
                vuln_medium.append(vuln)

            else:
                vuln_low.append(vuln)

        dict_vuln = vuln_critical + vuln_high + vuln_medium + vuln_low

        repartition_vuln = {
            'critique': len(vuln_critical),
            'haute': len(vuln_high),
            'moyenne': len(vuln_medium),
            'faible': len(vuln_low)
        }

    else:
        repartition_vuln = {
            'critique': 0,
            'haute': 0,
            'moyenne': 0,
            'faible': 0
        }

        for vuln in dict_vuln:
            crit = vuln['criticite']

            if crit == 'Critical':
                repartition_vuln['critique'] += 1
            if crit == 'High':
                repartition_vuln['haute'] += 1

            if crit == 'Medium':
                repartition_vuln['moyenne'] += 1

            else:
                repartition_vuln['faible'] += 1

    #Mise en forme du titre
    #Rappel: en latex les caractères spéciaux (_,& doivent être échappés), sinon erreur de compilation
    titre = titre.replace('&', '\&').replace('_', '')

    copyfile(REP_TRAVAIL + 'base.tex', REP_TRAVAIL + 'temp/' + titre + '.tex')
    pageGarde('Actions correctrices\n"' + titre + '"', AUTEUR, SOCIETE, LOGO,
              REP_TRAVAIL + 'temp/' + titre + '.tex')
    intro(repartition_vuln, listeIP, REP_TRAVAIL + 'temp/' + titre + '.tex')
    tableauVulnerabilites(dict_vuln, group_by,
                          REP_TRAVAIL + 'temp/' + titre + '.tex')
    tableauSolutions(dict_vuln, group_by,
                     REP_TRAVAIL + 'temp/' + titre + '.tex')
    fichierLatex = open(REP_TRAVAIL + 'temp/' + titre + '.tex', 'a')
    fichierLatex.write('''
\\end{document}''')
    fichierLatex.close()

    liste_arguments = [REP_TRAVAIL, titre]

    #Contrôle des arguments
    for arg in liste_arguments:
        desatanize(str(arg))

    titre_latex = titre
    titre_latex = titre_latex.replace(" ", "\ ").replace("'", "\\'")

    #Necessaire pour la creation des liens dans le sommaire vers les différentes parties
    for i in range(0, 3):
        try:
            subprocess.check_output([
                'pdflatex -no-file-line-error -interaction=nonstopmode --output-directory '
                + REP_TRAVAIL + 'temp/ ' + REP_TRAVAIL + 'temp/' +
                titre_latex + '.tex >/dev/null'
            ],
                                    shell=True)
            time.sleep(2)
        except Exception as e:
            logger.error("Erreur generation rapport: " + str(e))
            pass

    f = open(REP_TRAVAIL + 'temp/' + titre + '.pdf', 'r')
    pdf = f.read()
    f.close()

    subprocess.check_output([
        'rm ' + REP_TRAVAIL + 'temp/' +
        titre.replace(' ', '\ ').replace("'", "\\'") + '.* >/dev/null'
    ],
                            shell=True)

    return pdf
Esempio n. 13
0
def creerRapportEvolution(nomUnique,id_scan,type_scan):
    cursor=connection.cursor()
    cursor.execute('SELECT date_lancement FROM scans_status WHERE id=%s LIMIT 1',[id_scan])
    date=dictfetchall(cursor)
    date_scan=date[0]['date_lancement']

    cursor.execute('''SELECT ip_hote,nom,description,criticite,date_correction,date_detection FROM vuln_hote_service
        INNER JOIN vulnerabilitees ON vuln_hote_service.id_vuln=vulnerabilitees.id
        WHERE (date_detection=%s or date_correction=%s) AND criticite!='Info' ORDER BY ip_hote ASC''',[date_scan,date_scan])
    retourScan=dictfetchall(cursor)

    cursor.execute('''SELECT ip_hote,nom,protocole,port,version,date_ajout,date_retrait FROM services
        WHERE date_ajout=%s or date_retrait=%s ORDER BY ip_hote ASC''',[date_scan,date_scan])
    retourServices=dictfetchall(cursor)


    if type_scan=='plannifie':
        cursor.execute('''SELECT id_scan_plannifie FROM scans_status
            INNER JOIN scan_plannifie_status ON scans_status.id=scan_plannifie_status.id_scans_status
            WHERE scans_status.id=%s LIMIT 1''',[id_scan])
        dict_id_scan=dictfetchall(cursor)
        id_scan_plannifie=dict_id_scan[0]['id_scan_plannifie']

        cursor.execute('SELECT DISTINCT(ip) FROM scan_hote WHERE id_scan=%s',[id_scan])
        dictIP=dictfetchall(cursor)

        cursor.execute('SELECT * FROM scans_plannifies WHERE id=%s LIMIT 1',[id_scan_plannifie])
        dictScan=dictfetchall(cursor)
        titre='Rapport du scan plannifie\n"'+str(dictScan[0]['nom'])+'"\ndu '+str(date_scan).split(' ')[0]

        chemin_rapport=REP_RAPPORT+'ScansPlannifies/'+str(int(id_scan_plannifie))+'/'+str(int(id_scan))+'/'

    else:
        cursor.execute('''SELECT id_scan_manuel FROM scans_status
            INNER JOIN scan_manuel_status ON scans_status.id=scan_manuel_status.id_scans_status
            WHERE scans_status.id=%s LIMIT 1''',[id_scan])
        dict_id_scan=dictfetchall(cursor)
        id_scan_manuel=dict_id_scan[0]['id_scan_manuel']


        cursor.execute('SELECT DISTINCT(ip_hote) FROM scan_manuel_hote WHERE id_scan_manuel=%s',[id_scan_manuel])
        dictIP=dictfetchall(cursor)

        cursor.execute('SELECT * FROM scans_manuels WHERE id=%s LIMIT 1',[id_scan_manuel])
        dictScan=dictfetchall(cursor)

        if len(dictIP)==1:
            try:
                name, alias, addresslist = socket.gethostbyaddr(dictIP[0]['ip_hote'])
            except:
                name=dictIP[0]['ip_hote']

            titre='Rapport du scan Manuel sur \n"'+str(name)+'"\ndu '+str(date_scan).split(' ')[0]

        else:
            titre='Rapport du scan Manuel \n démarré le '+str(date_scan).split(' ')[0]+'\n à '+str(date_scan).split(' ')[1].split('.')[0]



        chemin_rapport=REP_RAPPORT+'ScansManuels/'+str(int(id_scan))+'/'


    copyfile(REP_TRAVAIL+'base.tex',REP_TRAVAIL+'/temp/'+nomUnique+'.tex')


    pageGarde(titre,AUTEUR,SOCIETE,LOGO,REP_TRAVAIL+'/temp/'+nomUnique+'.tex')

    if type_scan=='plannifie':
        intro(dictScan[0],dictIP,REP_TRAVAIL+'/temp/'+nomUnique+'.tex','plannifie')

    else:
        intro(dictScan[0],dictIP,REP_TRAVAIL+'/temp/'+nomUnique+'.tex','manuel')


    fichierLatex=open(REP_TRAVAIL+'/temp/'+nomUnique+'.tex','a')
    fichierLatex.write('''\\newpage
\\section{Scans}''')
    fichierLatex.close()


    if dictScan[0]['nessus']==True:
        tableauVuln(retourScan,REP_TRAVAIL+'/temp/'+nomUnique+'.tex')

    if dictScan[0]['nmap']==True:
        tableauServices(retourServices,REP_TRAVAIL+'/temp/'+nomUnique+'.tex')


    fichierLatex=open(REP_TRAVAIL+'/temp/'+nomUnique+'.tex','a')
    fichierLatex.write('''
\\end{document}''')
    fichierLatex.close()


    liste_arguments=[REP_TRAVAIL,nomUnique,chemin_rapport]

    #Contrôle des arguments
    #On s'assure qu'il n'y ait pas d'injection de codes tiers
    for arg in liste_arguments:
        tmp=desatanize(str(arg))


    #Necessaire pour la creation des liens dans le sommaire vers les différentes parties
    for i in range(0,5):
        try:
            subprocess.check_output(['pdflatex -no-file-line-error -interaction=nonstopmode --output-directory '+REP_TRAVAIL+'temp/ '+REP_TRAVAIL+'temp/'+nomUnique+'.tex >/dev/null &>/dev/null'],shell=True)
            time.sleep(3)
        except Exception as e:
            logger.error("Erreur generation rapport ["+str(id_scan)+"] : "+str(e))
            pass

    time.sleep(10)
    copyfile(REP_TRAVAIL+'temp/'+nomUnique+'.pdf',chemin_rapport+nomUnique+'_evolution.pdf')
    subprocess.check_output(['rm '+REP_TRAVAIL+'temp/'+nomUnique+'* >/dev/null'],shell=True)
Esempio n. 14
0
def creerRapportEvolution(nomUnique, id_scan, type_scan):
    cursor = connection.cursor()
    cursor.execute(
        'SELECT date_lancement FROM scans_status WHERE id=%s LIMIT 1',
        [id_scan])
    date = dictfetchall(cursor)
    date_scan = date[0]['date_lancement']

    cursor.execute(
        '''SELECT ip_hote,nom,description,criticite,date_correction,date_detection FROM vuln_hote_service
        INNER JOIN vulnerabilitees ON vuln_hote_service.id_vuln=vulnerabilitees.id
        WHERE (date_detection=%s or date_correction=%s) AND criticite!='Info' ORDER BY ip_hote ASC''',
        [date_scan, date_scan])
    retourScan = dictfetchall(cursor)

    cursor.execute(
        '''SELECT ip_hote,nom,protocole,port,version,date_ajout,date_retrait FROM services
        WHERE date_ajout=%s or date_retrait=%s ORDER BY ip_hote ASC''',
        [date_scan, date_scan])
    retourServices = dictfetchall(cursor)

    if type_scan == 'plannifie':
        cursor.execute(
            '''SELECT id_scan_plannifie FROM scans_status
            INNER JOIN scan_plannifie_status ON scans_status.id=scan_plannifie_status.id_scans_status
            WHERE scans_status.id=%s LIMIT 1''', [id_scan])
        dict_id_scan = dictfetchall(cursor)
        id_scan_plannifie = dict_id_scan[0]['id_scan_plannifie']

        cursor.execute('SELECT DISTINCT(ip) FROM scan_hote WHERE id_scan=%s',
                       [id_scan])
        dictIP = dictfetchall(cursor)

        cursor.execute('SELECT * FROM scans_plannifies WHERE id=%s LIMIT 1',
                       [id_scan_plannifie])
        dictScan = dictfetchall(cursor)
        titre = 'Rapport du scan plannifie\n"' + str(
            dictScan[0]['nom']) + '"\ndu ' + str(date_scan).split(' ')[0]

        chemin_rapport = REP_RAPPORT + 'ScansPlannifies/' + str(
            int(id_scan_plannifie)) + '/' + str(int(id_scan)) + '/'

    else:
        cursor.execute(
            '''SELECT id_scan_manuel FROM scans_status
            INNER JOIN scan_manuel_status ON scans_status.id=scan_manuel_status.id_scans_status
            WHERE scans_status.id=%s LIMIT 1''', [id_scan])
        dict_id_scan = dictfetchall(cursor)
        id_scan_manuel = dict_id_scan[0]['id_scan_manuel']

        cursor.execute(
            'SELECT DISTINCT(ip_hote) FROM scan_manuel_hote WHERE id_scan_manuel=%s',
            [id_scan_manuel])
        dictIP = dictfetchall(cursor)

        cursor.execute('SELECT * FROM scans_manuels WHERE id=%s LIMIT 1',
                       [id_scan_manuel])
        dictScan = dictfetchall(cursor)

        if len(dictIP) == 1:
            try:
                name, alias, addresslist = socket.gethostbyaddr(
                    dictIP[0]['ip_hote'])
            except:
                name = dictIP[0]['ip_hote']

            titre = 'Rapport du scan Manuel sur \n"' + str(
                name) + '"\ndu ' + str(date_scan).split(' ')[0]

        else:
            titre = 'Rapport du scan Manuel \n démarré le ' + str(
                date_scan).split(' ')[0] + '\n à ' + str(date_scan).split(
                    ' ')[1].split('.')[0]

        chemin_rapport = REP_RAPPORT + 'ScansManuels/' + str(
            int(id_scan)) + '/'

    copyfile(REP_TRAVAIL + 'base.tex',
             REP_TRAVAIL + '/temp/' + nomUnique + '.tex')

    pageGarde(titre, AUTEUR, SOCIETE, LOGO,
              REP_TRAVAIL + '/temp/' + nomUnique + '.tex')

    if type_scan == 'plannifie':
        intro(dictScan[0], dictIP, REP_TRAVAIL + '/temp/' + nomUnique + '.tex',
              'plannifie')

    else:
        intro(dictScan[0], dictIP, REP_TRAVAIL + '/temp/' + nomUnique + '.tex',
              'manuel')

    fichierLatex = open(REP_TRAVAIL + '/temp/' + nomUnique + '.tex', 'a')
    fichierLatex.write('''\\newpage
\\section{Scans}''')
    fichierLatex.close()

    if dictScan[0]['nessus'] == True:
        tableauVuln(retourScan, REP_TRAVAIL + '/temp/' + nomUnique + '.tex')

    if dictScan[0]['nmap'] == True:
        tableauServices(retourServices,
                        REP_TRAVAIL + '/temp/' + nomUnique + '.tex')

    fichierLatex = open(REP_TRAVAIL + '/temp/' + nomUnique + '.tex', 'a')
    fichierLatex.write('''
\\end{document}''')
    fichierLatex.close()

    liste_arguments = [REP_TRAVAIL, nomUnique, chemin_rapport]

    #Contrôle des arguments
    #On s'assure qu'il n'y ait pas d'injection de codes tiers
    for arg in liste_arguments:
        tmp = desatanize(str(arg))

    #Necessaire pour la creation des liens dans le sommaire vers les différentes parties
    for i in range(0, 5):
        try:
            subprocess.check_output([
                'pdflatex -no-file-line-error -interaction=nonstopmode --output-directory '
                + REP_TRAVAIL + 'temp/ ' + REP_TRAVAIL + 'temp/' + nomUnique +
                '.tex >/dev/null &>/dev/null'
            ],
                                    shell=True)
            time.sleep(3)
        except Exception as e:
            logger.error("Erreur generation rapport [" + str(id_scan) +
                         "] : " + str(e))
            pass

    time.sleep(10)
    copyfile(REP_TRAVAIL + 'temp/' + nomUnique + '.pdf',
             chemin_rapport + nomUnique + '_evolution.pdf')
    subprocess.check_output(
        ['rm ' + REP_TRAVAIL + 'temp/' + nomUnique + '* >/dev/null'],
        shell=True)
Esempio n. 15
0
    def __init__(self, fichier):
        self.fichier = fichier

        #Variables de verification
        cursor = connection.cursor()
        cursor.execute(
            'SELECT DISTINCT(nom) FROM application ORDER BY nom ASC')
        self.APPLIS = dictfetchall(cursor)

        cursor.execute('SELECT DISTINCT(ip) FROM hotes')
        temp = dictfetchall(cursor)
        self.LISTE_ADRESSES = []

        for ip in temp:
            self.LISTE_ADRESSES.append(ip['ip'])

        cursor.execute('SELECT DISTINCT(mac) FROM hotes')
        temp = dictfetchall(cursor)
        self.LISTE_MAC = []
        cursor.close()

        for mac in temp:
            self.LISTE_MAC.append(mac['mac'])

        BASE = settings.BASE_DIR + '/'
        Config = ConfigParser.ConfigParser()
        Config.readfp(codecs.open(BASE + "soc/default.cfg", "r", "utf-8"))
        self.LOCALISATION = [elem[0] for elem in Config.items('LOCALISATION')]
        self.TYPE_MACHINE = [elem[0] for elem in Config.items('TYPE')]
        self.LISTE_ENV = [elem[0] for elem in Config.items('ENVIRONNEMENT')]
        '''
        self.LISTE_ENV=('recette','pre-production','production')
        self.TYPE_MACHINE=('equipement-reseau','serveur','vm','appliance')
        self.LOCALISATION=('sarcelles','valence')
        '''
        self.dom = parse(fichier)

        #Liste des éléments pouvant être ajoutés en base pour une machine
        self.elements_hote = [{
            'nom': 'ip',
            'controle': self.valideAdresse
        }, {
            'nom': 'mac',
            'controle': self.valideMacAdresse
        }, {
            'nom': 'hostname',
            'controle': None
        }, {
            'nom': 'os',
            'controle': None
        }, {
            'nom': 'type_machine',
            'controle': self.valideTypeMachine
        }, {
            'nom': 'localisation',
            'controle': self.valideLocalisation
        }, {
            'nom': 'environnement',
            'controle': self.valideEnvironnement
        }, {
            'nom': 'commentaires',
            'controle': None
        }]

        self.NB_ELEMENTS = len(self.elements_hote)
        self.tableau_erreurs = []