Пример #1
0
def manda_correo(para, cc, cco, msg):
    """
    Se envia un correo con el mensaje especificado
    """
    server = None
    b = True
    try:
        if settings.CORREO_SSL:
            server = smtplib.SMTP_SSL(settings.CORREO_SERVIDOR, settings.CORREO_PUERTO)
        else:
            server = smtplib.SMTP(settings.CORREO_SERVIDOR, settings.CORREO_PUERTO)
            server.starttls()
        usr = settings.CORREO_USR
        passw = settings.CORREO_PASS
        if usr and passw:
            server.login(usr, passw)
        server.sendmail(usr, para + cc + cco, msg)
        log.log('Correo enviado. To:%s, Cc:%s, Bcc:%s' % (', '.join(para if para else []),
                                                      ', '.join(cc if cc else []),
                                                          ', '.join(cco if cco else [])), "correo.log")
    except Exception as e:
        log.log('Error: %s' % str(e), "correo.log")
        b = False
    finally:
        if server:
            server.quit()
        return b
Пример #2
0
def obten_urls(body, html=False):
    textos = [body]
    if html:
        try:
            soup = BeautifulSoup(body, 'html.parser')
            textos = []
            for x in soup.findAll(text=True):
                x = x.strip()
                if x:
                    textos.append(x)            
            for link in soup.find_all('a'):
                textos.append(link.get('href', ''))
        except Exception as e:
            log.log("Error al leer HTML: %s" % str(e), "correo.log")
    regex1 = re.compile(r"hxxp://")
    regex2 = re.compile(r"hxxps://")
    regex3 = re.compile(r" ?[(\[][.][)\]] ?")
    regex4 = re.compile(r" ?[(\[]dot[)\]] ?")
    urls = []
    for t in textos:
        try:
            t = regex1.sub('http://', t)
            t = regex2.sub('https://', t)
            t = regex3.sub('.', t)
            t = regex3.sub('.', t)
            urls += re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', t)
        except Exception as e:
            log.log("Error al extraer urls de correo: %s" % str(e), "correo.log")
    return urls
Пример #3
0
def get_mime(archivo):
    try:
        f = magic.Magic(mime=True)
        return f.from_buffer(archivo)
    except Exception as e:
        log.log("Error al leer archivo de entrada: %s" % str(e),
                "verifica_urls.log")
    return ''
Пример #4
0
def parsecorreo_aux(texto, nombre, archivos, urls, usuario_autenticado):
    try:
        mensaje = email.message_from_string(texto)
    except Exception as e:
        log.log("Error al leer correo %s: %s" % (nombre, str(e)), "correo.log")
        return None
    analiza_correo(mensaje, archivos, urls, usuario_autenticado)
    return mensaje    
Пример #5
0
def verifica_urls(request):
    if request.method == 'POST':
        if request.POST.get("boton_urls"):
            form = UrlsForm(request.POST)
            if form.is_valid():
                urls = form.cleaned_data['urls']
                urls_limpias = []
                for x in urls.split('\n'):
                    x = x.strip()
                    if x:
                        for y in x.split(','):
                            for z in y.split(' '):
                                z = z.strip()
                                if z:
                                    urls_limpias.append(z)
                urls_limpias = list(set(urls_limpias))
                sitios = phishing.verifica_urls(urls_limpias,
                                                "verifica_urls.log")
                urls = Url.objects.filter(pk__in=[x.pk
                                                  for x in sitios]).distinct()
                context = aux.context_reporte(urls)
                return render(request,
                              'verifica_urls/reporte_verificacion.html',
                              context)
        elif request.POST.get("boton_archivo") and request.FILES.get(
                'file', None):
            form = ArchivoForm(request.POST)
            f = request.FILES['file'].read()
            if not get_mime(f).startswith('text'):
                archivo = request.FILES['file'].name
                log.log(
                    "Ingresado archivo de entrada invalido: '%s'" % archivo,
                    "verifica_urls.log")
                context = {'archivo': archivo}
                return render(request, 'verifica_urls/error_archivo.html',
                              context)
            f = f.decode('utf-8', errors='ignore')
            name = request.FILES['file'].name
            urls = []
            if name.endswith('.json'):
                urls = entrada.lee_json(f)
            elif name.endswith('.csv'):
                urls = entrada.lee_csv(f)
            else:
                urls = entrada.lee_txt(f)
            urls = [x for x in list(set(urls)) if x]
            sitios = phishing.verifica_urls(urls, "verifica_urls.log")
            urls = Url.objects.filter(pk__in=[x.pk for x in sitios]).distinct()
            context = aux.context_reporte(urls)
            return render(request, 'verifica_urls/reporte_verificacion.html',
                          context)
    form1 = UrlsForm()
    form2 = ArchivoForm()
    return render(request, 'verifica_urls/verifica_urls.html', {
        'form1': form1,
        'form2': form2
    })
