Skip to content

Commit

Permalink
removing dependencies using ctypes (win32 and colorama) + some code r…
Browse files Browse the repository at this point in the history
…eview
  • Loading branch information
AlessandroZ committed Apr 18, 2017
1 parent 6ea2322 commit e403156
Show file tree
Hide file tree
Showing 36 changed files with 604 additions and 667 deletions.
103 changes: 103 additions & 0 deletions Windows/lazagne/config/WinStructure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from ctypes.wintypes import *
from ctypes import *

LPBYTE = POINTER(BYTE)
LPTSTR = LPSTR
LPCTSTR = LPSTR

# ------------------ Constants ------------------

# Credential Manager
CRYPTPROTECT_UI_FORBIDDEN = 0x01
CRED_TYPE_GENERIC = 0x1
CRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 0x4

# Regedit
HKEY_CURRENT_USER = -2147483647
KEY_READ = 131097
KEY_ENUMERATE_SUB_KEYS = 8
KEY_QUERY_VALUE = 1

# custom key to read registry (not from msdn)
ACCESS_READ = KEY_READ | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE

# ------------------ Structures ------------------

class CREDENTIAL_ATTRIBUTE(Structure):
_fields_ = [
('Keyword', LPSTR),
('Flags', DWORD),
('ValueSize', DWORD),
('Value', LPBYTE)
]
PCREDENTIAL_ATTRIBUTE = POINTER(CREDENTIAL_ATTRIBUTE)

class CREDENTIAL(Structure):
_fields_ = [
('Flags', DWORD),
('Type', DWORD),
('TargetName', LPSTR),
('Comment', LPSTR),
('LastWritten', FILETIME),
('CredentialBlobSize', DWORD),
# ('CredentialBlob', POINTER(BYTE)),
('CredentialBlob', POINTER(c_char)),
('Persist', DWORD),
('AttributeCount', DWORD),
('Attributes', PCREDENTIAL_ATTRIBUTE),
('TargetAlias', LPSTR),
('UserName', LPSTR)
]
PCREDENTIAL = POINTER(CREDENTIAL)

class DATA_BLOB(Structure):
_fields_ = [
('cbData', DWORD),
('pbData', POINTER(c_char))
]

# ------------------ Functions ------------------

CredEnumerate = windll.advapi32.CredEnumerateA
CredEnumerate.restype = BOOL
CredEnumerate.argtypes = [LPCTSTR, DWORD, POINTER(DWORD), POINTER(POINTER(PCREDENTIAL))]

CredFree = windll.advapi32.CredFree
CredFree.restype = c_void_p
CredFree.argtypes = [c_void_p]

memcpy = cdll.msvcrt.memcpy
LocalFree = windll.kernel32.LocalFree
CryptUnprotectData = windll.crypt32.CryptUnprotectData


# ------------------ Custom functions ------------------

def getData(blobOut):
cbData = int(blobOut.cbData)
pbData = blobOut.pbData
buffer = c_buffer(cbData)

memcpy(buffer, pbData, cbData)
LocalFree(pbData);
return buffer.raw

def Win32CryptUnprotectData(cipherText, entropy=None):
bufferIn = c_buffer(str(cipherText), len(cipherText))
blobIn = DATA_BLOB(len(cipherText), bufferIn)
blobOut = DATA_BLOB()

if entropy:
bufferEntropy = c_buffer(entropy, len(entropy))
blobEntropy = DATA_BLOB(len(entropy), bufferEntropy)

if CryptUnprotectData(byref(blobIn), None, byref(blobEntropy), None, None, 0, byref(blobOut)):
return getData(blobOut)
else:
return False

else:
if CryptUnprotectData(byref(blobIn), None, None, None, None, 0, byref(blobOut)):
return getData(blobOut)
else:
return False
43 changes: 34 additions & 9 deletions Windows/lazagne/config/header.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,55 @@
import logging
from colorama import init, Fore, Back, Style
import ctypes

STD_OUTPUT_HANDLE = -11
std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)

def setColor(color='white', intensity=False):
c = None
if color == 'white':
c = 0x07
elif color == 'red':
c = 0x04
elif color == 'green':
c = 0x02
elif color == 'cyan':
c = 0x03

if intensity:
c = c | 0x08

ctypes.windll.kernel32.SetConsoleTextAttribute(std_out_handle, c)

class Header():
def __init__(self):
init() # for colorama
# init() # for colorama
self.BRIGHT = '\x1b[31m'
self.WHITE = '\x1b[37m'
self.RESET_COLOR = '\x1b[0m'

