# !/bin/python
# -*- coding: utf-8 -*-
u"""SecureTea Social Engineering
Project:
    ╔═╗┌─┐┌─┐┬ ┬┬─┐┌─┐╔╦╗┌─┐┌─┐
    ╚═╗├┤ │  │ │├┬┘├┤  ║ ├┤ ├─┤
    ╚═╝└─┘└─┘└─┘┴└─└─┘ ╩ └─┘┴ ┴
    Author: Digvijay Bhosale <digvijayb1729@gmail.com> August 19 2021
    Version: 1.0
    Module: SecureTea
"""

import subprocess
import os
import time
import datetime
import pandas
import json
import threading
from securetea.lib.malware_analysis import malwareAnalysis
from securetea.lib.malware_analysis import malwareAnalysisJSONDisplay
from securetea.lib.malware_analysis import globals


class ContinuousDefence(threading.Thread):

    def __init__(self, gui=True, API_KEY=None):
        threading.Thread.__init__(self)
        self.gui = gui
        self.API_KEY = API_KEY

        self.mal_extensions = ['exe',
                               'doc', 'docx', 'docm', 'rtf',
                               'xls', 'xlsx',
                               'hta', 'html', 'htm',
                               'js', 'jar',
                               'py',
                               'vbs', 'vb',
                               'pdf',
                               'sfx', 'dll', 'bat', 'tmp', '.py', 'scr', 'zip', '7z', 'bz', 'gz', 'com',
                               'jpeg', 'jpg', 'png', 'mng'
                               ]
        self.high_threat_ext = ['exe',
                                'pdf'
                               ]
        self.djvu_ext = ['shadow', 'djvu', 'djvur', 'djvuu', 'udjvu', 'uudjvu', 'djvuq', 'djvus', 'djvur', 'djvut',
                         'pdff', 'tro', 'tfude', 'tfudet', 'tfudeq', 'rumba', 'adobe', 'adobee', 'blower', 'promos',
                         'promoz', 'promorad', 'promock', 'promok', 'promorad2', 'kroput', 'kroput1', 'pulsar1',
                         'kropun1', 'charck', 'klope', 'kropun', 'charcl', 'doples', 'luces', 'luceq', 'chech',
                         'proden', 'drume', 'tronas', 'trosak', 'grovas', 'grovat', 'roland', 'refols', 'raldug',
                         'etols', 'guvara', 'browec', 'norvas', 'moresa', 'vorasto', 'hrosas', 'kiratos', 'todarius',
                         'hofos', 'roldat', 'dutan', 'sarut', 'fedasot', 'berost', 'forasom', 'fordan', 'codnat',
                         'codnat1', 'bufas', 'dotmap', 'radman', 'ferosas', 'rectot', 'skymap', 'mogera', 'rezuc',
                         'stone', 'redmat', 'lanset', 'davda', 'poret', 'pidom', 'pidon', 'heroset', 'boston', 'muslat',
                         'gerosan', 'vesad', 'horon', 'neras', 'truke', 'dalle', 'lotep', 'nusar', 'litar', 'besub',
                         'cezor', 'lokas', 'godes', 'budak', 'vusad', 'herad', 'berosuce', 'gehad', 'gusau', 'madek',
                         'darus', 'tocue', 'lapoi', 'todar', 'dodoc', 'bopador', 'novasof', 'ntuseg', 'ndarod',
                         'access', 'format', 'nelasod', 'mogranos', 'cosakos', 'nvetud', 'lotej', 'kovasoh', 'prandel',
                         'zatrov', 'masok', 'brusaf', 'londec', 'krusop', 'mtogas', 'nasoh', 'nacro', 'pedro', 'nuksus',
                         'vesrato', 'masodas', 'cetori', 'stare', 'carote', 'gero', 'hese', 'seto', 'peta', 'moka',
                         'kvag', 'karl', 'nesa', 'noos', 'kuub', 'reco', 'bora', 'reig', 'tirp', 'plam', 'cosd', 'ygkz',
                         'cadq', 'ribd', 'qlkm', 'coos', 'wbxd', 'pola']
        self.directory = ''
        self.mal_files = {}
        self.djvu_files = {}

        globals.initialize()
        globals.initialize_colours()

    def run(self):
        """
        program flow starts here
        """
        while True:
            try:
                self.find_home()
                # self.directory = '/home/fox/GSOC/OWASP/SecureTea-Dev/test_files'
                self.find_malicious_extensions()
                self.scan_mal_files()
                print(globals.GRAY + 'Scan completed at : ' + str(datetime.datetime.now().time()) + globals.END)
                if self.gui:
                    globals.ctime = str(datetime.datetime.now().time())
                print(globals.GRAY + "Next Scan in 1 hour" + globals.END)
                self.mal_files.clear()
                self.djvu_files.clear()
                time.sleep(3600)
                # time.sleep(60)
            except KeyboardInterrupt:
                print(globals.WARNING + '\nKeyboardInterrupt... Quitting' + globals.END)
                exit(0)

    def dev_runner(self, files_dict):  # implements threading. NOT A START POINT OF PROGRAM
        """
        uses threading to send files to malwareAnalysis.py
        Uses global variables from globals.py
        Starts threads
        Global vars intialized here
        Edited in JSONDisplay.py
        Accessed here again
        """
        globals.detected.clear()
        globals.undetected.clear()
        globals.unsupported.clear()
        globals.total.clear()
        globals.report_id.clear()

        # print(*list(self.mal_files.keys()), sep="\n")

        thread_list = []

        for mal_file in files_dict.keys():
            t = threading.Thread(target=self.scan_mal_files_threading, args=(mal_file,))
            thread_list.append(t)
            t.start()
            time.sleep(15)

        for a_thread in thread_list:
            a_thread.join()

        '''
        if len(self.mal_files.keys()) < 100:
            print(globals.OKBLUE + 'Number of files < 100. Scanning all files' + globals.END)
            for mal_file in self.mal_files.keys():
                t = threading.Thread(target=self.scan_mal_files_threading, args=(mal_file,))
                thread_list.append(t)
                t.start()
                time.sleep(15)

            for a_thread in thread_list:
                a_thread.join()
        else:
            print(globals.OKBLUE + 'Number of files > 100. Scanning important files only' + globals.END)
            no_of_files_is_0 = True
            for mal_file in self.mal_files.keys():
                if self.mal_files[mal_file] in self.high_threat_ext:
                    no_of_files_is_0 = False
                    t = threading.Thread(target=self.scan_mal_files_threading, args=(mal_file,))
                    thread_list.append(t)
                    t.start()
                    time.sleep(15)
                if no_of_files_is_0:
                    return 'detected', 'undetected', 'unsupported', 'total', 'report_id'
        '''

        return globals.detected, globals.undetected, globals.unsupported, globals.total, globals.report_id

    def scan_mal_files_threading(self, filename):
        mal_obj = malwareAnalysis.MalwareAnalysis(filename=filename, API_KEY=self.API_KEY)
        mal_obj.threat_level_threading()

    def find_home(self):
        """
        finds home directory
        """
        base_directory = '/home'
        process = subprocess.Popen(['ls', base_directory],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        stdout, stderr = process.communicate()
        data = stdout.decode('utf-8')
        stderr = stderr.decode('utf-8')
        data = data.split('\n')
        data = str(data[0])
        # print(data)
        self.directory = base_directory + '/' + data

    def find_malicious_extensions(self):
        """
        finds files modified last 1 hour with probablmalicious extensions. stores that in
        self.djvu_files
        self.mal_files
        """
        process = subprocess.Popen(['find', self.directory, '-type', 'f', '-mmin', '-72'],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        '''
        1.2 hours because scan takes some time
        in that time, user may download some files that may go unnoticed by our program
        '''
        stdout, stderr = process.communicate()
        data = stdout.decode('utf-8')
        stderr = stderr.decode('utf-8')
        data = data.split('\n')
        for filename in data:
            temp = filename.split('/')[-1]
            ext = temp.split('.')
            if len(ext) == 1:
                ext = ''
            else:
                ext = ext[-1]

            if ext.lower() in self.djvu_ext:
                print(globals.HEADER + 'DJVU Ransomware detected' + globals.END)
                self.djvu_files[filename] = ext
            elif ext.lower() in self.mal_extensions:
                self.mal_files[filename] = ext

    def scan_mal_files(self):
        """
        Sends the mal files for scanning.
        Takes 5 dicts from dev_runner
        loads it into a dataframe
        Prints table
        """
        print(globals.HEADER + 'Total number of files changed in past 1 hour : ' + str(
            len(self.mal_files.keys())) + globals.END)
        for mal_file in self.mal_files.keys():
            print(mal_file)
        print(globals.HEADER + 'Total number of DJVU files found in past 1 hour : ' + str(
            len(self.djvu_files.keys())) + globals.END)
        for djvu_file in self.djvu_files.keys():
            print(globals.ALERT + djvu_file + globals.END)

        if len(self.djvu_files.keys()) != 0:
            if self.gui:
                for djvu_file in self.djvu_files:
                    globals.djvu_files.append(djvu_file)
                    # print("File in globals.djvu_files")

        # no of mal files = 0
        if len(self.mal_files.keys()) == 0:
            return

        crit_files = {}
        # no of mal files < 100  --> scan all files
        if len(self.mal_files.keys()) < 100:
            print(globals.OKBLUE + 'Number of files < 100. Scanning all files' + globals.END)
            detected, undetected, unsupported, total, report_id = self.dev_runner(files_dict=self.mal_files)

        # if no of mal files > 100  --> scan critical files
        else:
            print(globals.OKBLUE + 'Number of files > 100. Scanning critical files only' + globals.END)
            no_of_files_is_0 = True
            for mal_file in self.mal_files.keys():
                if self.mal_files[mal_file] in self.high_threat_ext:
                    print(mal_file)
                    no_of_files_is_0 = False
                    crit_files[mal_file] = self.mal_files[mal_file]

            if no_of_files_is_0:
                print('No Critical Files found')
                return
            else:
                detected, undetected, unsupported, total, report_id = self.dev_runner(files_dict=crit_files)

        mal_file_dict = {}

        for mal_file in total.keys():
            mal_file_dict[mal_file] = [detected[mal_file],
                                       undetected[mal_file],
                                       unsupported[mal_file],
                                       total[mal_file],
                                       report_id[mal_file]]

        if self.gui:
            for filename in mal_file_dict:
                globals.mal_file_dict[filename] = mal_file_dict[filename]

        # print(globals.WARNING + 'globals.mal_file_dict' + globals.END)
        # print(globals.WARNING + str(globals.mal_file_dict) + globals.END)

        mal_file_dict = str(mal_file_dict)
        mal_file_dict = mal_file_dict.replace('\'', '\"')
        mal_file_dict = json.loads(mal_file_dict)
        mal_df = pandas.DataFrame(mal_file_dict)
        mal_df = mal_df.transpose()

        mal_df.columns = ['Detected', 'Undetected', 'Unsupported', 'Total', 'Report ID']
        print(globals.WHITE + mal_df.to_string() + globals.END)