Пример #6
0
def url_ignora(url):
    url.ignorado = True
    url.timestamp_actualizacion = timezone.localtime(timezone.now())
    url.save()
    i = url.obten_info
    if i:
        i.deteccion = 'N'
        i.save()
    log.log("URL '%s' ignorada" % url.url, "monitoreo.log")
Пример #7
0
def url_reporta(url, ticket):
    url.ticket = ticket
    url.timestamp_actualizacion = ticket.timestamp
    url.save()
    i = url.obten_info
    if i and (i.deteccion != 'P' or i.deteccion != 'M'):
        i.deteccion = 'P'
        i.timestamp_deteccion = ticket.timestamp
        i.save()
    log.log("URL '%s' reportada" % url.url, "monitoreo.log")
Пример #8
0
 def handle(self, *args, **options):
     log.log('Comienza generación de reportes de salida', "salida.log")
     hoy = timezone.localtime(timezone.now()).date()
     urls_hoy = Url.objects.filter(timestamp_creacion__date=hoy).order_by(
         'url', '-timestamp_creacion').distinct('url')
     urls_pk = []
     for x in urls_hoy:
         i = x.obten_info
         if i and (i.deteccion == 'P' or i.deteccion == 'M'):
             urls_pk.append(x.pk)
     urls = Url.objects.filter(pk__in=urls_pk)
     d = os.path.join(settings.DIR_SALIDA, str(hoy))
     if not os.path.exists(d):
         os.makedirs(d)
     with open(os.path.join(d, 'ips.txt'), 'a') as ips, \
          open(os.path.join(d, 'phishing.txt'), 'a') as phishing, \
          open(os.path.join(d, 'redirecciones.txt'), 'a') as red, \
          open(os.path.join(d, 'maliciosos.txt'), 'a') as mal, \
          open(os.path.join(d, 'firewall.txt'), 'a') as fire, \
          open(os.path.join(d, 'snort.txt'), 'a') as snort, \
          open(os.path.join(d, 'formato.txt'), 'a') as form, \
          open(os.path.join(d, 'sitios.json'), 'w') as sitios:
         for u in urls:
             if u.es_redireccion:
                 red.write('%s\n' % u.url)
             i = u.obten_info
             if i and i.deteccion == 'P':
                 phishing.write('%s\n' % u.url)
             elif i and i.deteccion == 'M':
                 mal.write('%s\n' % u.url)
             asn = '-'
             nom = '-'
             if u.dominio.asn:
                 a = u.dominio.asn
                 asn = a.asn
                 nom = a.nombre
             ip = '-'
             if u.dominio.ip:
                 ip = u.dominio.ip
             t = time.strftime('%Y-%m-%d %H:%M:%S')
             form.write('%s | %s | %s | %d saapm %d %s | %s\n' %
                        (asn, ip, t, u.pk, u.pk, u.url, nom))
         urls_dom = urls.distinct('dominio')
         for u in urls_dom:
             snort.write(
                 'Alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS '
                 '(msg:"Regla sitio malicioso"; flow:to_server,established; content:'
                 '"%s"; nocase; sid:%d; rev:1;)\n' %
                 (u.dominio.dominio, randint(10000000, 20000000)))
             if u.dominio.ip:
                 ips.write('%s\n' % u.dominio.ip)
                 fire.write('iptables -A INPUT -s %s -j DROP\n' %
                            u.dominio.ip)
         json.dump(self.json_urls(urls), sitios, indent=4)
     log.log('Generados reportes de salida', "salida.log")
