WebLogic密码恢复(二)[转]_Tomcat, WebLogic及J2EE讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Tomcat, WebLogic及J2EE讨论区 »
总帖数
2
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4636 | 回复: 1   主题: WebLogic密码恢复(二)[转]        下一篇 
John
注册用户
等级:大元帅
经验:90444
发帖:136
精华:2
注册:2011-7-21
状态:离线
发送短消息息给John 加好友    发送短消息息给John 发消息
发表于: IP:您无权察看 2011-8-15 14:00:22 | [全部帖] [楼主帖] 楼主

来源: http://www.cnblogs.com/alfredxiao/archive/2010/09/16/weblogic_lost_password2.html

作者: 长须飘飘

如果你不想用WebLogic密码恢复(一)介绍的加新帐号的方式,哦们还有一个至强的杀手锏,就是反向破解。废话少说了,这种方法就是利用WLST脚本对boot.properties文件进行解密。大家都知道,boot.properties就是保存了你的启动帐号和密码的一个文件,开始时是明文的,第一次启动后被系统加密。当忘记密码之后,用本法可以破解从而读出之前的密码。其中之原理就不得而知了。

北京联动北方科技有限公司北京联动北方科技有限公司代码

#=============================================================================# Jython Script for displaying de-crypted WebLogic boot.properties files## To run, change to a WebLogic domain directory and execute:## > /opt/weblogic/wlsadm/weblogic92/common/bin/wlst.sh ~/home/chordadm/wlsdecrypt.py (Unix)# OR# > C:\\bea\\weblogic92\\common\\bin\\wlst.cmd C:\\myscripts\\wlsdecrypt.py (Windows)## Add parameter '-?' to the end of the command line to display more help#============================================================================= import osfrom java.io import FileInputStreamfrom java.util import Propertiesfrom weblogic.management import EncryptionHelperfrom weblogic.security.service import SecurityManagerfrom weblogic.security.subject import SubjectManager # =============================================================================# Main#=============================================================================def main():# for arg in sys.argv:# if arg.count(arg.strip()):# printUsageAndExit() saltFilePath=os.path.join('security', 'SerializedSystemIni.dat') if not os.path.exists(saltFilePath): print "Error: The script must be run from a WebLogic domain direcotry or a directory containing '%s'" % saltFilePath printUsageAndExit() try: open(saltFilePath, 'r').close() except IOError: print "Error: The file '%s' is not readable - check file permissions" % saltFilePath printUsageAndExit() processBootFiles(os.curdir, descryptPropsFile) # =============================================================================# Decrypt (Note, to encrypt just use: EncryptionHelper.encrypt(text))#=============================================================================def decrypt(text): getKernelIdMethod = SecurityManager.getDeclaredMethod('getKernelIdentity', None) getKernelIdMethod.accessible=1 return EncryptionHelper.decrypt(text, getKernelIdMethod.invoke(SecurityManager, None)) # =============================================================================# Process Boot Files#=============================================================================def processBootFiles(rootPath, processFunc): if not os.path.isdir(rootPath): return fileNames = os.listdir(rootPath) for fileName in fileNames: path = os.path.join(rootPath, fileName) if os.path.isfile(path): if fileName == 'boot.properties': processFunc(path) elif os.path.isdir(path): processBootFiles(path, processFunc) processFunc("./boot.properties") # =============================================================================# Decrypt Props File#=============================================================================def descryptPropsFile(filepath): print print '----- Decrypting %s -----' % filepath try: properties = Properties() file = FileInputStream(filepath) properties.load(file) file.close() for entry in properties.entrySet(): print '%s = %s' % (entry.key.strip(), java.lang.String(decrypt(entry.value.strip()))) except IOError: print "Error: Unable to read file '%s' - check file permissions" % filepath print # =============================================================================# Print Usage And Exit#=============================================================================def printUsageAndExit(): print print 'wlsdecrypt.py' print '-------------' print print "Jython Script for displaying de-crypted boot.properties files from a WebLogic domain. Before running the script, change directory to the directory that contains a WebLogic domain (or a directory containing 'security/SerializedSystemIni.dat' and one or more associated 'boot.properties' files). Run this script via WLST or directly via the Java/Jython launch command (the latter option requires both 'jython.jar' and 'weblogic.jar' to be added to the classpath)." print print 'Example Usage:' print print '> /opt/weblogic/wlsadm/weblogic92/common/bin/wlst.sh ~/home/chordadm/wlsdecrypt.py (Unix)' print print '> C:\\bea\\weblogic92\\common\\bin\\wlst.cmd C:\\myscripts\\wlsdecrypt.py (Windows)' print exit() ## Invoke main and end#main()

