Skip to content

Commit

Permalink
[WIP] py3 - creddump + pep8
Browse files Browse the repository at this point in the history
  • Loading branch information
AlessandroZ committed Apr 10, 2019
1 parent f0db340 commit 0e3dbc5
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 62 deletions.
14 changes: 7 additions & 7 deletions Windows/lazagne/softwares/windows/creddump7/addrspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, fname, mode='rb', fast=False):
self.fhandle = open(fname, mode)
self.fsize = os.path.getsize(fname)

if fast == True:
if fast:
self.fast_fhandle = open(fname, mode)

def fread(self, len):
Expand Down Expand Up @@ -87,12 +87,12 @@ def read(self, vaddr, length, zero=False):
left_over = (length + vaddr) % BLOCK_SIZE

paddr = self.vtop(vaddr)
if paddr == None and zero:
if not paddr and zero:
if length < first_block:
return "\0" * length
else:
stuff_read = "\0" * first_block
elif paddr == None:
elif not paddr:
return None
else:
if length < first_block:
Expand All @@ -109,9 +109,9 @@ def read(self, vaddr, length, zero=False):
new_vaddr = vaddr + first_block
for i in range(0, full_blocks):
paddr = self.vtop(new_vaddr)
if paddr == None and zero:
if not paddr and zero:
stuff_read = stuff_read + "\0" * BLOCK_SIZE
elif paddr == None:
elif not paddr:
return None
else:
new_stuff = self.base.read(paddr, BLOCK_SIZE)
Expand All @@ -125,9 +125,9 @@ def read(self, vaddr, length, zero=False):

if left_over > 0:
paddr = self.vtop(new_vaddr)
if paddr == None and zero:
if not paddr and zero:
stuff_read = stuff_read + "\0" * left_over
elif paddr == None:
elif not paddr:
return None
else:
stuff_read = stuff_read + self.base.read(paddr, left_over)
Expand Down
47 changes: 26 additions & 21 deletions Windows/lazagne/softwares/windows/creddump7/newobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,19 @@ def __getattribute__(self, attr):
return Pointer(tp, self.address+off, self.space, ptp)
else:
return Obj(tp, self.address+off, self.space)


def __truediv__(self, other):
if isinstance(other, (tuple, list)):
return Pointer(other[0], self.address, self.space, other[1])
elif isinstance(other, str):
return Obj(other, self.address, self.space)
else:
raise ValueError("Must provide a type name as string for casting")

def __div__(self, other):
if isinstance(other,tuple) or isinstance(other,list):
if isinstance(other, tuple) or isinstance(other, list):
return Pointer(other[0], self.address, self.space, other[1])
elif isinstance(other,str):
elif isinstance(other, str):
return Obj(other, self.address, self.space)
else:
raise ValueError("Must provide a type name as string for casting")
Expand All @@ -118,7 +126,7 @@ def members(self):
"""Return a list of this object's members, sorted by offset."""

# Could also just return the list
membs = [ (k, v[0]) for k,v in types[self.name][1].items()]
membs = [(k, v[0]) for k,v in types[self.name][1].items()]
membs.sort(key=itemgetter(1))
return map(itemgetter(0),membs) + self.extra_members

Expand Down Expand Up @@ -183,11 +191,13 @@ def __new__(typ, *args, **kwargs):
return obj

def __init__(self, name, address, space):
super(Primitive,self).__init__(name, address, space)
super(Primitive, self).__init__(name, address, space)
length, fmt = builtin_types[name]
data = space.read(address,length)
if not data: self.value = None
else: self.value = unpack(fmt,data)[0]
data = space.read(address, length)
if not data:
self.value = None
else:
self.value = unpack(fmt,data)[0]

def __repr__(self):
return repr(self.value)
Expand All @@ -210,7 +220,7 @@ def __new__(typ, *args, **kwargs):
return obj

def __init__(self, name, address, space, ptr_type):
super(Pointer,self).__init__(name, address, space)
super(Pointer, self).__init__(name, address, space)
ptr_address = read_value(space, name, address)
if ptr_type[0] == 'pointer':
self.value = Pointer(ptr_type[0], ptr_address, self.space, ptr_type[1])
Expand All @@ -223,7 +233,7 @@ def __getattribute__(self, attr):
# find an attribute via our superclass, just dereference the pointer
# and return the attribute in the pointed-to type.
try:
return super(Pointer,self).__getattribute__(attr)
return super(Pointer, self).__getattribute__(attr)
except AttributeError:
return getattr(self.value, attr)

Expand Down Expand Up @@ -262,8 +272,7 @@ def __new__(typ, *args, **kwargs):
return obj

def getName(self):
return read_string(self.space, types, ['_CM_KEY_NODE', 'Name'],
self.address, self.NameLength.value)
return read_string(self.space, types, ['_CM_KEY_NODE', 'Name'], self.address, self.NameLength.value)
Name = property(fget=getName)