Пример #9
0
def es_malicioso(HASH_sha256):
    resultado = None
    try:
        vt = VirusTotalPublicApi(settings.VIRUSTOTAL_API_KEY)
        response = vt.get_file_report(HASH_sha256)
        resultado = json.loads(json.dumps(response))
    except Exception as e:
        log.log('Error: %s' % str(e), "correo.log")
        return False
    resultados = resultado.get('results', None) if resultado else None
    return resultados and resultados.get('positives', 0) > 0
Пример #10
0
def adjunta_imagen(msg, sitio):
    """
    Se ajunta un archivo al mensaje msg
    """
    try:
        with sitio.captura.open(mode='rb') as a_file:
            basename = os.path.basename(sitio.captura_url)
            part = MIMEApplication(a_file.read(), Name=basename)
            part['Content-Disposition'] = 'attachment; filename="%s"' % basename
            msg.attach(part)
    except Exception as e:
        log.log('Error: %s' % str(e), "correo.log")
Пример #11
0
def cambia_frecuencia(funcion, n):
    n = 1 if n < 1 or n > 24 else n
    comando = "/bin/bash -c 'source %s/bin/activate && python %s/manage.py %s'" % \
              (settings.DIR_ENV, settings.BASE_DIR, funcion)
    process = Popen('crontab -l | egrep -v "%s"  | crontab -' % (comando),
                    shell=True,
                    stdout=PIPE,
                    stderr=PIPE)
    out, err = process.communicate()
    if err:
        log.log("Error: %s" % err.decode('utf-8', errors='ignore'),
                "ajustes.log")
    if out:
        log.log(out.decode('utf-8', errors='ignore'), "ajustes.log")
    i = "*/%d" % n if n < 24 else '0'
    process = Popen(
        '(crontab -l ; echo "0 %s * * * %s") | sort - | uniq - | crontab -' %
        (i, comando),
        shell=True,
        stdout=PIPE,
        stderr=PIPE)
    out, err = process.communicate()
    if err:
        log.log("Error: %s" % err.decode('utf-8', errors='ignore'),
                "ajustes.log")
    if out:
        log.log(out.decode('utf-8', errors='ignore'), "ajustes.log")
Пример #12
0
def obten_plantilla(mensaje, dominio, urls, ticket=''):
    dicc = crea_diccionario(dominio, urls)
    dicc['ticket'] = ticket
    try:
        plantilla = settings.PLANTILLA_CORREO_ASUNTO
        if mensaje:
            plantilla = settings.PLANTILLA_CORREO_MENSAJE
        if (dominio.ip and (dominio.ip.startswith('132.248') or dominio.ip.startswith('132.247'))) \
           or dominio.dominio.endswith('unam.mx'):
            plantilla = settings.PLANTILLA_UNAM_ASUNTO
            if mensaje:
                plantilla = settings.PLANTILLA_UNAM_MENSAJE
        s = obten_texto(mensaje, plantilla).format_map(dicc)
        return s
    except Exception as e:
        log.log('Error: %s' % str(e), "correo.log")
        return 'Error en formato de texto'
