Skip to content

Commit

Permalink
cf changelog version 1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Alessandro ZANNI committed Jul 2, 2016
1 parent 290cfab commit 658a1a5
Show file tree
Hide file tree
Showing 122 changed files with 989 additions and 104 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
LaZagne 1.3 (02/07/2016)
- Only Windows
See "User impersonnation" in README for more information
* User impersonation (high privileges needed)
* Stealing user process token (when other user processes are running on the system)
* All credentials can be retrieved (Chrome, Firefox, etc.)
* Browsing file system (ex: C:\Users\<user>\...)
* Only software's passwords which do not use Windows API to encrypt it, can be retrieved (Firefox, Jitsi, Pidgin, etc.).
* Json output has been implemented (txt output is still present with the options -oN)
* Lazagne all -oJ => Json output
* Standalone lighter (from 18 Mo to 6 Mo) => Thanks to the new version of Pyinstaller
* Fix some bugs

LaZagne 1.1 (22/10/2015)
- Only Windows
* New category: games (Thanks to David Lodge)
Expand Down
Empty file modified LICENSE
100644 → 100755
Empty file.
46 changes: 40 additions & 6 deletions Linux/src/LaZagne.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
import argparse
import time, sys, os
import logging
import json
import getpass
from softwares.browsers.mozilla import Mozilla

# Configuration
from config.header import Header
from config.write_output import write_header, write_footer, print_footer
from config.write_output import write_header, write_footer, print_footer, parseJsonResultToBuffer
from config.constant import *
from config.manageModules import get_categories, get_modules

Expand All @@ -36,12 +38,27 @@
modules['mails']['thunderbird'] = Mozilla(True) # For thunderbird (firefox and thunderbird use the same class)

def output():
if args['write'] == True:
if args['write_normal']:
constant.output = 'txt'

if args['write_json']:
constant.output = 'json'

if args['write_all']:
constant.output = 'all'

if constant.output:
if not os.path.exists(constant.folder_name):
os.makedirs(constant.folder_name)
# constant.file_name_results = 'credentials' # let the choice of the name to the user

if constant.output != 'json':
write_header()
del args['write']

# Remove all unecessary variables
del args['write_normal']
del args['write_json']
del args['write_all']

def verbosity():
# Write on the console + debug file
Expand Down Expand Up @@ -136,8 +153,10 @@ def error(self, message):