Expand All @@ -273,8 +282,7 @@ def __new__(typ, *args, **kwargs):
return obj

def getName(self):
return read_string(self.space, types, ['_CM_KEY_VALUE', 'Name'],
self.address, self.NameLength.value)
return read_string(self.space, types, ['_CM_KEY_VALUE', 'Name'], self.address, self.NameLength.value)
Name = property(fget=getName)


Expand All @@ -285,11 +293,9 @@ def __new__(typ, *args, **kwargs):

def getList(self):
lst = []
list_address = read_obj(self.space, types,
['_CHILD_LIST', 'List'], self.address)
list_address = read_obj(self.space, types, ['_CHILD_LIST', 'List'], self.address)
for i in range(self.Count.value):
lst.append(Pointer("pointer", list_address+(i*4), self.space,
["_CM_KEY_VALUE"]))
lst.append(Pointer("pointer", list_address+(i*4), self.space, ["_CM_KEY_VALUE"]))
return lst
List = property(fget=getList)

Expand All @@ -303,8 +309,7 @@ def getList(self):
lst = []
for i in range(self.Count.value):
# we are ignoring the hash value here
off,tp = get_obj_offset(types, ['_CM_KEY_INDEX', 'List', i*2])
lst.append(Pointer("pointer", self.address+off, self.space,
["_CM_KEY_NODE"]))
off, tp = get_obj_offset(types, ['_CM_KEY_INDEX', 'List', i*2])
lst.append(Pointer("pointer", self.address+off, self.space, ["_CM_KEY_NODE"]))
return lst
List = property(fget=getList)
8 changes: 4 additions & 4 deletions Windows/lazagne/softwares/windows/creddump7/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@
'long long': (8, 'q'),
'unsigned long long': (8, 'Q'),
'pointer': (4, 'I'),
}
}


def obj_size(types, objname):
if objname not in types:
raise Exception('Invalid type %s not in types' % (objname))
raise Exception('Invalid type %s not in types' % objname)

return types[objname][0]


def builtin_size(builtin):
if builtin not in builtin_types:
raise Exception('Invalid built-in type %s' % (builtin))
raise Exception('Invalid built-in type %s' % builtin)

return builtin_types[builtin][0]

Expand All @@ -61,7 +61,7 @@ def read_value(addr_space, value_type, vaddr):
"""

if value_type not in builtin_types:
raise Exception('Invalid built-in type %s' % (value_type))
raise Exception('Invalid built-in type %s' % value_type)

type_unpack_char = builtin_types[value_type][1]
type_size = builtin_types[value_type][0]
Expand Down
27 changes: 12 additions & 15 deletions Windows/lazagne/softwares/windows/creddump7/win32/domcachedump.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from .rawreg import *
from ..addrspace import HiveFileAddressSpace
from .hashdump import get_bootkey
from .lsasecrets import get_secret_by_name,get_lsa_key
from .lsasecrets import get_secret_by_name, get_lsa_key
from struct import unpack

from lazagne.config.crypto.pyaes.aes import AESModeOfOperationCBC
Expand Down Expand Up @@ -55,7 +55,7 @@ def decrypt_hash_vista(edata, nlkm, ch):

out = ""
for i in range(0, len(edata), 16):
buf = edata[i : i+16]
buf = edata[i:i+16]
if len(buf) < 16:
buf += (16 - len(buf)) * "\00"
out += b"".join([aes.decrypt(buf[i:i + AES_BLOCK_SIZE]) for i in range(0, len(buf), AES_BLOCK_SIZE)])
Expand All @@ -67,19 +67,18 @@ def parse_cache_entry(cache_data):
(domain_name_len,) = unpack("<H", cache_data[60:62])
ch = cache_data[64:80]
enc_data = cache_data[96:]
return (uname_len, domain_len, domain_name_len, enc_data, ch)
return uname_len, domain_len, domain_name_len, enc_data, ch


def parse_decrypted_cache(dec_data, uname_len,
domain_len, domain_name_len):
def parse_decrypted_cache(dec_data, uname_len, domain_len, domain_name_len):
uname_off = 72
pad = 2 * ( ( uname_len / 2 ) % 2 )
pad = 2 * ((uname_len / 2) % 2)
domain_off = uname_off + uname_len + pad
pad = 2 * ( ( domain_len / 2 ) % 2 )
pad = 2 * ((domain_len / 2) % 2)
domain_name_off = domain_off + domain_len + pad

data_hash = dec_data[:0x10]

username = dec_data[uname_off:uname_off+uname_len]
username = username.decode('utf-16-le', errors='ignore')

Expand All @@ -89,7 +88,7 @@ def parse_decrypted_cache(dec_data, uname_len,
domain_name = dec_data[domain_name_off:domain_name_off+domain_name_len]
domain_name = domain_name.decode('utf-16-le', errors='ignore')

return (username, domain, domain_name, data_hash)
return username, domain, domain_name, data_hash


def dump_hashes(sysaddr, secaddr, vista):
Expand All @@ -115,12 +114,12 @@ def dump_hashes(sysaddr, secaddr, vista):

hashes = []
for v in values(cache):
if v.Name == "NL$Control": continue
if v.Name == "NL$Control":
continue

data = v.space.read(v.Data.value, v.DataLength.value)

(uname_len, domain_len, domain_name_len,
enc_data, ch) = parse_cache_entry(data)
(uname_len, domain_len, domain_name_len, enc_data, ch) = parse_cache_entry(data)

# Skip if nothing in this cache entry
if uname_len == 0:
Expand All @@ -131,9 +130,7 @@ def dump_hashes(sysaddr, secaddr, vista):
else:
dec_data = decrypt_hash(enc_data, nlkm, ch)

(username, domain, domain_name, hash) = parse_decrypted_cache(dec_data, uname_len,
domain_len, domain_name_len)

(username, domain, domain_name, hash) = parse_decrypted_cache(dec_data, uname_len, domain_len, domain_name_len)
hashes.append((username, domain, domain_name, hash))

return hashes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ def dump_hashes(sysaddr, samaddr):
if not nthash:
nthash = empty_nt
results.append(
"%s:%d:%s:%s:::" % (get_user_name(user), int(user.Name, 16), codecs.encode(lmhash, 'hex').decode(), codecs.encode(nthash, 'hex').decode()))
"%s:%d:%s:%s:::" % (get_user_name(user), int(user.Name, 16), codecs.encode(lmhash, 'hex').decode(),
codecs.encode(nthash, 'hex').decode()))
return results


Expand Down
13 changes: 5 additions & 8 deletions Windows/lazagne/softwares/windows/creddump7/win32/lsasecrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ def get_lsa_key(secaddr, bootkey, vista):
if not enc_reg_value:
return None

obf_lsa_key = secaddr.read(enc_reg_value.Data.value,
enc_reg_value.DataLength.value)
obf_lsa_key = secaddr.read(enc_reg_value.Data.value, enc_reg_value.DataLength.value)
if not obf_lsa_key:
return None

Expand All @@ -74,15 +73,15 @@ def decrypt_secret(secret, key):
Note that key can be longer than 7 bytes."""
decrypted_data = ''
j = 0 # key index
for i in range(0,len(secret),8):
for i in range(0, len(secret), 8):
enc_block = secret[i:i+8]
block_key = key[j:j+7]
des_key = str_to_key(block_key)
crypter = des(des_key, ECB)