Пример #13
0
def guarda_payload(nombre, payload, malicioso):
    adjunto = None
    try:
        adjunto = ArchivoAdjunto(malicioso=malicioso)
        z_payload = gzip.compress(payload)
        adjunto.archivo.save(nombre, ContentFile(z_payload))
        adjunto.save()
    except IntegrityError:
        hoy = timezone.localtime(timezone.now())
        adjuntos = ArchivoAdjunto.objects.filter(timestamp__date=hoy.date())
        for archivo in adjuntos:
            if archivo.filename == nombre:
                return archivo
        return None
    except Exception as e:
        log.log("Error al guardar archivo adjunto '%s': %s" % (archivo, str(e)), "correo.log")
        return None
    return adjunto
Пример #14
0
def agrega_imagen(fig, documento, titulo, descripcion):
    try:
        a = ''.join(
            random.choice(string.ascii_uppercase + string.digits)
            for _ in range(8))
        path = '/tmp/%s.png' % a
        fig.savefig(path)
        plt.clf()
        q = documento.add_paragraph()
        q.alignment = WD_ALIGN_PARAGRAPH.CENTER
        q.add_run(titulo.upper()).bold = True
        q.add_run("\n%s" % descripcion)
        documento.add_picture(path)
        q = documento.add_paragraph()
        run = q.add_run()
        run.add_break(WD_BREAK.PAGE)
        os.remove(path)
    except Exception as e:
        log.log('Error: %s' % str(e), 'reportes.log')
Пример #15
0
 def handle(self, *args, **options):
     log.log('Comieza verificación de URLs', 'monitoreo.log')
     urls = Url.objects.filter(timestamp_desactivado__isnull=True)
     sitios = phishing.verifica_urls_cron(urls)
     for x in sitios:
         log.log("URL '%s' verificada" % str(x), 'monitoreo.log')
     log.log('Termina verificación de URLs', 'monitoreo.log')
Пример #16
0
def analisis_archivo(attachment, usuario_autenticado):
    """
    Esta funcion analiza los archivos contenidos en los correos
    """
    datos = {}
    try:
        datos['Tipo'] = attachment.get_content_type()
        payload = attachment.get_payload(decode=True)
        datos['Tamaño'] = humanize.naturalsize(0)
        if payload:
            datos['Tipo'] = magic.from_buffer(payload, mime=True)
            sha256_h = sha256(payload)
            archivo = "%s.gz" % sha256_h
            malicioso = es_malicioso(sha256_h)
            guarda = guarda_payload(archivo, payload, malicioso)
            if guarda and usuario_autenticado:
                datos['Archivo'] = guarda
            datos['Tamaño'] = humanize.naturalsize(len(payload))
            datos['Es malicioso'] = 'Sí' if malicioso else 'No'
            datos['Referencia'] = "https://www.virustotal.com/#/search/%s" % sha256_h
        content_disposition = attachment.get("Content-Disposition", None)
        if content_disposition:
            dispositions = content_disposition.strip().split(";")
            for param in dispositions[1:]:
                param = param.strip()
                k, v = param.split("=")
                k = k.lower()
                if k == "filename":
                    datos['Nombre'] = v
                elif k == "create-date":
                    datos['Fecha de creación'] = v
                elif k == "modification-date":
                    datos['Fecha de modificación'] = v
                elif k == "read-date":
                    datos['Fecha de lectura'] = v
    except Exception as e:
        log.log('Error: %s' % str(e), "correo.log")
        return None
    return datos
