
Nail in the JKS coffin - Cracking passwords of private key entries in a JKS file
The Java Key Store (JKS) is the Java way of storing one or several cryptographic private and public keys for asymmetric cryptography in a file. While there are various key store formats, Java and Android still default to the JKS file format. JKS is one of the file formats for Java key stores, but JKS is confusingly used as the acronym for the general Java key store API as well. This project includes information regarding the security mechanisms of the JKS file format and how the password protection of the private key can be cracked. Due the unusual design of JKS the developed implementation can ignore the key store password and crack the private key password directly. Because it ignores the key store password, this implementation can attack every JKS configuration, which is not the case with most other tools. By exploiting a weakness of the Password Based Encryption scheme for the private key in JKS, passwords can be cracked very efficiently. Until now, no public tool was available exploiting this weakness. This technique was implemented in hashcat to amplify the efficiency of the algorithm with higher cracking speeds on GPUs.
To get the theory part, please refer to the POC||GTFO article "15:12 Nail in the Java Key Store Coffin" in issue 0x15 included in this repository (pocorgtfo15.pdf) or available on various mirros like this beautiful one: https://unpack.debug.su/pocorgtfo/
Before you ask: JCEKS or BKS or any other Key Store format is not supported (yet).
The answer is build your own cracking hardware for it ;) . But let's be a little more practical, so the answer is using your GPU:
_____: _____________ _____: v3.6.0 ____________
_\ |__\______ _/_______ _\ |_____ _______\______ /__ ______
| _ | __ \ ____/____ _ | ___/____ __ |_______/
| | | \ _\____ / | | \ / \ | |
|_____| |______/ / /____| |_________/_________: |
|_____:-aTZ!/___________/ |_____: /_______:
* BLAKE2 * BLOCKCHAIN2 * DPAPI * CHACHA20 * JAVA KEYSTORE * ETHEREUM WALLET *
All you need to do is run the following command:
java -jar JksPrivkPrepare.jar your_JKS_file.jks > hash.txt
If your hash.txt ends up being empty, there is either no private key in the JKS file or you specified a non-JKS file.
Then feed the hash.txt file to hashcat (version 3.6.0 and above, but if you want to be on the safe side and also make sure you can crack very long passwords please use at least version 4 of hashcat!), for example like this:
$ ./hashcat -m 15500 -a 3 -1 '?u|' -w 3 hash.txt ?1?1?1?1?1?1?1?1?1
hashcat (v3.6.0) starting...
OpenCL Platform #1: NVIDIA Corporation
======================================
* Device #1: GeForce GTX 1080, 2026/8107 MB allocatable, 20MCU
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Applicable optimizers:
* Zero-Byte
* Precompute-Init
* Not-Iterated
* Appended-Salt
* Single-Hash
* Single-Salt
* Brute-Force
Watchdog: Temperature abort trigger set to 90c
Watchdog: Temperature retain trigger set to 75c
$jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test:POC||GTFO
Session..........: hashcat
Status...........: Cracked
Hash.Type........: JKS Java Key Store Private Keys (SHA1)
Hash.Target......: $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test
Time.Started.....: Tue May 30 17:41:58 2017 (8 mins, 25 secs)
Time.Estimated...: Tue May 30 17:50:23 2017 (0 secs)
Guess.Mask.......: ?1?1?1?1?1?1?1?1?1 [9]
Guess.Charset....: -1 ?u|, -2 Undefined, -3 Undefined, -4 Undefined
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#1.....: 7946.6 MH/s (39.48ms)
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 4014116700160/7625597484987 (52.64%)
Rejected.........: 0/4014116700160 (0.00%)
Restore.Point....: 5505024000/10460353203 (52.63%)
Candidates.#1....: NNVGFSRFO -> Z|ZFVDUFO
HWMon.Dev.#1.....: Temp: 75c Fan: 89% Util:100% Core:1936MHz Mem:4513MHz Bus:1
Started: Tue May 30 17:41:56 2017
Stopped: Tue May 30 17:50:24 2017
So from this repository you basically only need the JksPrivkPrepare.jar to run a cracking session.
This information is only important to CTF players or hash cracking competition players. In real life you should have access to the JKS file and just use JksPrivkPrepare.jar. However, when you get an artifical challenge, you sometimes only get the "John the Ripper" hash format from keystore2john.py. I'll explain how you can get from the "John" format to the original JKS file (yes, the entire file is in the john hash format). Let's look at an example: