def createShortcut(self, url, fakeUrl, fakeText, domainShortener='tinyurl', api_key=None, user_id=None): try: short = Shortener(api_key=api_key, user_id=user_id) if domainShortener in short.available_shorteners: sh = eval('short.{do}'.format(do=domainShortener)) endLink = sh.short(url) withouthttp = endLink[7:] if withouthttp.startswith('/'): withouthttp = withouthttp[1:] fakeUrl = fakeUrl.replace('http://', '').replace('https://', '').replace('www.', '') fakeText = '-'.join(fakeText.split(' ')) return "https://www.{dom}-{post}@{withouthttp}".format( dom=fakeUrl, post=fakeText, withouthttp=withouthttp) return "" except Exception as e: Logger.printMessage(str(e), is_warn=True) return ""
def set_mp3_metadata(self, mp3_file, title=None, artist=None, album=None, album_artist=None, track_num=None): try: new_file = "edited-{f}".format(f=os.path.split(mp3_file)[1]) new_file = os.path.join(output_dir, new_file) audioFile = eyed3.load(mp3_file) if title: audioFile.tag.title = title if artist: audioFile.tag.artist = artist if album: audioFile.tag.album = album if album_artist: audioFile.tag.album_artist = album_artist if track_num: audioFile.tag.title = track_num audioFile.tag.save(new_file) return new_file except Exception as e: Logger.printMessage(str(e), is_error=True) return str(e)
def get_mp3_exif(self, mp3_file): try: audioFile = eyed3.load(mp3_file) keys = [ tag for tag in dir(audioFile.tag) if not tag.startswith('_') ] data = {} for k in keys: temp = eval("audioFile.tag.{f}".format(f=k)) if temp is not None and temp: if not isinstance(temp, str): subkeys = [ t for t in dir(temp) if not t.startswith('_') ] if subkeys: data[k] = {} for s in subkeys: new_temp = eval("audioFile.tag.{f}.{r}".format( f=k, r=s)) if new_temp is not None and new_temp: if isinstance(new_temp, str): if str(new_temp) != 'None': data[k][s] = str(new_temp) if k in data and not data[k]: del data[k] else: data[k] = str(temp) return data except Exception as e: Logger.printMessage(str(e), is_error=True) return str(e)
def extractFilePassword(self, zipPathName, password='', posible_combinations=1, output_dir_new=None): #ZipFile only works with 7z with ZypCrypto encryption for setting the password try: Logger.printMessage( message="extractFilePassword", description='ZIP - {pwd} - {msg_posible_comb}: {com}'.format( pwd=password, msg_posible_comb=config['posible_combinations'], com=posible_combinations), debug_module=True) with ZipFile(zipPathName) as zf: zf.extractall( output_dir if not output_dir_new else output_dir_new, pwd=str.encode(password)) return password except Exception as e: Logger.printMessage(message="extractFilePassword", description='{e} - {p}'.format(e=str(e), p=password), is_error=True) return None
def queryShodan(self, category='', osintDays=100, shodan_api=None): try: Logger.printMessage( message='{methodName}'.format(methodName='queryShodan'), debug_module=True) days_back = int(osintDays) + 1 limit_date = (datetime.date.today() - datetime.timedelta(days=days_back)).strftime( config['search_limit_date_format']) search_term = 'category:{category} after:{time}'.format( category=category, time=limit_date) searcher = self.__getShodanByAPI__(shodan_api) if searcher: results = searcher.search(search_term, page=1) Logger.printMessage(message='{message_result}: {res}'.format( message_result=config['msg_result_found'], res=results['total']), debug_module=True) pages = results['total'] / 100 if results['total'] % 100 > 0: pages += 1 ip_list = [] for n in range(1, pages + 1): if n > 1: results = searcher.search(search_term, page=n) Logger.printMessage( message='{msg_fetch_page} {num} of {pages}...'. format(msg_fetch_page=config['msg_fetch_page'], num=n, pages=pages), debug_module=True) for result in results['matches']: ip_list.append(result['ip_str']) return ip_list else: return [] except Exception as e: Logger.printMessage(message='{error}: {error_msg}'.format( error=config['error'], error_msg=e), debug_module=True) return [] except Exception as e: Logger.printMessage(message='{error}: {error_msg}'.format( error=config['error'], error_msg=e), debug_module=True) return []
def upload_files(self, files): """Upload multiple files to a remote directory.""" if self.client is None: self.client = self.__connect__() uploads = [self.__upload_single_file__(file) for file in files] Logger.printMessage( f'Finished uploading {len(uploads)} files to {self.remote_path} on {self.host}', debug_module=True)
def extractFile(self, zipPathName, password=None): #ZipFile only works with 7z with ZypCrypto encryption for setting the password try: with ZipFile(zipPathName) as zf: return zf.extractall(password) if password else zf.extractall(os.path.split(zipPathName)[0]) except Exception as e: Logger.printMessage(message="extractFile", description=str(e), is_error=True) return None
def executeScan(self, ip, params=''): Logger.printMessage( message='{methodName}'.format(methodName='executeScan'), description='{param}'.format(param=ip), debug_module=True) nm = nmap.PortScanner() try: return dict(nm.scan(hosts=ip, arguments=params)) except: return {}
def __upload_ssh_key__(self): try: os.system( f'scp -i {self.ssh_key_filepath} {self.user}@{self.host}') os.system( f'scp -i {self.ssh_key_filepath}.pub {self.user}@{self.host}') except FileNotFoundError as e: Logger.printMessage(e, is_error=True) except Exception as e: Logger.printMessage(e, is_error=True)
def execute_commands(self, commands): """Execute multiple commands in succession.""" if self.client is None: self.client = self.__connect__() for cmd in commands: stdin, stdout, stderr = self.client.exec_command(cmd) stdout.channel.recv_exit_status() response = stdout.readlines() for line in response: Logger.printMessage(f'INPUT: {cmd} | OUTPUT: {line}')
def getSSLCerts(self, ip, shodan_api=None): res = {} try: searcher = self.__getShodanByAPI__(shodan_api) Logger.printMessage( message='{methodName}'.format(methodName='getSSLCerts'), debug_module=True) for banner in searcher.stream.ports([443, 8443]): if 'ssl' in banner: res['ssl'] = banner['ssl'] except Exception as e: res['ssl'] = None return res
def search_host(self, ip, shodan_api=None, count_loop_try=0): res = {} if count_loop_try > 5: return res try: Logger.printMessage( message='{methodName}'.format(methodName='search_host'), description='{param}'.format(param=ip), debug_module=True) searcher = self.__getShodanByAPI__(shodan_api) if searcher: host = searcher.host(ip) interesting_data = config['scan_interesting_data_keys'] for posibe_data in interesting_data: try: if host[posibe_data]: if isinstance(host[posibe_data], dict): if posibe_data in 'data': res[posibe_data] = {} res[posibe_data]['port'] = host[ posibe_data]['port'] res[posibe_data]['data'] = host[ posibe_data]['data'] else: res[posibe_data] = host[posibe_data][0] else: res[posibe_data] = host[posibe_data] elif host.get(posibe_data): res[posibe_data] = host.get(posibe_data) except: try: if host.get(posibe_data): res[posibe_data] = host.get(posibe_data) except: pass except Exception as e: Logger.printMessage( message='Warning: {0}... Retrying in 0,5 seconds...'.format(e), is_warn=True, debug_module=True) time.sleep(0.4) return self.search_host(ip, shodan_api, count_loop_try=count_loop_try + 1) return res
def set_pdf_field_value(self, pdf_file, field, fieldValue): try: trailer = PdfReader(pdf_file) if trailer.Info is None: trailer.Info = pdfrw.objects.pdfdict.PdfDict() setDataQuery = 'trailer.Info.{f} = "{v}"'.format(f=field.replace( '/', ''), v=fieldValue) exec(setDataQuery) new_pdf = os.path.split(pdf_file)[1] new_file = os.path.join(output_dir, new_pdf) PdfWriter(new_file, trailer=trailer).write() return new_file except: Logger.printMessage(pdf_file, is_error=True) return pdf_file
def convertToExe(self, stub_name): """ Convert's given Python file path in String into a new one with the same name and .exe as extension Compile's with pyinstaller and could be change it's params in config.json Arguments --------- stub_name : str File path to convert to exe """ Logger.printMessage( message='{methodName}'.format(methodName='convertToExe'), description='{stub_name}'.format(stub_name=stub_name), debug_module=True) # Convert py to exe with pyinstaller import os os.system(config['pyinstaller'].format( path=os.path.dirname(stub_name)) + " " + stub_name) filename = '{file}.exe'.format( file=stub_name.split('.')[0].split('\\')[-1]) file_to_move = os.path.abspath( os.path.join('dist', '{file}'.format(file=filename))) new_file = os.path.abspath( os.path.join(os.path.dirname(stub_name), filename)) if os.path.isfile(file_to_move) and not os.path.isfile(new_file): os.rename(file_to_move, new_file) new_spec_file = '{name}.spec'.format(name=new_file.split('.')[0]) if os.path.isfile(new_spec_file): os.remove(new_spec_file) build_dir = os.path.abspath( os.path.join('build', '{file}'.format(file=filename.split('.')[0]))) if os.path.isdir(build_dir): shutil.rmtree(build_dir) if os.path.isfile(file_to_move): os.remove(file_to_move) spec_file = os.path.abspath( '{file}.spec'.format(file=filename.split('.')[0])) if os.path.isfile(spec_file): os.remove(spec_file)
def getCVEsFromHost(self, ip): Logger.printMessage( message='{methodName}'.format(methodName='getConnectedDevices'), description='{param}'.format(param=ip), debug_module=True) nm = nmap.PortScanner() results = nm.scan(hosts=ip, arguments='-Pn --script vuln') protocols = ('tcp', 'udp') discard_vuln_by_description = ( 'ERROR:', 'Couldn\'t', '\n /jmx-console/: Authentication was not required\n') res = {} for p in protocols: if 'scan' in results and ip in results['scan']: if p in results['scan'][ip]: for port in results['scan'][ip][p]: res[port] = [] if 'script' in results['scan'][ip][p][port]: for vuln in results['scan'][ip][p][port]['script']: discard = False for dis in discard_vuln_by_description: if results['scan'][ip][p][port]['script'][ vuln].startswith(dis): discard = True if not discard: if not results['scan'][ip][p][port][ 'script'][vuln] == '\n': if 'CVE:' in results['scan'][ip][p][ port]['script'][vuln]: res[port].append({ vuln: results['scan'][ip][p][port] ['script'][vuln].split( 'CVE:')[1].split( '\n')[0].split(' ')[0] }) else: res[port].append({ vuln: results['scan'][ip][p][port] ['script'][vuln] }) if len(res[port]) == 0: del res[port] return res
def crackZip(self, zipPathName, unzipper=None, alphabet='lalpha', password_length=4, password_pattern=None, log=False): #max_length_posibilities = int(config['max_for_chunk']) if not unzipper: unzipper = ht.getModule('ht_unzip') if log: Logger.setDebugCore(True) for text in [ Utils.getCombinationPosibilitiesByPattern( try_pattern=password_pattern) if password_pattern else Utils.getDict(length=password_length, alphabet=alphabet) ]: # if len(texts) > max_length_posibilities: # texts_list = numpy.array_split(texts, max_length_posibilities) # else: # texts_list = [texts] # for index_t_list, t_list in enumerate(texts_list): # if len(t_list) > max_length_posibilities: # Logger.printMessage(message='crackZip', description='Chunk {n} - {word}'.format(n=index_t_list, word=t_list[1])) # for text in t_list: if os.path.isfile(zipPathName): password = unzipper.extractFilePassword( zipPathName, text) #, posible_combinations=len(texts)) else: Logger.printMessage( message='crackZip', description='File doesnt exists {a}'.format(a=zipPathName), is_error=True) break if password: Logger.printMessage( message='crackZip', description='{msg_password_is} {a}'.format( msg_password_is=config['msg_password_is'], a=password), debug_module=True) if log: Logger.setDebugCore(False) return password Logger.setDebugCore(False) return None
def get_image_exif(self, filename): Logger.printMessage( message='{methodName}'.format(methodName='get_image_exif'), description=filename, debug_module=True) try: img_file = Image.open(filename) img_file.verify() info = img_file._getexif() return info except Exception as e: Logger.printMessage( message='{methodName}'.format(methodName='exception'), description=e, debug_module=True) return e return -1
def __handleLink__(self, link, depth=100, webForms={}, proxies=None, linksVisited=[], totalProfundity=0): Logger.printMessage( message='{methodName}'.format(methodName='__handleLink__'), description='{param}'.format(param=link), debug_module=True) totalProfundity += 1 if ('href' in dict(link.attrs) and "http" in link['href']): try: href = link["href"] if href in linksVisited: return if proxies: urlLink = urllib3.urlopen(href, proxies=proxies) else: urlLink = urllib3.urlopen(href) linksVisited.append(link['href']) #Extract info about the link, before to get links in this page. if totalProfundity <= depth: linkSite = BeautifulSoup(urlLink, "lxml") depthLinks = linkSite.find_all("a") webForms[link['href']] = self.__storeWebSiteForms__( url=link['href'], proxies=proxies, forms=webForms) for sublink in depthLinks: #processLink = multiprocessing.Process(target=self.__handleLink__, args=[sublink]) #processLink.daemon = True #processLink.start() self.__handleLink__(link=sublink, depth=depth, webForms=webForms, proxies=proxies, linksVisited=linksVisited, totalProfundity=totalProfundity) else: totalProfundity -= 1 return except: pass
def isBadFile(self, filename, virustotal_api=None): try: if not virustotal_api: virustotal_api = ht.Config.config['API']['virustotal'] Logger.printMessage(message="isBadFile", description=filename, debug_module=True) self.vtotal = Virustotal(virustotal_api) response = self.vtotal.file_scan(filename) if response["status_code"] == 200: scan_id = str(response["json_resp"]["scan_id"]) time.sleep(2) resp = self.isBadFileHash(scan_id, virustotal_api) return resp except Exception as e: Logger.printMessage(message="isBadFile", description=str(e), is_error=True) return str(e)
def getRandomKeypair(self, length=8): Logger.printMessage( message='{methodName}'.format(methodName='getRandomKeypair'), debug_module=True) prime_a = '' prime_b = '' while prime_a == prime_b: while prime_a == '' or prime_a == prime_b: prime_a = Utils.getRandomPrimeByLength(length) while prime_b == '' or prime_a == prime_b: prime_b = Utils.getRandomPrimeByLength(length) if prime_a > prime_b: temp = prime_b prime_b = prime_a prime_a = temp Logger.printMessage(message='getRandomKeypair', description=(prime_a, prime_b), debug_module=True) return (prime_a, prime_b)
def getIPListfromServices(self, serviceName, shodan_api=None): Logger.printMessage( message='{methodName}'.format(methodName='getIPListfromServices'), description='{param}'.format(param=serviceName), debug_module=True) searcher = self.__getShodanByAPI__(shodan_api) if searcher: try: result = searcher.search(serviceName) dict_obj = [] for res in result['matches']: dict_obj.append( res['ip_str'].encode('utf-8').decode('utf-8')) return dict_obj except: return [] else: return []
def getConnectedDevices(self, ip): Logger.printMessage( message='{methodName}'.format(methodName='getConnectedDevices'), description='{param}'.format(param=ip), debug_module=True) nm = nmap.PortScanner() results = nm.scan(hosts=ip, arguments='-n -sP -PE -PA21,23,80,3389') if 'scan' in results: hosts = {} for host in results['scan']: if results['scan'][host]['status']['state'] == 'up': mac_address = None if 'mac' in results['scan'][host]['addresses']: mac_address = results['scan'][host]['addresses']['mac'] hosts[host] = '' if not mac_address else results['scan'][ host]['vendor'][mac_address] return hosts return []
def encrypt(self, private_key, plaintext): try: Logger.printMessage( message='{methodName}'.format(methodName='encrypt'), description='{private_key} - {msg}'.format( private_key=private_key, msg=plaintext[0:10]), debug_module=True) #Unpack the key into it's components key, n = private_key ba64 = base64.b64encode(plaintext) ashex = Utils.asciiToHex(ba64) hexba64 = Utils.hexToBase64(ashex) ba64un = Utils.joinBase64(hexba64) decasc = Utils.decimalToAscii(ba64un) mensaje = Utils.textToAscii(decasc) Logger.printMessage( message='{methodName}'.format(methodName='encrypt'), description='{msg} - Length: {l}'.format(msg=mensaje[0:10], l=len(mensaje)), debug_module=True) mensaje1 = [(ord(chr(char))**key) % n for char in mensaje] mensajeHex = Utils.asciiToHex(mensaje1) mensajeBase64 = Utils.hexToBase64(mensajeHex) mensajeFinalBase64 = Utils.joinBase64(mensajeBase64) return mensajeFinalBase64.decode("utf-8") except Exception as e: Logger.printMessage( message='{methodName}'.format(methodName='encrypt'), description='{msg}'.format(msg=e)) return
def decrypt(self, public_key, ciphertext): Logger.printMessage( message='{methodName}'.format(methodName='decrypt'), description='{public_key}'.format(public_key=public_key), debug_module=True) #Unpack the key into its components key, n = public_key menRec = Utils.asciiToBase64(ciphertext.encode('utf-8')) menHex = Utils.base64ToHex(menRec) menDec = Utils.hexToDecimal(menHex) Logger.printMessage( message='{methodName}'.format(methodName='decrypt'), description='{msg}'.format(msg=menDec[0:10]), debug_module=True) menDesc = [((char**key) % n) for char in menDec] menAscii = Utils.decimalToAscii(menDesc) decasc = Utils.asciiToBase64(''.join(menAscii).encode()) hexba64 = Utils.base64ToHex(decasc) ashex = Utils.hexToDecimal(hexba64) deasc = Utils.decimalToAscii(ashex) ba64 = base64.b64decode(deasc.encode()) return ba64
def getDevicePorts(self, ip, tcp=True, udp=False): Logger.printMessage( message='{methodName}'.format(methodName='getDevicePorts'), description='{param} - TCP {tcp} - UDP {udp}'.format(param=ip, tcp=tcp, udp=udp), debug_module=True) nm = nmap.PortScanner() results = nm.scan(ip) try: if tcp and not udp: return Utils.getValidDictNoEmptyKeys( results["scan"][ip]["tcp"]) if udp and not tcp: return Utils.getValidDictNoEmptyKeys( results["scan"][ip]["udp"]) if tcp and udp: return Utils.getValidDictNoEmptyKeys( [results["scan"][ip]["tcp"], results["scan"][ip]["udp"]]) return Utils.getValidDictNoEmptyKeys(results["scan"][ip]["tcp"]) except: return []
def hasDevicePortOpened(self, ip, port): Logger.printMessage( message='{methodName}'.format(methodName='hasDevicePortOpened'), description='{param}:{param2}'.format(param=ip, param2=port), debug_module=True) nm = nmap.PortScanner() results = nm.scan(ip) exists = False try: for host in results.all_hosts(): if exists: break if not exists: exists = results[host].has_tcp(port) if not exists: exists = results[host].has_udp(port) except: Logger.printMessage(message="isBadFile", description=results, is_error=True) raise return exists
def searchFromConfig(self, search='', keyword='', shodan_api=None): if search != '' and keyword != '' and config[search]: Logger.printMessage(message='{methodName}'.format( methodName='searchFromConfig', description=search), debug_module=True) url = ("https://api.shodan.io/{search}&key={api}".format( search=config[search], api=shodan_api)).format(ip=keyword) # IP because config {ip} request = requests.get(url) txt = request.text return json.loads(txt) else: Logger.printMessage(message='{methodName}'.format( methodName='searchFromConfig', description='suggestions_cause_bad_search'), debug_module=True) sugg_conf = [] res = {} for configuration in config: if configuration.startswith('shodan_'): sugg_conf.append(configuration) res['search_options'] = sugg_conf return res
def get_pdf_exif(self, pdf_file): Logger.printMessage( message='{methodName}'.format(methodName='get_pdf_exif'), description=pdf_file, debug_module=True) info = '' data = {} try: with open(pdf_file, 'rb') as f: pdf = PdfFileReader(f) info = pdf.getDocumentInfo() number_of_pages = pdf.getNumPages() if info: for a in info: data[a] = info[a] return data except Exception as e: Logger.printMessage( message='{methodName}'.format(methodName='exception'), description=e, debug_module=True) return e return -1
def isBadFileHash(self, fileHash, virustotal_api=None, session_id=None): try: if not virustotal_api: virustotal_api = ht.Config.getAPIKey('virustotal_api', session_id) self.vtotal = Virustotal(virustotal_api) resp = self.vtotal.file_report([fileHash]) if resp["status_code"] in (200, 204): if resp["status_code"] == 204: Logger.printMessage( message="isBadFileHash", description="Testing - {hash} - Waiting 2 seconds...". format(hash=fileHash), debug_module=True) time.sleep(2) return self.isBadFileHash(fileHash, virustotal_api) while resp["json_resp"]["response_code"] == -2: Logger.printMessage( message="isBadFileHash", description="Testing - {hash} - Waiting 2 seconds...". format(hash=fileHash), debug_module=True) time.sleep(2) return self.isBadFileHash(fileHash, virustotal_api) no_detected_list = [] detected_list = [] detected_types = [] for antivirus in resp["json_resp"]["scans"]: if resp["json_resp"]["scans"][antivirus]["detected"]: detected_list.append( (antivirus, resp["json_resp"]["scans"][antivirus]["version"])) if not resp["json_resp"]["scans"][antivirus][ "result"] in detected_types: detected_types.append(resp["json_resp"]["scans"] [antivirus]["result"]) else: no_detected_list.append( (antivirus, resp["json_resp"]["scans"][antivirus]["version"])) if detected_list: data = {} data["detected_list"] = detected_list data["detected_types"] = detected_types data["no_detected_list"] = no_detected_list return json.dumps({"Detected": data}, indent=4, sort_keys=True) return json.dumps({"No detected": no_detected_list}, indent=4, sort_keys=True) return resp except Exception as e: Logger.printMessage(message="isBadFileHash", description=str(e), is_error=True) return str(e)
def generate_keypair(self, prime_a, prime_b): if not (Utils.isPrime(int(prime_a)) and Utils.isPrime(int(prime_b))): Logger.printMessage( message='{methodName}'.format(methodName='generate_keypair'), description=config['bad_identical_prime'], debug_module=True, is_error=True) return config['bad_identical_prime'] elif prime_a == prime_b: Logger.printMessage( message='{methodName}'.format(methodName='generate_keypair'), description=config['p_q_equal_error'], debug_module=True, is_error=True) return config['p_q_equal_error'] else: #n = pq n = prime_a * prime_b #Phi is the totient of n phi = (prime_a - 1) * (prime_b - 1) #Choose an integer e such that e and phi(n) are coprime e = random.randrange(1, phi) #Use Euclid's Algorithm to verify that e and phi(n) are comprime g = Utils.euclides(e, phi) while g != 1: e = random.randrange(1, phi) g = Utils.euclides(e, phi) #Use Extended Euclid's Algorithm to generate the private key d = Utils.multiplicativeInverse(e, phi) #Return public and private keypair #Public key is (e, n) and private key is (d, n) return ((e, n), (d, n))