用法很简单,如下:

1、cd到你的域目录;

2、运行 <weblogic_home>\wlserver_10.3\common\bin\wlst.cmd/sh <path_to_script>/your_script.py

注意:

a. 上面给出的脚本是Jyphon语法的脚本,你需要把它保存起来,文件即是上面第2步的参数指向的文件;

b. 以上的脚本是适用于WebLogic 9.x和10.x的,如果要在WebLogic 8中使用,你需要把“saltFilePath=os.path.join(’security’, ‘SerializedSystemIni.dat’)”这行中的’security’改为’.’即可;

c. 确保你要解密的boot.properties是在域目录中,如weblogic 9/10的话你可以从servers\<AdminServer>\security下拷贝。


实际上,高人很多阿,有人写了一个Java程序,来解密包括boot.properties和xml配置文件中的密码(如config.xml及jdbc设置的xml文件),我就把其源码给贴出来分享了:

北京联动北方科技有限公司北京联动北方科技有限公司代码

import java.util.*;import java.io.*;import javax.xml.parsers.*;import javax.xml.xpath.*;import org.w3c.dom.*; import weblogic.security.internal.*; // requires weblogic.jar in the class pathimport weblogic.security.internal.encryption.*; public class WebLogicDecryptor { private static final String PREFIX = "{3DES}"; private static final String XPATH_EXPRESSION = "//node()[starts-with(text(), '" + PREFIX + "')] //@*[starts-with(., '" + PREFIX + "')]"; private static ClearOrEncryptedService ces; public static void main(String[] args) throws Exception { if (args.length < 2) { System.out.println("Usage: [domainDir] [configFile]"); return; } ces = new ClearOrEncryptedService(SerializedSystemIni.getEncryptionService(new File(args[0]).getAbsolutePath())); File file = new File(args[1]); if (file.getName().endsWith(".xml")) { processXml(file); } else if (file.getName().endsWith(".properties")){ processProperties(file); } } private static void processXml(File file) throws Exception { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file); XPathExpression expr = XPathFactory.newInstance().newXPath().compile(XPATH_EXPRESSION); NodeList nodes = (NodeList)expr.evaluate(doc, XPathConstants.NODESET); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); print(node.getNodeName(), node.getTextContent()); } } private static void processProperties(File file) throws Exception { Properties properties = new Properties(); properties.load(new FileInputStream(file)); for (Map.Entry p : properties.entrySet()) { if (p.getValue().toString().startsWith(PREFIX)) { print(p.getKey(), p.getValue()); } } } private static void print(Object attributeName, Object encrypted) { System.out.println("Node name: " + attributeName); System.out.println("Encrypted: " + encrypted); System.out.println("Decrypted: " + ces.decrypt((String)encrypted) + "\n"); }}

这段代码,原则上对WebLogic 8/9/10都可以使用,单因为目录结构稍有不同,可以根据实际需要调整。原链接是 http://gustlik.wordpress.com/2008/08/06/decryption-of-configuration-passwords-in-weblogic/

另外,原来Apache上也有一个类似的东西,原链接为 http://geronimo.apache.org/apidocs/2.0.1/src-html/org/apache/geronimo/converter/bea/Weblogic81Utils.html。内容如下(以下代码把decryptString()改为public了):

北京联动北方科技有限公司北京联动北方科技有限公司代码

