Skip to content
Snippets Groups Projects
Commit 0f86bd4e authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

windows: Add code for enabling accounts

This is needed if the Administrator account is locked
parent d34c4912
No related branches found
No related tags found
No related merge requests found
...@@ -466,6 +466,7 @@ class Windows(OSBase): ...@@ -466,6 +466,7 @@ class Windows(OSBase):
self.out.output("Preparing media for boot ...", False) self.out.output("Preparing media for boot ...", False)
with self.mount(readonly=False, silent=True): with self.mount(readonly=False, silent=True):
activated = self.registry.reset_account(admin)
v_val = self.registry.reset_passwd(admin) v_val = self.registry.reset_passwd(admin)
disabled_uac = self.registry.update_uac_remote_setting(1) disabled_uac = self.registry.update_uac_remote_setting(1)
self._add_boot_scripts() self._add_boot_scripts()
...@@ -533,9 +534,11 @@ class Windows(OSBase): ...@@ -533,9 +534,11 @@ class Windows(OSBase):
if disabled_uac: if disabled_uac:
self.registry.update_uac_remote_setting(0) self.registry.update_uac_remote_setting(0)
if not activated:
self.registry.reset_account(admin, False)
if not self.sysprepped: if not self.sysprepped:
# Reset the old password # Reset the old password
admin = self.sysprep_params['admin'].value
self.registry.reset_passwd(admin, v_val) self.registry.reset_passwd(admin, v_val)
self.registry.update_firewalls(*firewall_states) self.registry.update_firewalls(*firewall_states)
...@@ -786,6 +789,7 @@ class Windows(OSBase): ...@@ -786,6 +789,7 @@ class Windows(OSBase):
with self.mount(readonly=False, silent=True): with self.mount(readonly=False, silent=True):
admin = self.sysprep_params['admin'].value admin = self.sysprep_params['admin'].value
v_val = self.registry.reset_passwd(admin) v_val = self.registry.reset_passwd(admin)
activated = self.registry.reset_account(admin)
self.registry.enable_autologon(admin) self.registry.enable_autologon(admin)
tmp = uuid.uuid4().hex tmp = uuid.uuid4().hex
......
...@@ -330,7 +330,7 @@ class Registry(object): ...@@ -330,7 +330,7 @@ class Registry(object):
# http://www.beginningtoseethelight.org/ntsecurity/index.htm # http://www.beginningtoseethelight.org/ntsecurity/index.htm
# #D3BC3F5643A17823 # #D3BC3F5643A17823
fmt = '%ds4x8s4x%ds' % (0xa0, len(v_val) - 0xb0) fmt = '%ds4x8s4x%ds' % (0xa0, len(v_val) - 0xb0)
new = ("\x00" * 4).join(struct.unpack(fmt, v_val)) new = ("\x00" * 4).join(struct.unpack(fmt, v_val))
hive.node_set_value(rid_node, REG_BINARY('V', new)) hive.node_set_value(rid_node, REG_BINARY('V', new))
hive.commit(None) hive.commit(None)
...@@ -341,6 +341,47 @@ class Registry(object): ...@@ -341,6 +341,47 @@ class Registry(object):
assert 'old' in parent, "user: `%s' does not exist" % user assert 'old' in parent, "user: `%s' does not exist" % user
return parent['old'] return parent['old']
def reset_account(self, user, activate=True):
# This is a hack. I cannot assign a new value to nonlocal variable.
# This is why I'm using a dict
state = {}
# Convert byte to int
to_int = lambda b: int(b.encode('hex'), 16)
# Under HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\%RID% there is
# an F field that contains information about this user account. Bytes
# 56 & 57 are the account type and status flags. The first bit is the
# 'account disabled' bit:
#
# http://www.beginningtoseethelight.org/ntsecurity/index.htm
# #8603CF0AFBB170DD
#
isactive = lambda f: (to_int(f[56]) & 0x01) == 0
def update_f_field(hive, username, rid_node):
field = hive.node_get_value(rid_node, 'F')
f_type, f_val = hive.value_value(field)
assert f_type == 3L, "F field type (=%d) isn't REG_BINARY" % f_type
state['old'] = isactive(f_val)
if activate is state['old']:
# nothing to do
return
mask = (lambda b: b & 0xfe) if activate else (lambda b: b | 0x01)
new = struct.pack("56sB23s", f_val[:56], mask(to_int(f_val[56])),
f_val[57:])
hive.node_set_value(rid_node, REG_BINARY('F', new))
hive.commit(None)
self._foreach_user([user], update_f_field, write=True)
return state['old']
def _foreach_user(self, userlist, action, write=False): def _foreach_user(self, userlist, action, write=False):
"""Performs an action on the RID node of a user in the registry, for """Performs an action on the RID node of a user in the registry, for
every user found in the userlist. If userlist is empty, it performs the every user found in the userlist. If userlist is empty, it performs the
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment