├── BouncyCastle.Crypto.dll ├── Invoke-WebLogicPasswordDecryptor.psm1 ├── LICENSE ├── README.md └── WebLogicPasswordDecryptor.java /BouncyCastle.Crypto.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/WebLogicPasswordDecryptor/d0d1544edcf311240a4dd87ec50e5af4f09167bf/BouncyCastle.Crypto.dll -------------------------------------------------------------------------------- /Invoke-WebLogicPasswordDecryptor.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Author: Eric Gruber 2015, NetSPI 3 | .Synopsis 4 | PowerShell script to decrypt WebLogic passwords 5 | .EXAMPLE 6 | Invoke-WebLogicPasswordDecryptor -SerializedSystemIni C:\SerializedSystemIni.dat -CipherText "{3DES}JMRazF/vClP1WAgy1czd2Q==" 7 | .EXAMPLE 8 | Invoke-WebLogicPasswordDecryptor -SerializedSystemIni C:\SerializedSystemIni.dat -CipherText "{AES}8/rTjIuC4mwlrlZgJK++LKmAThcoJMHyigbcJGIztug=" 9 | #> 10 | function Invoke-WebLogicPasswordDecryptor 11 | { 12 | [CmdletBinding()] 13 | Param 14 | ( 15 | [Parameter(Mandatory = $true, 16 | Position = 0)] 17 | [String] 18 | $SerializedSystemIni, 19 | 20 | [Parameter(Mandatory = $true, 21 | Position = 0)] 22 | [String] 23 | $CipherText, 24 | 25 | [Parameter(Mandatory = $false, 26 | Position = 0)] 27 | [String] 28 | $BouncyCastle 29 | ) 30 | 31 | if (!$BouncyCastle) 32 | { 33 | $BouncyCastle = '.\BouncyCastle.Crypto.dll' 34 | } 35 | 36 | Add-Type -Path $BouncyCastle 37 | 38 | $Pass = '0xccb97558940b82637c8bec3c770f86fa3a391a56' 39 | $Pass = $Pass.ToCharArray() 40 | 41 | if ($CipherText.StartsWith('{AES}')) 42 | { 43 | $CipherText = $CipherText.TrimStart('{AES}') 44 | } 45 | elseif ($CipherText.StartsWith('{3DES}')) 46 | { 47 | $CipherText = $CipherText.TrimStart('{3DES}') 48 | } 49 | 50 | $DecodedCipherText = [System.Convert]::FromBase64String($CipherText) 51 | 52 | $BinaryReader = New-Object -TypeName System.IO.BinaryReader -ArgumentList ([System.IO.File]::Open($SerializedSystemIni, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)) 53 | $NumberOfBytes = $BinaryReader.ReadByte() 54 | $Salt = $BinaryReader.ReadBytes($NumberOfBytes) 55 | $Version = $BinaryReader.ReadByte() 56 | $NumberOfBytes = $BinaryReader.ReadByte() 57 | $EncryptionKey = $BinaryReader.ReadBytes($NumberOfBytes) 58 | 59 | if ($Version -ge 2) 60 | { 61 | $NumberOfBytes = $BinaryReader.ReadByte() 62 | $EncryptionKey = $BinaryReader.ReadBytes($NumberOfBytes) 63 | 64 | $ClearText = Invoke-DecryptAES -Salt $Salt -EncryptionKey $EncryptionKey -Pass $Pass -DecodedCipherText $DecodedCipherText 65 | } 66 | else 67 | { 68 | $ClearText = Invoke-Decrypt3DES -Salt $Salt -EncryptionKey $EncryptionKey -Pass $Pass -DecodedCipherText $DecodedCipherText 69 | } 70 | 71 | Write-Output $ClearText 72 | } 73 | 74 | function Invoke-DecryptAES 75 | { 76 | param 77 | ( 78 | [byte[]] 79 | $Salt, 80 | 81 | [byte[]] 82 | $EncryptionKey, 83 | 84 | [char[]] 85 | $Pass, 86 | 87 | [byte[]] 88 | $DecodedCipherText 89 | ) 90 | 91 | $EncryptionCipher = 'AES/CBC/PKCS5Padding' 92 | 93 | $EncryptionKeyCipher = 'PBEWITHSHAAND128BITRC2-CBC' 94 | 95 | $IV = New-Object -TypeName byte[] -ArgumentList 16 96 | 97 | [array]::Copy($DecodedCipherText,0,$IV, 0 ,16) 98 | 99 | $CipherText = New-Object -TypeName byte[] -ArgumentList ($DecodedCipherText.Length - 16) 100 | [array]::Copy($DecodedCipherText,16,$CipherText,0,($DecodedCipherText.Length - 16)) 101 | 102 | 103 | $AlgorithmParameters = [Org.BouncyCastle.Security.PbeUtilities]::GenerateAlgorithmParameters($EncryptionKeyCipher,$Salt,5) 104 | 105 | $CipherParameters = [Org.BouncyCastle.Security.PbeUtilities]::GenerateCipherParameters($EncryptionKeyCipher,$Pass,$AlgorithmParameters) 106 | 107 | 108 | $KeyCipher = [Org.BouncyCastle.Security.PbeUtilities]::CreateEngine($EncryptionKeyCipher) 109 | $KeyCipher.Init($false, $CipherParameters) 110 | 111 | $Key = $KeyCipher.DoFinal($EncryptionKey) 112 | 113 | 114 | $Cipher = [Org.BouncyCastle.Security.CipherUtilities]::GetCipher($EncryptionCipher) 115 | $KeyParameter = [Org.BouncyCastle.Crypto.Parameters.KeyParameter] $Key 116 | $ParametersWithIV = [Org.BouncyCastle.Crypto.Parameters.ParametersWithIV]::new($KeyParameter , $IV) 117 | 118 | $Cipher.Init($false, $ParametersWithIV) 119 | $ClearText = $Cipher.DoFinal($CipherText) 120 | 121 | [System.Text.Encoding]::ASCII.GetString($ClearText) 122 | } 123 | 124 | function Invoke-Decrypt3DES 125 | { 126 | param 127 | ( 128 | [byte[]] 129 | $Salt, 130 | 131 | [byte[]] 132 | $EncryptionKey, 133 | 134 | [char[]] 135 | $Pass, 136 | 137 | [byte[]] 138 | $DecodedCipherText 139 | ) 140 | 141 | $EncryptionCipher = 'DESEDE/CBC/PKCS5Padding' 142 | 143 | $EncryptionKeyCipher = 'PBEWITHSHAAND128BITRC2-CBC' 144 | 145 | $IV = New-Object -TypeName byte[] -ArgumentList 8 146 | 147 | [array]::Copy($Salt,0,$IV, 0 ,4) 148 | [array]::Copy($Salt,0,$IV, 4 ,4) 149 | 150 | $AlgorithmParameters = [Org.BouncyCastle.Security.PbeUtilities]::GenerateAlgorithmParameters($EncryptionKeyCipher,$Salt,5) 151 | $CipherParameters = [Org.BouncyCastle.Security.PbeUtilities]::GenerateCipherParameters($EncryptionKeyCipher,$Pass,$AlgorithmParameters) 152 | 153 | $KeyCipher = [Org.BouncyCastle.Security.PbeUtilities]::CreateEngine($EncryptionKeyCipher) 154 | $KeyCipher.Init($false, $CipherParameters) 155 | 156 | $Key = $KeyCipher.DoFinal($EncryptionKey) 157 | 158 | $Cipher = [Org.BouncyCastle.Security.CipherUtilities]::GetCipher($EncryptionCipher) 159 | $KeyParameter = [Org.BouncyCastle.Crypto.Parameters.KeyParameter] $Key 160 | $ParametersWithIV = [Org.BouncyCastle.Crypto.Parameters.ParametersWithIV]::new($KeyParameter , $IV) 161 | 162 | $Cipher.Init($false, $ParametersWithIV) 163 | $ClearText = $Cipher.DoFinal($DecodedCipherText) 164 | 165 | [System.Text.Encoding]::ASCII.GetString($ClearText) 166 | } 167 | 168 | Export-ModuleMember -Function Invoke-WebLogicPasswordDecryptor 169 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 NetSPI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WebLogic Password Decryptor 2 | ========= 3 | 4 | PowerShell script and Java code to decrypt WebLogic passwords 5 | 6 | ``` 7 | Import the module 8 | 9 | Import-Module .\Invoke-WebLogicPasswordDecryptor.psm1 10 | ``` 11 | 12 | ``` 13 | Decrypt AES 14 | 15 | Invoke-WebLogicPasswordDecryptor -SerializedSystemIni C:\SerializedSystemIni.dat -CipherText "{AES}8/rTjIuC4mwlrlZgJK++LKmAThcoJMHyigbcJGIztug=" 16 | ``` 17 | 18 | ``` 19 | Decrypt 3DES 20 | 21 | Invoke-WebLogicPasswordDecryptor -SerializedSystemIni C:\SerializedSystemIni.dat -CipherText "{3DES}JMRazF/vClP1WAgy1czd2Q==" 22 | ``` 23 | 24 | ``` 25 | Java 26 | 27 | WebLogicPasswordDecryptor "C:\SerializedSystemIni.dat" "{AES}8/rTjIuC4mwlrlZgJK++LKmAThcoJMHyigbcJGIztug=" 28 | 29 | WebLogicPasswordDecryptor "C:\SerializedSystemIni.dat" "{3DES}JMRazF/vClP1WAgy1czd2Q==" 30 | 31 | ``` 32 | -------------------------------------------------------------------------------- /WebLogicPasswordDecryptor.java: -------------------------------------------------------------------------------- 1 | import org.bouncycastle.jce.provider.BouncyCastleProvider; 2 | import sun.misc.BASE64Decoder; 3 | 4 | import javax.crypto.*; 5 | import javax.crypto.spec.IvParameterSpec; 6 | import javax.crypto.spec.PBEKeySpec; 7 | import javax.crypto.spec.PBEParameterSpec; 8 | import javax.crypto.spec.SecretKeySpec; 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.security.InvalidAlgorithmParameterException; 13 | import java.security.InvalidKeyException; 14 | import java.security.NoSuchAlgorithmException; 15 | import java.security.Security; 16 | import java.security.spec.InvalidKeySpecException; 17 | 18 | 19 | public class WebLogicPasswordDecryptor { 20 | 21 | public static void main(String args[]) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException, InvalidAlgorithmParameterException { 22 | 23 | Security.addProvider(new BouncyCastleProvider()); 24 | String serializedSystemIniPath = args[0]; 25 | String ciphertext = args[1]; 26 | String cleartext = ""; 27 | 28 | if (ciphertext.startsWith("{AES}")){ 29 | ciphertext = ciphertext.replaceAll("^[{AES}]+", ""); 30 | cleartext = decryptAES(serializedSystemIniPath,ciphertext); 31 | } else if (ciphertext.startsWith("{3DES}")){ 32 | ciphertext = ciphertext.replaceAll("^[{3DES}]+", ""); 33 | cleartext = decrypt3DES(serializedSystemIniPath, ciphertext); 34 | } 35 | 36 | System.out.println(cleartext); 37 | } 38 | 39 | public static String decryptAES(String SerializedSystemIni, String ciphertext) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException { 40 | 41 | byte[] encryptedPassword1 = new BASE64Decoder().decodeBuffer(ciphertext); 42 | byte[] salt = null; 43 | byte[] encryptionKey = null; 44 | 45 | String key = "0xccb97558940b82637c8bec3c770f86fa3a391a56"; 46 | 47 | char password[] = new char[key.length()]; 48 | 49 | key.getChars(0, password.length, password, 0); 50 | 51 | FileInputStream is = new FileInputStream(SerializedSystemIni); 52 | try { 53 | salt = readBytes(is); 54 | 55 | int version = is.read(); 56 | if (version != -1) { 57 | encryptionKey = readBytes(is); 58 | if (version >= 2) { 59 | encryptionKey = readBytes(is); 60 | } 61 | } 62 | } catch (IOException e) { 63 | 64 | } 65 | 66 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHSHAAND128BITRC2-CBC"); 67 | 68 | PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, 5); 69 | 70 | SecretKey secretKey = keyFactory.generateSecret(pbeKeySpec); 71 | 72 | PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 0); 73 | 74 | Cipher cipher = Cipher.getInstance("PBEWITHSHAAND128BITRC2-CBC"); 75 | cipher.init(Cipher.DECRYPT_MODE, secretKey, pbeParameterSpec); 76 | SecretKeySpec secretKeySpec = new SecretKeySpec(cipher.doFinal(encryptionKey), "AES"); 77 | 78 | byte[] iv = new byte[16]; 79 | System.arraycopy(encryptedPassword1, 0, iv, 0, 16); 80 | int encryptedPasswordlength = encryptedPassword1.length - 16 ; 81 | byte[] encryptedPassword2 = new byte[encryptedPasswordlength]; 82 | System.arraycopy(encryptedPassword1, 16, encryptedPassword2, 0, encryptedPasswordlength); 83 | IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 84 | Cipher outCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 85 | outCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); 86 | 87 | byte[] cleartext = outCipher.doFinal(encryptedPassword2); 88 | 89 | return new String(cleartext, "UTF-8"); 90 | 91 | } 92 | 93 | public static String decrypt3DES(String SerializedSystemIni, String ciphertext) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException { 94 | 95 | byte[] encryptedPassword1 = new BASE64Decoder().decodeBuffer(ciphertext); 96 | byte[] salt = null; 97 | byte[] encryptionKey = null; 98 | 99 | String PW = "0xccb97558940b82637c8bec3c770f86fa3a391a56"; 100 | 101 | char password[] = new char[PW.length()]; 102 | 103 | PW.getChars(0, password.length, password, 0); 104 | 105 | FileInputStream is = new FileInputStream(SerializedSystemIni); 106 | try { 107 | salt = readBytes(is); 108 | 109 | int version = is.read(); 110 | if (version != -1) { 111 | encryptionKey = readBytes(is); 112 | if (version >= 2) { 113 | encryptionKey = readBytes(is); 114 | } 115 | } 116 | 117 | 118 | } catch (IOException e) { 119 | 120 | } 121 | 122 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHSHAAND128BITRC2-CBC"); 123 | 124 | PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, 5); 125 | 126 | SecretKey secretKey = keyFactory.generateSecret(pbeKeySpec); 127 | 128 | PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 0); 129 | 130 | Cipher cipher = Cipher.getInstance("PBEWITHSHAAND128BITRC2-CBC"); 131 | cipher.init(Cipher.DECRYPT_MODE, secretKey, pbeParameterSpec); 132 | SecretKeySpec secretKeySpec = new SecretKeySpec(cipher.doFinal(encryptionKey),"DESEDE"); 133 | 134 | byte[] iv = new byte[8]; 135 | System.arraycopy(salt, 0, iv, 0, 4); 136 | System.arraycopy(salt, 0, iv, 4, 4); 137 | 138 | IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 139 | Cipher outCipher = Cipher.getInstance("DESEDE/CBC/PKCS5Padding"); 140 | outCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); 141 | 142 | byte[] cleartext = outCipher.doFinal(encryptedPassword1); 143 | return new String(cleartext, "UTF-8"); 144 | 145 | } 146 | 147 | public static byte[] readBytes(InputStream stream) throws IOException { 148 | int length = stream.read(); 149 | byte[] bytes = new byte[length]; 150 | int in = 0; 151 | int justread; 152 | while (in < length) { 153 | justread = stream.read(bytes, in, length - in); 154 | if (justread == -1) { 155 | break; 156 | } 157 | in += justread; 158 | } 159 | return bytes; 160 | } 161 | } 162 | 163 | --------------------------------------------------------------------------------