From disk image to offline windows AD account login
tl;dr #
- create a writeable overlay
.qcow2
image backed by the read-only base image - attach the disk with
qemu-nbd
- mount the windows system partition
- replace
Utilman.exe
withcmd.exe
- copy
SECURITY
andSYSTEM
registry hives from the mounted partition - create a UEFI virtual machine using Virtual Machine Manager with the
.qcow2
attached - boot up the machine, click on the accessibility icon in the bottom right corner
- you get an Administrator shell, change the admin password with
net user
- close the terminal and login with Administrator
- copy
SysInternals
to the machine and launch acmd.exe
withpsexec
in the name of userSYSTEM
- on the host machine execute
mscache3.py
acquire areg
command that resets the cached user password hash to a known value - execute the
reg
command - log out and login to the target account
Detailed Steps #
Acquiring files #
We received the following files:
-rwxr-xr-x 1 root root 256060514304 Aug 26 14:30 disk.001
-rwxr-xr-x 1 root root 465 Aug 26 14:30 disk.vmdk
The .vmdk
just links to the flat file disk.001
:
# disk.vmdk
# ---
# Disk DescriptorFile
version=1
encoding="UTF-8"
CID=...
parentCID=ffffffff
createType="monolithicFlat"
# Extent description
RW 500118192 FLAT "D:\disk.001" 0
# The Disk Data Base
#DDB
ddb.adapterType = "lsilogic"
ddb.geometry.cylinders = "31130"
ddb.geometry.heads = "255"
ddb.geometry.sectors = "63"
ddb.longContentID = "..."
ddb.uuid = "..."
ddb.virtualHWVersion = "7"
So actually we don't even need the .vmdk
file because the disk.001
is just a byte-by-byte copy of the original disk.
We could even rename it to .img
, .dd
, or .raw
.
What we want to do is to create a new, writable disk image, backed by this read-only flat file, so only modifications
are written to the new file. This is what .qcow2
is for:
# create a qcow2 formatted file backed by disk.001 raw image
qemu-img create -f qcow2 -b disk.001 -F raw disk-live.qcow2
Now we can attach this file to our system as a block device with qemu-nbd
:
# load nbd module if no already loaded
modprobe nbd
qemu-nbd --connect /dev/nbd2 disk-live.qcow2
# lsblk
nbd2 43:64 0 238.5G 0 disk
├─nbd2p1 43:65 0 300M 0 part
├─nbd2p2 43:66 0 500M 0 part
├─nbd2p3 43:67 0 128M 0 part
├─nbd2p4 43:68 0 236.9G 0 part
└─nbd2p5 43:69 0 628M 0 part
Now we'd like to mount the the windows system partition (nbd2p4
):
mkdir /mnt/tmp4
mount /dev/nbd2p4 /mnt/tmp4
Now we have acccess to the complete NTFS filesystem. What we'd like to do is overwrite Utilman.exe
with cmd.exe
:
cp /mnt/tmp4/Windows/System32/Utilman.exe{,.bak}
cp /mnt/tmp4/Windows/System32/{cmd.exe,Utilman.exe}
Also copy the SYSTEM
and SECURITY
registry hives cause we'll need them later:
cp /mnt/tmp4/Windows/System32/config/{SYSTEM,SECURITY} ./
Then detach the image:
umount /mnt/tmp4
qemu-nbd -d /dev/nbd2
Working with the VM #
I was using Virtual Machine Manager (aka virt-manager
) to create and manage the VM as it was more convenient, but feel
free to use virsh
.
- Create a new virtual machine
- Select
UEFI
instead ofBIOS
. - Add the disk.
Here is my config file: vm.xml
Now boot up the machine and after seeing the login screen click on accessiblity tools in the bottom right corner.
A Command Propt should open. If you execure whoami
, you should be NT AUTHORITY\SYSTEM
.
By executing net accounts
, you should see the minimal password length and other configurations.
You can change the minimal password length to 2
with net accounts /minpwlen:2
.
Complex passwords are probably set by default which means at least 3 of the following characted classes are required:
uppercase, lowercase, digits, special characters.
Now we can change the administrator password with:
net user Administrator Admin123
Close the Command Prompt and login with Administrator
and Admin123
.
Logging in as offline AD user #
By default, Windows caches AD logins (for the last 10 accounts) so that the user can login to their machine even if the AD network is inaccessible. You can check this at the following registry key:
HKLM > SOFTWARE > Microsoft > Windows NT > CurrentVersion > Winlogon -> CachedLogonsCount = 10
This means that the login hashes are stored and compared offline. Can we change them to a known value? Yes, of course we can!
Login caches are stored in the SECURITY
hive under HKEY_LOCAL_MACHINE\SECURITY\CACHE\NL$1
through NL$10
, but
they are obfuscated BLOBs. Obfuscated means that they are encrypted with the NL$KM
key that can be queried from the
SECURITY
registry hive under: HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\NK$LM
.
Thankfully others have already done the reverse engineering so a python2
script is
available: mscache.py But we have a python3
version:
mscache3.py You can use it like this:
# list the cached entries
python3 ./mscache3.py --system ./SYSTEM --security ./SECURITY
# modify password for a user
# note that this doesn't change the hive files, only prints a reg command that you can use to change it
python3 ./mscache3.py --system ./SYSTEM --security ./SECURITY --user TargetUser --password Admin123!
For example the output reg
command might look like this:
reg add "HKEY_LOCAL_MACHINE\SECURITY\Cache" /v "NL$2" /t REG_BINARY /d <REDACTED> /f
Now all you need to do is get a Command Prompt as NT AUTHORITY\SYSTEM
and execute the output of mscache3.py
:
PsExec.exe -s -i -d cmd.exe
Now you can log out and log back in with TargetUser
and Admin123
.
- Previous post: Ansible - Show output of long running command
- Next post: About Hashcat mask processing