/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.geronimo.converter.bea; import java.util.regex.Pattern;import java.util.regex.Matcher;import java.util.Properties;import java.util.Iterator;import java.lang.reflect.Method;import java.lang.reflect.InvocationTargetException;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.BufferedReader;import java.io.FileReader;import java.io.StringWriter;import java.io.PrintWriter;import java.io.IOException;import java.io.InputStream;import java.net.URLClassLoader;import java.net.URL; /** * Reads information out of the WebLogic domain directory. * Needs access to the WebLogic JARs in the weblogic81/server/lib directory. * * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ */public class Weblogic81Utils { private final static Pattern ENCRYPTED_STRING = Pattern.compile("\\\"\\{\\S+\\}\\S+?\\\""); private Object decoder; private Method decode; private Object decrypter; private Method decrypt; private File domainDir; public Weblogic81Utils(String libDirPath, String domainDirPath) { File libDir = new File(libDirPath); if(!libDir.exists() !libDir.canRead() !libDir.isDirectory()) throw new IllegalArgumentException("Bad weblogic lib dir"); File weblogicJar = new File(libDir, "weblogic.jar"); File securityJar = new File(libDir, "jsafeFIPS.jar"); if(!weblogicJar.canRead()) throw new IllegalArgumentException("Cannot find JARs in provided lib dir"); domainDir = new File(domainDirPath); if(!domainDir.exists() !domainDir.canRead() !domainDir.isDirectory()) throw new IllegalArgumentException("Bad domain directory"); File state = new File(domainDir, "SerializedSystemIni.dat"); if(!state.canRead()) throw new IllegalArgumentException("Cannot find serialized state in domain directory"); try { ClassLoader loader = new URLClassLoader(securityJar.exists() ? new URL[]{weblogicJar.toURL(), securityJar.toURL()} : new URL[]{weblogicJar.toURL()}, Weblogic81Utils.class.getClassLoader()); initialize(loader, state); } catch (Exception e) { throw (RuntimeException)new IllegalArgumentException("Unable to initialize encryption routines from provided arguments").initCause(e); } } public Properties getBootProperties() { File boot = new File(domainDir, "boot.properties"); FileInputStream bootIn = null; try { bootIn = new FileInputStream(boot); } catch (FileNotFoundException e) { return null; } try { Properties props = new Properties(); props.load(bootIn); bootIn.close(); for (Iterator it = props.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); String value = props.getProperty(key); if(value != null && value.startsWith("{")) props.setProperty(key, decryptString(value)); } return props; } catch (Exception e) { return null; } } public String getConfigXML() throws FileNotFoundException { File config = new File(domainDir, "config.xml"); BufferedReader in = new BufferedReader(new FileReader(config)); StringWriter string = new StringWriter(); PrintWriter out = new PrintWriter(string); String line; Matcher m = ENCRYPTED_STRING.matcher(""); try { while((line = in.readLine()) != null) { m.reset(line); int last = -1; while(m.find()) { out.print(line.substring(last+1, m.start())); String s = line.substring(m.start(), m.end()); out.print("\""); out.print(decryptString(s.substring(1, s.length()-1))); out.print("\""); last = m.end()-1; } if(last == -1) { out.println(line); } else { if(line.length() > last+1) { out.print(line.substring(last+1)); } out.println(); } out.flush(); } in.close(); out.close(); } catch (Exception e) { return null; } return string.getBuffer().toString(); } private void initialize(ClassLoader loader, File state) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException, InstantiationException { byte[] salt = null, key = null; FileInputStream in = new FileInputStream(state); salt = readBytes(in); int i = in.read(); if(i != -1) { if(i != 1) throw new IllegalStateException(); key = readBytes(in); } in.close(); decrypter = getEncryptionService(loader, salt, key); decoder = loader.loadClass("weblogic.utils.encoders.BASE64Decoder").newInstance(); decode = decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}); decrypt = decrypter.getClass().getMethod("decryptString", new Class[]{byte[].class}); } private static byte[] readBytes(InputStream in) throws IOException { int len = in.read(); if(len < 0) throw new IOException("stream is empty"); byte result[] = new byte[len]; int index = 0; while(true) { if(index >= len) { break; } int count = in.read(result, index, len - index); if(count == -1) break; index += count; } return result; } public String decryptString(String string) throws IllegalAccessException, InvocationTargetException { if(string.indexOf('}') > -1) { string = string.substring(string.indexOf("}")+1); } return (String) decrypt.invoke(decrypter, new Object[]{decode.invoke(decoder, new Object[]{string})}); } static Object getEncryptionService(ClassLoader loader, byte salt[], byte key[]) throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException { String magic = "0xccb97558940b82637c8bec3c770f86fa3a391a56"; Object factory = loader.loadClass("weblogic.security.internal.encryption.JSafeEncryptionServiceImpl").getMethod("getFactory", new Class[0]).invoke(null, null); Method getter = factory.getClass().getMethod("getEncryptionService", new Class[]{byte[].class, String.class, byte[].class}); return getter.invoke(factory, new Object[]{salt, magic, key}); }}

