1

How to get a heart attack while using JEB decompiler

 1 year ago
source link: https://blog.stmcyber.com/how-to-get-a-heart-attack-while-using-jeb-decompiler/
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

How to get a heart attack while using JEB decompiler

Author: Anonymous Duck, 15.09.2022

Once upon a time, we had to reverse engineer an Android application. To do that, we've decided to use our favorite tool of choice - JEB. All was good until we noticed something suspicious…

Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "2022.08.30"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "2022.08.30"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "15:33:24.375"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "2022.08.30"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "2022.08.30"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "15:33:24.375"

We highly doubted that our application had an encrypted string with the exact current date down to a second. It looked like facts about our environment were somehow being "leaked" into the decompilation? When you suspect some shady actions are happening, it's always a good idea to look at the process list:

image.png
htop showing JEB spawning suspicious processes

WHAT.

Does the application we're reverse engineering contain a JEB 0-day? Is someone actively trying to exploit us? After a short reverse engineering effort, we've located the suspect, which is a function that looks for su binary on a rooted device:

public static String H() {
String s = System.getenv("PATH");
HashSet hashSet0 = new HashSet();
String[] arr_s = s.split(":");
for(int v = 0; v < arr_s.length; ++v) {
hashSet0.add(arr_s[v]);
Iterator iterator0 = hashSet0.iterator();
while(iterator0.hasNext()) {
Object object0 = iterator0.next();
String s1 = (String)object0;
if(!new File(s1 + "/su").exists()) {
continue;
Process process0 = Runtime.getRuntime().exec(new String[]{s1 + "/su", "-c", "id"}, null, null);
BufferedReader bufferedReader0 = new BufferedReader(new InputStreamReader(process0.getInputStream()));
String s2 = bufferedReader0.readLine();
bufferedReader0.close();
process0.waitFor();
if(s2 == null) {
return null;
if(!s2.startsWith("uid=0")) {
continue;
return s1 + "/su";
catch(InterruptedException | IOException iOException0) {
Log.i("ERROR", Utils.w(iOException0));
return null;
    public static String H() {
        String s = System.getenv("PATH");
        HashSet hashSet0 = new HashSet();
        
        String[] arr_s = s.split(":");
        for(int v = 0; v < arr_s.length; ++v) {
            hashSet0.add(arr_s[v]);
        }

        Iterator iterator0 = hashSet0.iterator();
        while(iterator0.hasNext()) {
            Object object0 = iterator0.next();
            String s1 = (String)object0;
            if(!new File(s1 + "/su").exists()) {
                continue;
            }

            try {
                Process process0 = Runtime.getRuntime().exec(new String[]{s1 + "/su", "-c", "id"}, null, null);
                BufferedReader bufferedReader0 = new BufferedReader(new InputStreamReader(process0.getInputStream()));
                String s2 = bufferedReader0.readLine();
                bufferedReader0.close();
                process0.waitFor();
                if(s2 == null) {
                    return null;
                }

                if(!s2.startsWith("uid=0")) {
                    continue;
                }

                return s1 + "/su";
            }
            catch(InterruptedException | IOException iOException0) {
                Log.i("ERROR", Utils.w(iOException0));
            }
        }

        return null;
    }

The hypothesis was that JEB somehow executes this code in its runtime. To verify this idea, we've prepared a modified version of the apk file by unpacking it with apktool, patching strings, and packing the apk back up. Shortly after, we confirmed the hypothesis - indeed, JEB was executing code from the application!

image-6.png
htop showing Jeb spawning "better" processes

However, after opening JEB more than a dozen times in a span of 15 minutes, we've also noticed a fine print in Jeb's console log right after hitting the decompile button.

image-1.pnglogs from Jeb while performing decompilation

Hmmm? Let's read more from JEB's website.

image-2.png
note from Jeb's webpage about JDK 18+

Oh. Oooooooh. That explains a lot. So JEB's "emulation" is just executing code in a sandbox. And since Java Security Sandbox doesn't work on Java 18 without an additional console flag - it executes code without any sandboxing on your host machine.

It would be nice to have this notification in a big red message box instead of small print after you hit decompile. At that point it's kind of too late. Especially when you can read this on their blog post:

image-3.pngfragment form JEB's blog about deobfuscators

How to avoid this problem?

Just disable deobfuscators during decompilation or use older Java.

image-4.png
JEB decompilation options

Special note from author:

image-5.png
author of this blog post after nearly getting a heart attack

Extra note: We tried to contact the PNF Software crew twice on their slack before posting this article, but they didn't respond to us.

Update 17.09.2022: The vulnerability was patched in the JEB 4.19.1, thanks to the PNF Software crew for the fast patch.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK