0x01 背景说明
我们在渗透测试过程中,可以很容易发现weblogic的 server name
一旦被修改,其web应用有一个目录就会发生改变,导致我们在部署war拿shell时受阻。
比如bea_wls_internal这个weblogic自带web应用的web目录物理路径为:
weblogic10.3.6.0user_projectsdomainsbase_domainserversAdminServertmp_WL_internalbea_wls_internal9j4dqkwar
PS:为了后面的讨论,这里统一下概念,域名为base_domain
,server name
为AdminServer
,web应用名为bea_wls_internal
,伪随机目录为9j4dqk
。
这时如果server name
修改为c0ny1
的话,经过测试其伪随机目录会变成qn64ct
,即该web应用物理路径变为:
weblogic10.3.6.0user_projectsdomainsbase_domainserversc0ny1tmp_WL_internalbea_wls_internalqn64ctwar
0x02 真随机 or 伪随机?
在此前我一直以为改目录是随机的无法。直到我做了下面的测试,将两个域的server name
都改为c0ny1
。
![]()
![]()
发现两个域下相同web应用的随机目录名相同,这说明随机数目录其实是伪随机,它是有算法来生成的。而通过结果我们很容易就判断出该随机数和域名无关,和server name
与application name
有关!
0x03 探究生成算法
于是我打算跟踪下weblogic源码,扒出负责生产伪随机数的算法函数。由于其生成伪随机目录在weblogic未启动完全情况下,故通过weblogic配置的调试比较难。这种情况下更好的思路是插桩,但要插哪个函数的桩呢?
我在翻阅weblogic的源码(weblogic.jar)时,着重关注文件操作和部署接口的代码,发现了一个相关性很大的方法。该函数就在weblogic的路径工具类(weblogic.application.utils.PathUtils)中。
![]()
在判断不失误的情况下,我们只要知道其传入的参数值就知道改函数如何使用了。为此我编写了如下代码,使用javassist将打印函数参数值的代码注入到该函数中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod;
public class Test { public static void changeMethode() { try { ClassPool.getDefault().insertClassPath("/Users/c0ny1/IdeaProjects/weblogic-path-test/lib/weblogic.jar");
CtClass cls = ClassPool.getDefault().getCtClass("weblogic.application.utils.PathUtils"); CtMethod m = cls.getDeclaredMethod("generateTempPath"); m.setBody("{StringBuffer var3 = new StringBuffer();n" + " if ($1 != null) {n" + " var3.append($1);n" + " }n" + "n" + " if ($2 != null) {n" + " var3.append("_").append($2);n" + " }n" + "n" + " if ($3 != null) {n" + " var3.append("_").append($3);n" + " }n" + "n" + " String str = $2 + java.io.File.separator + Long.toString((long)Math.abs(var3.toString().hashCode()), 36);n" + " System.out.println("[+] p1:" + $1);n" + " System.out.println("[+] p2:" + $2);n" + " System.out.println("[+] p3:" + $3);n" + " System.out.println("[+] " + str);n" + " return str;}"); cls.defrost(); cls.writeFile("./PathUtils.class");
} catch (Exception e) { e.printStackTrace(); } }
public static void main(String[] args) { changeMethode(); } }
|
![]()
将插桩后的PathUtils类通过Winrar软件覆盖weblogic.jar原来的类,然后重新启动weblogic,即可从控制台查看到如下:
![]()
由此我们知道web应用bea_wls9_async_response的随机目录被生成时,该函数被调用并传入server name
和application name
,这也验证我们之前的猜想。
1
|
generateTempPath("c0ny1","bea_wls9_async_response","bea_wls9_async_response.war")
|
0x04 伪随机目录生成代码编写
到这里写计算伪随机目录生成程序就是很简单的事了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class WeblogicPathBuilder { public static String generateTempPath(String paramString1, String paramString2, String paramString3) { StringBuffer stringBuffer = new StringBuffer();
if (paramString1 != null) stringBuffer.append(paramString1);
if (paramString2 != null) { stringBuffer.append("_").append(paramString2); }
if (paramString3 != null) { stringBuffer.append("_").append(paramString3); } return Long.toString(Math.abs(stringBuffer.toString().hashCode()), 36); }
public static void main(String[] args) { String ServerName = args[0]; String AppName = args[1]; String AppWarName = AppName + ".war"; System.out.println(generateTempPath(ServerName,AppName,AppWarName)); } }
|
计算结果和weblogic实际生成完全吻合!!!
![]()
之后的几天逛Github时,发现早就有人发现其规律。
https://github.com/dr0op/WeblogicScan/blob/master/app/plugins/CVE-2019-2618.py
文章来源于gv7.me:weblogic“伪随机”目录生成算法探究
相关推荐: 过滤器作用范围/和/*引发的安全问题
问题:过滤器作用范围设置为/或/*一样么? 安全人员可能觉得不一样,毕竟从对通配符的认识来说,/代表的只是根目录,/*代表所有。 开发人员可能觉得一样,根据平常的开发经验,并未发现两者的差别。 其实呢,这两种认识都不正确,更确切地说前者说的不够正确。具体许我慢…
评论