def first_title(self):
init()
print Style.BRIGHT + Fore.WHITE
setColor(color='white', intensity=True)
print '|====================================================================|'
print '| |'
print '| The LaZagne Project |'
print '| |'
print '| ! BANG BANG ! |'
print '| |'
print '|====================================================================|'
print Style.RESET_ALL
setColor()

# info option for the logging
def title(self, title):
print Style.BRIGHT + Fore.WHITE + '------------------- ' + title + ' passwords -----------------\n' + Style.RESET_ALL
setColor(color='white', intensity=True)
print '------------------- ' + title + ' passwords -----------------\n'
setColor()

# Subtitle
def title1(self, title1):
print Style.BRIGHT + Fore.WHITE + '[*] ' + title1 + '\n' + Style.RESET_ALL
# def title1(self, title1):
# print self.BRIGHT + self.WHITE + '[*] ' + title1 + '\n' + self.RESET_COLOR

# debug option for the logging
def title_info(self, title):
logging.info(Style.BRIGHT + Fore.WHITE + '------------------- ' + title + ' passwords -----------------\n' + Style.RESET_ALL)
setColor(color='white', intensity=True)
logging.info('------------------- ' + title + ' passwords -----------------\n')
setColor()
6 changes: 2 additions & 4 deletions Windows/lazagne/config/manageModules.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from lazagne.softwares.browsers.ie import IE
# windows
from lazagne.softwares.windows.system_hash import Hashes
from lazagne.softwares.windows.network import Network
from lazagne.softwares.windows.dot_net import Dot_net
from lazagne.softwares.windows.credman import Credman
# sysadmin
from lazagne.softwares.sysadmin.filezilla import Filezilla
from lazagne.softwares.sysadmin.cyberduck import Cyberduck
Expand Down Expand Up @@ -68,7 +67,6 @@ def get_modules():
moduleNames = [
ApacheDirectoryStudio(),
Dbvisualizer(),
Dot_net(),
Chrome(),
CoreFTP(),
Cyberduck(),
Expand All @@ -84,7 +82,7 @@ def get_modules():
MavenRepositories(),
MemoryDump(),
Mozilla(),
Network(),
Credman(),
OpenSSHForWindows(),
Opera(),
Outlook(),
Expand Down
2 changes: 1 addition & 1 deletion Windows/lazagne/config/write_output.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# -*- coding: utf-8 -*-from constant import constantfrom time import gmtime, strftimeimport os, getpass, socketimport loggingimport jsonimport tempfilefrom lazagne.config.header import Headerfrom colorama import init, Fore, Back, Styleinit() # init the colorama function# --------------------------- Functions used to write ---------------------------def write_header(): time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) header = '''|====================================================================|\r\n| |\r\n| Credentials discovery |\r\n| |\r\n| ! BANG BANG ! |\r\n| |\r\n|====================================================================|\r\n\r\n- Date: ''' + time + '''\n\r- Username: ''' + getpass.getuser() + ''' \r\n- Hostname: ''' + socket.gethostname() + ''' \r\n\r\n------------------------------ Results ------------------------------\r\n\r\n''' open(constant.folder_name + os.sep + constant.file_name_results + '.txt',"a+b").write(header)def write_footer(): footer = '\n[+] %s passwords have been found.\r\n\r\n' % str(constant.nbPasswordFound) open(constant.folder_name + os.sep + constant.file_name_results + '.txt',"a+b").write(footer) def write_credentials(pwdFound, category, filePath): tmp = "############ %s passwords ############\r\n\r\n" % category for pwd in pwdFound: for p in pwd.keys(): tmp = str(tmp) + str(p) + ": " + str(pwd[p].encode('utf-8')) + "\r\n" tmp = str(tmp) + "\r\n" open(filePath,"a+b").write(tmp) def checks_write(values, category): if values: if "Passwords" not in constant.finalResults: constant.finalResults["Passwords"] = [] constant.finalResults["Passwords"].append([{"Category": category}, values])# --------------------------- End of functions used to write ---------------------------# --------------------------- Output functions ---------------------------def print_footer(): footer = '\n[+] %s passwords have been found.\n' % str(constant.nbPasswordFound) if logging.getLogger().isEnabledFor(logging.INFO) == False: footer += 'For more information launch it again with the -v option\n' print footer# print output if passwords have been founddef print_output(software_name, pwdFound, title1 = False): if pwdFound: # if the debug logging level is not apply => print the title if logging.getLogger().isEnabledFor(logging.INFO) == False: if not title1: Header().title(software_name) toWrite = [] password_category = False for pwd in pwdFound: # detect which kinds of password has been found lower_list = [s.lower() for s in pwd.keys()] password = [s for s in lower_list if "password" in s] if password: password_category = password else: key = [s for s in lower_list if "key" in s] # for the wifi if key: password_category = key else: hash = [s for s in lower_list if "hash" in s] if hash: password_category = hash # No password found if not password_category: print_debug("FAILED", "Password not found !!!") else: print_debug("OK", '%s found !!!' % password_category[0].title()) toWrite.append(pwd) # Store all passwords found on a table => for dictionary attack if master password set constant.nbPasswordFound += 1 try: constant.passwordFound.append(pwd[password_category[0]]) except: pass for p in pwd.keys(): try: print '%s: %s' % (p, pwd[p]) except Exception,e: print_debug('DEBUG', '{0}'.format(e)) print '%s: %s' % (p.encode('utf-8'), pwd[p].encode('utf-8')) print # write credentials into a text file checks_write(toWrite, software_name) else: logging.info("[!] No passwords found\n")def print_debug(error_level, message): # print when password is found if error_level == 'OK': print Fore.GREEN + message + Style.RESET_ALL # print when password is not found elif error_level == 'FAILED': print Style.BRIGHT + Fore.RED + message + Style.RESET_ALL # print messages depending of their criticism elif error_level == 'CRITICAL': logging.critical(Style.BRIGHT + Fore.RED + '[CRITICAL] %s\n' % message + Style.RESET_ALL) elif error_level == 'ERROR': logging.error(Style.BRIGHT + Fore.RED + '[ERROR] %s\n' % message + Style.RESET_ALL) elif error_level == 'WARNING': logging.warning(Fore.CYAN + '[WARNING] %s\n' % message + Style.RESET_ALL) elif error_level == 'DEBUG': logging.debug('[DEBUG] %s\n' % message) elif error_level == 'INFO': logging.info('%s\n' % message) else: logging.info('[%s] %s' % (error_level, message))# --------------------------- End of output functions ---------------------------def parseJsonResultToBuffer(jsonString, color=False): green = '' reset = '' title = '' if color: green = Fore.GREEN title = Style.BRIGHT + Fore.WHITE reset = Style.RESET_ALL buffer = '' try: for json in jsonString: if json: buffer += '\r\n\r\n{title_color}########## User: {username} ##########{reset_color}\r\n\r\n'.format(title_color=title, username=json['User'], reset_color=reset) if 'Passwords' not in json: buffer += 'No passwords found for this user !' else: for all_passwords in json['Passwords']: buffer += '{title_color}------------------- {password_category} -----------------{reset_color}\r\n'.format(title_color=title, password_category=all_passwords[0]['Category'], reset_color=reset) for password_by_category in all_passwords[1]: buffer += '\r\n{green_color}Password found !!!{reset_color}\r\n'.format(green_color=green, reset_color=reset) constant.nbPasswordFound += 1 for dic in password_by_category.keys(): try: buffer += '%s: %s\r\n' % (dic, password_by_category[dic].encode('utf-8')) except: buffer += '%s: %s\r\n' % (dic, password_by_category[dic].encode(encoding='utf-8',errors='replace')) buffer += '\r\n' except Exception as e: print_debug('ERROR', 'Error parsing the json results: %s' % e) print_debug('ERROR', 'json content: %s' % jsonString) return buffer
# -*- coding: utf-8 -*-from constant import constantfrom time import gmtime, strftimeimport os, getpass, socketimport loggingimport jsonimport tempfilefrom lazagne.config.header import Header, setColor# --------------------------- Functions used to write ---------------------------def write_header(): time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) header = '''|====================================================================|\r\n| |\r\n| Credentials discovery |\r\n| |\r\n| ! BANG BANG ! |\r\n| |\r\n|====================================================================|\r\n\r\n- Date: ''' + time + '''\n\r- Username: ''' + getpass.getuser() + ''' \r\n- Hostname: ''' + socket.gethostname() + ''' \r\n\r\n------------------------------ Results ------------------------------\r\n\r\n''' open(constant.folder_name + os.sep + constant.file_name_results + '.txt',"a+b").write(header)def write_footer(): footer = '\n[+] %s passwords have been found.\r\n\r\n' % str(constant.nbPasswordFound) open(constant.folder_name + os.sep + constant.file_name_results + '.txt',"a+b").write(footer) def write_credentials(pwdFound, category, filePath): tmp = "############ %s passwords ############\r\n\r\n" % category for pwd in pwdFound: for p in pwd.keys(): tmp = str(tmp) + str(p) + ": " + str(pwd[p].encode('utf-8')) + "\r\n" tmp = str(tmp) + "\r\n" open(filePath,"a+b").write(tmp) def checks_write(values, category): if values: if "Passwords" not in constant.finalResults: constant.finalResults["Passwords"] = [] constant.finalResults["Passwords"].append([{"Category": category}, values])# --------------------------- End of functions used to write ---------------------------# --------------------------- Output functions ---------------------------def print_footer(): footer = '\n[+] %s passwords have been found.\n' % str(constant.nbPasswordFound) if logging.getLogger().isEnabledFor(logging.INFO) == False: footer += 'For more information launch it again with the -v option\n' print footer# print output if passwords have been founddef print_output(software_name, pwdFound, title1 = False): if pwdFound: # if the debug logging level is not apply => print the title if logging.getLogger().isEnabledFor(logging.INFO) == False: if not title1: Header().title(software_name) toWrite = [] password_category = False for pwd in pwdFound: # detect which kinds of password has been found lower_list = [s.lower() for s in pwd.keys()] password = [s for s in lower_list if "password" in s] if password: password_category = password else: key = [s for s in lower_list if "key" in s] # for the wifi if key: password_category = key else: hash = [s for s in lower_list if "hash" in s] if hash: password_category = hash # No password found if not password_category: print_debug("FAILED", "Password not found !!!") else: print_debug("OK", '%s found !!!' % password_category[0].title()) toWrite.append(pwd) # Store all passwords found on a table => for dictionary attack if master password set constant.nbPasswordFound += 1 try: constant.passwordFound.append(pwd[password_category[0]]) except: pass for p in pwd.keys(): try: print '%s: %s' % (p, pwd[p]) except Exception,e: print_debug('DEBUG', '{0}'.format(e)) print '%s: %s' % (p.encode('utf-8'), pwd[p].encode('utf-8')) print # write credentials into a text file checks_write(toWrite, software_name) else: logging.info("[!] No passwords found\n")def print_debug(error_level, message): GREEN = '\x1b[32m' RED = '\x1b[31m' RESET_COLOR = '\x1b[0m' BRIGHT = '\x1b[1m' CYAN = '\x1b[36m' # print when password is found if error_level == 'OK': setColor('green') print message setColor() # print when password is not found elif error_level == 'FAILED': setColor('red', True) print message setColor() # print messages depending of their criticism elif error_level == 'CRITICAL': setColor('red', True) logging.critical('[CRITICAL] %s\n' % message) setColor() elif error_level == 'ERROR': setColor('red', True) logging.error('[ERROR] %s\n' % message) setColor() elif error_level == 'WARNING': setColor('cyan') logging.warning('[WARNING] %s\n' % message) setColor() elif error_level == 'DEBUG': logging.debug('[DEBUG] %s\n' % message) elif error_level == 'INFO': logging.info('%s\n' % message) else: logging.info('[%s] %s' % (error_level, message))# --------------------------- End of output functions ---------------------------def parseJsonResultToBuffer(jsonString, color=False): green = '' reset = '' title = '' # if color: # green = Fore.GREEN # title = BRIGHT + Fore.WHITE # reset = RESET_COLOR buffer = '' try: for json in jsonString: if json: buffer += '\r\n\r\n{title_color}########## User: {username} ##########{reset_color}\r\n\r\n'.format(title_color=title, username=json['User'], reset_color=reset) if 'Passwords' not in json: buffer += 'No passwords found for this user !' else: for all_passwords in json['Passwords']: buffer += '{title_color}------------------- {password_category} -----------------{reset_color}\r\n'.format(title_color=title, password_category=all_passwords[0]['Category'], reset_color=reset) for password_by_category in all_passwords[1]: buffer += '\r\n{green_color}Password found !!!{reset_color}\r\n'.format(green_color=green, reset_color=reset) constant.nbPasswordFound += 1 for dic in password_by_category.keys(): try: buffer += '%s: %s\r\n' % (dic, password_by_category[dic].encode('utf-8')) except: buffer += '%s: %s\r\n' % (dic, password_by_category[dic].encode(encoding='utf-8',errors='replace')) buffer += '\r\n' except Exception as e: print_debug('ERROR', 'Error parsing the json results: %s' % e) print_debug('ERROR', 'json content: %s' % jsonString) return buffer
Expand Down
Loading

0 comments on commit e403156

Please sign in to comment.