简单编写一个客户端即可调用之,例如:

北京联动北方科技有限公司北京联动北方科技有限公司代码

import java.util.*;import java.io.*; public class Main { public static void main(String args[]) { try{ if ( args== null args.length<2 ) { System.out.println("Usage:" ); System.out.println("arg1 = Server/lib or the Directory which has the requried JAR files"); System.out.println("arg2 = App Domain or the Directory which has SerializedSystemIni.dat"); System.out.println("[arg3] = 3DES hashed password"); System.exit(0); } if (! new File(args[0]).exists()) { System.out.println("Path ["+args[0]+"] does not exists"); System.exit(0); } if (! new File(args[1]).exists()) { System.out.println("Path ["+args[1]+"] does not exists"); System.exit(0); } String beaDir = args[0]; String appDir = args[1]; String hashedPassword = null; if (args.length >= 3) { hashedPassword = args[2]; } Weblogic81Utils weblogic81Utils = new Weblogic81Utils(beaDir, appDir); String configXML = weblogic81Utils.getConfigXML(); Properties bootProperties = (Properties) weblogic81Utils.getBootProperties(); System.out.println("---------------------------------------------------------------------"); System.out.println("boot.properties" + " <username> " + bootProperties.getProperty("username")); System.out.println("boot.properties" + " <password> " + bootProperties.getProperty("password")); if (hashedPassword != null) { String plainTextPassword = weblogic81Utils.decryptString(hashedPassword); System.out.println(hashedPassword + " == " + plainTextPassword); } System.out.println("---------------------------------------------------------------------"); } catch (Exception e) { throw (RuntimeException)new IllegalArgumentException("Unable to initialize encryption routines from provided ar guments").initCause(e); } } //end of main}

注意decryptString()本来不是public的。运行时,第一个参数是server/lib对应的目录路径,如C:\bea\wls816\weblogic81\server\lib;第二个参数是域目录;第三个参数是可选的,你可以从boot.properties或者其他xml里拿到密码片段然后作为这个参数,如{3DES}g+uYFmHnzJ7jojlRd+SOwg==,注意在boot.properties文件中,有时用\=代表一个=,这是由于.properties文件的格式要求,你运行以上程序(Main.java)时输入的第三个参数不应该包含’\’号。

另外还有知道,这些程序解密时都需要读取域目录下的一个文件SerializedSystemIni.dat,以作为解密的key使用,因此,不能把一个域中的加密后的字符片段拿到另一个域中去解,那样是解不出来的。




赞(0)    操作        顶端 
tianyuan.liu
注册用户
等级:上尉
经验:766
发帖:33
精华:0
注册:1970-1-1
状态:离线
发送短消息息给tianyuan.liu 加好友    发送短消息息给tianyuan.liu 发消息
发表于: IP:您无权察看 2015-1-22 16:33:49 | [全部帖] [楼主帖] 2  楼

该帖已被版主加工整理,多个帖子进行了联合编辑

浏览最新整理出的资料贴: http://bbs.landingbj.com:80/t-0-251327-1.html



赞(0)    操作        顶端 
总帖数
2
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论