try:
decrypted_data += crypter.decrypt(enc_block)
except:
except Exception:
continue

j += 7
Expand Down Expand Up @@ -125,8 +124,7 @@ def get_secret_by_name(secaddr, name, lsakey, vista):
if not enc_secret_value:
return None

enc_secret = secaddr.read(enc_secret_value.Data.value,
enc_secret_value.DataLength.value)
enc_secret = secaddr.read(enc_secret_value.Data.value, enc_secret_value.DataLength.value)
if not enc_secret:
return None

Expand Down Expand Up @@ -160,8 +158,7 @@ def get_secrets(sysaddr, secaddr, vista):
if not enc_secret_value:
continue

enc_secret = secaddr.read(enc_secret_value.Data.value,
enc_secret_value.DataLength.value)
enc_secret = secaddr.read(enc_secret_value.Data.value, enc_secret_value.DataLength.value)
if not enc_secret:
continue

Expand Down
15 changes: 9 additions & 6 deletions Windows/lazagne/softwares/windows/creddump7/win32/rawreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@contact: bdolangavitt@wesleyan.edu
"""

from ..newobj import Obj,Pointer
from ..newobj import Obj, Pointer
from struct import unpack

ROOT_INDEX = 0x20
Expand All @@ -33,7 +33,7 @@ def get_root(address_space):


def open_key(root, key):
if key == []:
if not key:
return root

keyname = key.pop(0)
Expand All @@ -44,9 +44,12 @@ def open_key(root, key):
return None


def subkeys(key,stable=True):
if stable: k = 0
else: k = 1
def subkeys(key, stable=True):
if stable:
k = 0
else:
k = 1

sk = (key.SubKeyLists[k]/["pointer", ["_CM_KEY_INDEX"]]).value
sub_list = []
if (sk.Signature.value == LH_SIG or
Expand All @@ -55,7 +58,7 @@ def subkeys(key,stable=True):
elif sk.Signature.value == RI_SIG:
lfs = []
for i in range(sk.Count.value):
off,tp = sk.get_offset(['List', i])
off, tp = sk.get_offset(['List', i])
lfs.append(Pointer("pointer", sk.address+off, sk.space,
["_CM_KEY_INDEX"]))
for lf in lfs:
Expand Down

0 comments on commit 0e3dbc5

Please sign in to comment.