# Output
PWrite = argparse.ArgumentParser(add_help=False,formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
PWrite._optionals.title = 'output'
PWrite.add_argument('-w', dest='write', action= 'store_true', help = 'write a text file on the current directory')
PWrite._optionals.title = 'Output'
PWrite.add_argument('-oN', dest='write_normal', action='store_true', help = 'output file in a readable format')
PWrite.add_argument('-oJ', dest='write_json', action='store_true', help = 'output file in a json format')
PWrite.add_argument('-oA', dest='write_all', action='store_true', help = 'output file in all format')

# ------------------------------------------- Add options and suboptions to all modules -------------------------------------------
all_subparser = []
Expand Down Expand Up @@ -188,11 +207,26 @@ def error(self, message):
start_time = time.time()
output()
verbosity()

user = getpass.getuser()
constant.finalResults = {}
constant.finalResults['User'] = user

print '\n\n########## User: %s ##########\n' % user
arguments.func()

if constant.output == 'json' or constant.output == 'all':
# Human readable Json format
prettyJson = json.dumps(constant.finalResults, sort_keys=True, indent=4, separators=(',', ': '))
with open(constant.folder_name + os.sep + constant.file_name_results + '.json', 'w+') as f:
json.dump(prettyJson, f)

# Print the number of passwords found
if constant.output == 'txt':
if constant.output == 'txt' or constant.output == 'all':
with open(constant.folder_name + os.sep + constant.file_name_results + '.txt', 'a+b') as f:
f.write(parseJsonResultToBuffer(constant.finalResults).encode('utf-8'))
write_footer()

print_footer()

elapsed_time = time.time() - start_time
Expand Down
Empty file modified Linux/src/config/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/config/color.py
100644 → 100755
Empty file.
5 changes: 4 additions & 1 deletion Linux/src/config/constant.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

class constant():
folder_name = 'results'
file_name_results = 'credentials' # the extention is added depending on the user output choice
MAX_HELP_POSITION = 27
CURRENT_VERSION = '1.0'
CURRENT_VERSION = '1.1'
output = None
file_logger = None
verbose = False
Expand All @@ -20,3 +21,5 @@ class constant():
# total password found
nbPasswordFound = 0
passwordFound = []

finalResults = {}
Empty file modified Linux/src/config/dico.py
100644 → 100755
Empty file.
Empty file modified Linux/src/config/header.py
100644 → 100755
Empty file.
Empty file modified Linux/src/config/manageModules.py
100644 → 100755
Empty file.
Empty file modified Linux/src/config/moduleInfo.py
100644 → 100755
Empty file.
45 changes: 38 additions & 7 deletions Linux/src/config/write_output.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from config.color import bcolors
from config.constant import constant
import logging
import json

# --------------------------- Functions used to write ---------------------------

Expand Down Expand Up @@ -39,13 +40,17 @@ def write_credentials(pwdFound, category):
open(constant.folder_name + os.sep + 'credentials.txt',"a+b").write(tmp)

def checks_write(values, category):
# if values:
# if constant.output == 'txt':
# try:
# write_credentials(values, category)
# logging.info('[+] Credentials stored successfully on the file: %s\\credentials.txt\n' % constant.folder_name)
# except:
# logging.info('Couldn\'t write the results file\n')
if values:
if constant.output == 'txt':
try:
write_credentials(values, category)
logging.info('[+] Credentials stored successfully on the file: %s\\credentials.txt\n' % constant.folder_name)
except:
logging.info('Couldn\'t write the results file\n')
if "Passwords" not in constant.finalResults:
constant.finalResults["Passwords"] = []
constant.finalResults["Passwords"].append([{"Category": category}, values])

# --------------------------- End of functions used to write ---------------------------

Expand Down Expand Up @@ -136,4 +141,30 @@ def print_debug(error_level, message):
else:
logging.info('[%s] %s' % (error_level, message))

# --------------------------- End of output functions ---------------------------
# --------------------------- End of output functions ---------------------------

def parseJsonResultToBuffer(jsonString):
buffer = ''
try:
if jsonString:
buffer += '\r\n\r\n########## User: %s ##########\r\n' % jsonString['User']
if 'Passwords' not in jsonString:
buffer += 'No passwords found for this user !'
else:
for all_passwords in jsonString['Passwords']:
# print '- Category: %s' % all_passwords[0]['Category']
buffer += '------------------- %s -----------------\r\n' % all_passwords[0]['Category']
for password_by_category in all_passwords[1]:
buffer += '\r\nPassword found !!!\r\n'
for dic in password_by_category.keys():
try:
buffer += '%s: %s\r\n' % (dic, password_by_category[dic])
except:
buffer += '%s: %s\r\n' % (dic, password_by_category[dic].encode('utf-8'))
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
Empty file modified Linux/src/softwares/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/browsers/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/browsers/mozilla.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/browsers/opera.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/chats/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/chats/jitsi.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/chats/pbkdf2.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/chats/pidgin.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/databases/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/databases/dbvis.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/databases/sqldeveloper.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/databases/squirrel.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/sysadmin/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/sysadmin/env_variable.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/sysadmin/filezilla.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/sysadmin/shadow.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/wallet/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/wallet/gnome.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/wallet/kde.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/wifi/__init__.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/wifi/wifi.py
100644 → 100755
Empty file.
Empty file modified Linux/src/softwares/wifi/wpa_supplicant.py
100644 → 100755
Empty file.
15 changes: 12 additions & 3 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ Usage
* example: laZagne.exe browsers -f
* help: laZagne.exe browsers -h

* Write all passwords found into a file (-w options)
* cmd: laZagne.exe all -w
* Write all passwords found into a file (-oN for Normal txt, -oJ for Json, -oA for All)
* cmd: laZagne.exe all -oN

* Use a file for dictionary attacks (used only when it's necessary: mozilla masterpassword, system hahes, etc.). The file has to be a wordlist in cleartext (no rainbow), it has not been optmized to be fast but could useful for basic passwords.
* cmd: laZagne.exe all -path file.txt
Expand All @@ -50,6 +50,13 @@ Supported software

(*) used by many tools to store passwords: Chrome, Owncloud, Evolution, KMail, etc.

User impersonnation
----
When laZagne is launched with admin privileges (UAC bypassed) or System, it manages to retrieve passwords from other user.
It uses two ways to do that:
* If a process from another user is launched (using runas or if many users are connected to the same host), it manages to steal a process token to launch laZagne with its privileges (this is the best way). It could retrieve passwords stored encrypted with the Windows API.
* If no process has been launched but other user exists (visible on the file system in C:\Users\...), it browses the file system in order to retrieve passwords from these users. However, it could not retrieve passwords encrypted with the Windows API (we have to be on the same context as the user to decrypt these passwords). Only few passwords could be retrieved (Firefox, Jitsi, Dbvis, etc.).

IE Browser history
----
Internet Explorer passwords (from IE7 and before Windows 8) can only be decrypted using the URL of the website. This one is used as an argument of the Win32CryptUnprotectData api. Thus, using the browsing history of ie will permit to decrypt many passwords.
Expand Down Expand Up @@ -91,14 +98,16 @@ To compile the source code, some external libraries are required.
* PyCrypto: pip install pycrypto
* Impacket (for Windows hashes + LSA Secrets): https://github.com/CoreSecurity/impacket
* Pyasn1 (for ASN1 decoding): https://pypi.python.org/pypi/pyasn1/
* Microsoft Visual C++ 2010 Redistributable Package (x86): https://www.microsoft.com/en-us/download/details.aspx?id=5555

* For Linux
* Python 2.7
* Argparse
* PyCrypto: https://www.dlitz.net/software/pycrypto/
* Dbus (Pidgin)
* Python-kde4 (Kwallet)
* Pyasn1 (for ASN1 decoding): https://pypi.python.org/pypi/pyasn1/
* Python Gnome keyring: apt-get install python-gnomekeyring
* Python-kde4 (Kwallet): apt-get install python-kde4

----
| __Alessandro ZANNI__ |
Expand Down
Empty file modified Windows/src/LaZagne/config/__init__.py
100644 → 100755
Empty file.
Loading

0 comments on commit 658a1a5

Please sign in to comment.