simplify icon indicating copy to clipboard operation
simplify copied to clipboard

issue running against GE application APK

Open thehesiod opened this issue 6 years ago • 13 comments

Got the following error:

19:08:37.893 WARN  InvokeOp     - Unhandled virtual exception: java.lang.NullPointerException: Name is null
19:08:37.896 WARN  MethodReflector - Failed to reflect Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V: Name is null
19:08:37.896 ERROR NodeExecutor - ExecutionNode{signature=Lc/x;-><init>(Ljava/lang/String;ILjava/lang/String;)V, op=invoke-direct {r0, r1, r2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V, @=0} unhandled virtual exception: {}
java.lang.NullPointerException: Name is null
	at java.lang.Enum.valueOf(Enum.java:236)
	at org.cf.smalivm.MethodReflector.invoke(MethodReflector.java:138)
	at org.cf.smalivm.MethodReflector.reflect(MethodReflector.java:39)
	at org.cf.smalivm.opcode.InvokeOp.executeNonLocalMethod(InvokeOp.java:450)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:103)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNecessary(ExecutionContext.java:205)
	at org.cf.smalivm.context.ExecutionContext.readClassState(ExecutionContext.java:132)
	at org.cf.smalivm.StaticFieldAccessor.getLocalField(StaticFieldAccessor.java:32)
	at org.cf.smalivm.StaticFieldAccessor.getField(StaticFieldAccessor.java:27)
	at org.cf.smalivm.opcode.SGetOp.execute(SGetOp.java:39)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNecessary(ExecutionContext.java:205)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:96)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:185)
	at org.cf.simplify.Launcher.run(Launcher.java:149)
	at org.cf.simplify.Main.main(Main.java:14)

thehesiod avatar Sep 12 '17 02:09 thehesiod

some others like:

19:08:37.786 ERROR NodeExecutor - ExecutionNode{signature=Lcom/ge/commonframework/c/d;->a(Ljava/security/KeyStore;)Ljava/util/HashMap;, op=invoke-virtual {r5}, Ljava/security/KeyStore;->aliases()Ljava/util/Enumeration;, @=5} unhandled virtual exception: {}
java.lang.NullPointerException: null

thehesiod avatar Sep 12 '17 02:09 thehesiod

I'll need the file hash and how you executed simplify at minimum to reproduce. File would be better.

CalebFenton avatar Sep 12 '17 02:09 CalebFenton

I'm using this: https://apkpure.com/kitchen-ge-appliances/com.ge.kitchen. Thanks for looking into this! Really looking forward to seeing the output from this tool!

thehesiod avatar Sep 12 '17 19:09 thehesiod

I'll also need how you executed simplify at minimum to reproduce.

While this is a valid issue, and is probably surfacing a valid bug, simplify is unlikely to help you because the app simply isn't obfuscated. This tool is mostly for hostile sample analysis. It's 99% of the time not useful for "whatever" you want to do with a commercial app.

CalebFenton avatar Sep 12 '17 21:09 CalebFenton

this app does appear to use string obfuscation. I simply ran:

unzip GE_Appliances_v1.0.6.3.apk
java -jar ./simplify/build/libs/simplify.jar classes.dex

thehesiod avatar Sep 12 '17 21:09 thehesiod

Can you point out a class which uses string encryption? That should be simplify-able.

CalebFenton avatar Sep 12 '17 22:09 CalebFenton

I'm a newbie at this, but see com.ge.commonframework.c.c (array of base64 that decodes to binary), used in com.ge.commonframework.https.HttpsOAuthConnect.initSSLContext. Another suspicious string in com.ge.commonframework.dataModel.XMPPCredential where all the values are BuildConfig.FLAVOR.

thehesiod avatar Sep 12 '17 22:09 thehesiod

The array of base64 encoded strings looks like a certificate. It's used in Lcom/ge/commonframework/c/b;->a(Ljava/security/cert/X509Certificate;)Z to verify if the cert is trusted. If they're cert contents, they're not really encrypted and can't be decrypted.

The XMPPCredential stuff are all empty strings. If you're seeing the value as BuildConfig;->FLAVOR it may because that's also an empty string and the decompiler (JEB?) is making a best guess. It looks like the initializer with all of the password, port, etc. parameters is never called and those values only get set by calling setter methods from Lcom/ge/commonframework/xmlParsers/XMPPCredentialParserHandler;. The values appear to be pulled from an XML which isn't in the APK.

You might get a better understanding of what this app is doing by installing it and monitoring traffic. There are ways to disable cert pinning, both at the framework level and by modifying the app, and there are ways to monitor HTTPS traffic without cert pinning. I don't want to discuss the details of this process for any specific non-malware samples here though.

CalebFenton avatar Sep 12 '17 22:09 CalebFenton

thanks for your help! Ya I did SSL monitoring and they check for MITM so ya I'll have to figure a way to disable that. Closing issue since fixing this issue won't help me.

thehesiod avatar Sep 12 '17 23:09 thehesiod

If you don't mind, I'm going to leave this open since I have everything to repro and it's probably a legit bug.

CalebFenton avatar Sep 13 '17 02:09 CalebFenton

Also, to disable cert pinning, check out https://github.com/Fuzion24/JustTrustMe

CalebFenton avatar Sep 13 '17 03:09 CalebFenton

The problem is the Lc/x; class is an Enum with an unusual <init>. Enums normally have a <clinit> that assigns some literals to instance fields, e.g. this.MONDAY = "Monday". Smalivm doesn't handle instance members, so it does some simple analysis which looks for constant strings and then the next iput which sets the instance field. This works in most cases, but in this case there's a custom initializer.

A more general fix would be to somehow execute the <clinit> method, get the fields initialized, and then make the mapping between strings and field names from that. The current method could be used as a fallback if <clinit> execution fails.

I'm thinking this isn't a common problem, so I'm going to prioritize other fixes until something changes or there's nothing else to work on.

CalebFenton avatar Oct 11 '18 04:10 CalebFenton

Cool. Hopefully can get back to this soon. Right now in google API hell :)

thehesiod avatar Oct 11 '18 05:10 thehesiod