Пример #17
0
 def handle(self, *args, **options):
     log.log("Inicia ejecucion de script de notificacion",
             "notificacion.log")
     dir_correos = settings.DIR_CORREOS
     log.log("Directorio base de correos: %s" % dir_correos,
             "notificacion.log")
     p = os.path.join(dir_correos, "procesados")
     if not os.path.exists(p):
         os.mkdir(p)
     archivos = [
         f for f in os.listdir(dir_correos)
         if os.path.isfile(os.path.join(dir_correos, f))
     ]
     for archivo in archivos:
         log.log("Leyendo archivo %s" % archivo, "notificacion.log")
         a = os.path.join(dir_correos, archivo)
         with open(a) as f:
             headers, urls, _, _, error = correo.parsecorreo(
                 f.read(), archivo, False)
             urls = list(set(urls))
             sitios = phishing.verifica_urls(urls, "notificacion.log")
             for u in urls:
                 log.log("Verificada URL %s" % u, "notificacion.log")
             if headers.get('Subject', '') == 'Reporte Phishing - TSU':
                 dominios = []
                 for s in sitios:
                     dominios.append(s.dominio)
                 dominios = list(set(dominios))
                 for d in dominios:
                     urls0 = d.urls_activas
                     urls = []
                     sitios = []
                     for u in urls0:
                         i = u.obten_info
                         if i and (i.deteccion == 'P' or i.deteccion == 'M') and \
                            i.entidad_afectada:
                             sitios.append(i)
                             urls.append(u)
                     if len(urls) == 0:
                         continue
                     sitios = list(set(sitios))
                     hoy = timezone.localtime(timezone.now())
                     cadena_urls = ''.join([x.identificador for x in urls])
                     md = phishing.md5((d.dominio + cadena_urls).encode(
                         'utf-8', 'backslashreplace'))
                     ticket = (
                         '%d%02d%02d%s' %
                         (hoy.year, hoy.month, hoy.day, md[:7])).upper()
                     de = settings.CORREO_DE
                     para = [
                         '*****@*****.**',
                         '*****@*****.**'
                     ]
                     cc = []
                     cco = ['*****@*****.**'
                            ]  #settings.CORREO_CCO.split()
                     urls_qs = Url.objects.filter(
                         pk__in=[u.pk for u in urls])
                     asunto = correo.obten_asunto(d, urls_qs, ticket)
                     mensaje = correo.obten_mensaje(d, urls_qs, ticket)
                     msg = correo.genera_mensaje(de, para, cc, cco, asunto,
                                                 mensaje, sitios)
                     enviado = correo.manda_correo(para, cc, cco, msg)
                     if not enviado:
                         log.log("Error al reportar dominio %s" % d.dominio,
                                 "notificacion.log")
                     else:
                         ts = timezone.localtime(timezone.now())
                         try:
                             ticketO = Ticket.objects.get(ticket=ticket)
                         except:
                             ticketO = Ticket(ticket=ticket, timestamp=ts)
                             ticketO.save()
                         for u in urls:
                             url_reporta(u, ticketO)
                             log.log("URL %s reportada" % u.url,
                                     "notificacion.log")
         os.rename(a, os.path.join(p, archivo))
     log.log("Termino ejecucion del script", "notificacion.log")
Пример #18
0
 def handle(self, *args, **options):
     archivo = options['archivo'][0]
     if not os.path.exists(archivo):
         self.stderr.write(
             self.style.ERROR('El archivo "%s" no existe.' % archivo))
         return
     with open(archivo, 'rb') as f:
         texto = f.read().decode('utf-8', errors='ignore')
     resultados, urls, headers, archivos, error = correo.parsecorreo(
         texto, archivo, False)
     if error:
         log.log("Error al leer correo '%s'" % archivo, "correo.log")
         return
     sitios = phishing.verifica_urls(urls, "correo.log")
     if options['verbosity'] > 1:
         for u in sitios:
             self.stdout.write("URL '%s' verificada" % u.url)
     self.stdout.write(self.style.SUCCESS('Correo procesado exitósamente.'))
     if options['cabeceras']:
         self.stdout.write("CABECERAS\n\n")
         for k, v in resultados.items():
             self.stdout.write("%s: %s" % (k, v))
     if options['raw']:
         self.stdout.write("\nRAW\n\n")
         self.stdout.write(headers)
     if options['adjuntos']:
         self.stdout.write("\nARCHIVOS ADJUNTOS")
         for archivo in archivos:
             self.stdout.write("")
             for k, v in archivo.items():
                 self.stdout.write("%s: %s" % (k, v))
     if options['reporte-urls']:
         self.stdout.write("\nREPORTE DE URLS\n\n")
         urls = Url.objects.filter(pk__in=[x.pk for x in sitios]).distinct()
         context = aux.context_reporte(urls)
         self.stdout.write("# Sitios analizados: %d" %
                           context['urls_total'])
         self.stdout.write("# Sitios activos: %d" %
                           context['num_urls_activas'])
         self.stdout.write("# Sitios inactivos: %d" %
                           context['num_urls_inactivas'])
         self.stdout.write("# Redirecciones: %d" %
                           context['num_urls_redirecciones'])
         self.stdout.write("# Dominios afectados: %d\n" %
                           len(context['dominios']))
         self.stdout.write("\nENTIDADES")
         for e in context['entidades']:
             self.stdout.write("	%s: %d" % (e[0], e[1]))
         self.stdout.write("\nTÍTULOS")
         for e in context['titulos']:
             self.stdout.write("	%s: %d" % (e[0], e[1]))
         self.stdout.write("\nDOMINIOS")
         for e in context['dominios']:
             self.stdout.write("	%s: %d" % (e[0], e[1]))
         self.stdout.write("\nPAÍSES")
         for e in context['paises']:
             self.stdout.write("	%s: %d" % (e[0], e[1]))
         for u in urls:
             self.stdout.write("\nURL: %s" % u.url)
             self.stdout.write("IP: %s" % u.dominio.ip_str)
             self.stdout.write("Código: %s" % u.codigo_str)
             self.stdout.write("Estado: %s" % u.estado)
             self.stdout.write("Correos de abuso: %s" %
                               u.dominio.correos_str)
             self.stdout.write("ISP: %s" % u.dominio.isp_str)
             self.stdout.write("País: %s" % u.dominio.pais_str)
             self.stdout.write("ASN: %s" % u.dominio.asn_str)
             self.stdout.write("Servidor web: %s" % u.dominio.servidor_str)
             self.stdout.write("RIR: %s" % u.dominio.rir_str)
             self.stdout.write("Sevidores DNS: %s" % u.dominio.dns_str)
             self.stdout.write("Fecha de creción: %s" %
                               u.timestamp_creacion)
             self.stdout.write("Ignorado: %s" % u.ignorado_str)
             self.stdout.write("Reportado: %s" % u.reportado_str)
             self.stdout.write("Detección: %s" % u.deteccion_str)
             self.stdout.write("Entidad afectada: %s" %
                               u.entidad_afectada_str)
             ua = u.obten_info_activa
             if ua:
                 self.stdout.write("Título: %s" % ua.titulo_str)
                 self.stdout.write("Ofuscación: %s" % ua.ofuscaciones_str)
                 self.stdout.write("Hash MD5 de archivo: %s" %
                                   ua.hash_archivo_str)
     self.stdout.flush()
Пример #19
0
 def handle(self, *args, **options):
     log.log("Inicia ejecucion de script de correos", "correo.log")
     d = settings.DIR_CORREOS
     log.log("Directorio base de correos: %s" % d, "correo.log")
     p = os.path.join(d, "procesados")
     if not os.path.exists(p):
         os.mkdir(p)
     archivos = [
         f for f in os.listdir(d) if os.path.isfile(os.path.join(d, f))
     ]
     for x in archivos:
         log.log("Leyendo archivo %s" % x, "correo.log")
         a = os.path.join(d, x)
         with open(a) as f:
             _, urls, _, _, error = correo.parsecorreo(f.read(), x, False)
             if error:
                 log.log("Error al leer correo '%s'" % a, "correo.log")
             else:
                 urls = list(set(urls))
                 phishing.verifica_urls(urls, "correo.log")
                 for u in urls:
                     log.log("Verificada URL %s" % u, "correo.log")
         os.rename(a, os.path.join(p, x))
     log.log("Termino ejecucion del script", "correo.log")