FotaProvider.apk — Arbitrary Command Execution

This is an exercise from Maddiestone’s “Android Reverse Engineering 101” workshop.
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="android.uid.system" android:versionCode="220" android:versionName="2.2.0" package="com.adups.fota.sysoper">
android:sharedUserId="android.uid.system"
At first, we see a major issue on the App. The App shares the same userId as the system. Meaning it can execute all of its functionalities with system privileges. Potentially harmful.

Another potentially vulnerability. All those App Components have the exported parameter defined as “true”. Meaning we can execute system services and app services by calling it from an outsider intent.
App components that contain an <intent-filter> tag are set with the exported=”true” by default.
Java Classes
com.adups.fota.sysoper.SysService
Let’s take a look at the first service we encountered.
m2a

The function may have something to do with command line, receiving a string as a parameter, calling “m3a” and spliting that string into an StringArray.
m3a

Unfortunately there was a decompiling error, but it wont keep us from reversing it.
This function is very interesting. First we assign “r3” a new ProcessBuilder (which is one of the functions that make system execution of commands), then we initiate that process with the StringArray returned from m2a.
But as it seems interesting, that whole class isn’t the vulnerability itself (even though it is quite a bit suspicious). Let’s keep diving on the APK.
com.adups.fota.sysoper.WriteCommandReceiver
Now that we have encountered a possible command exec function, we can search for another usage of this function.

We found an usage in the WriteCommandReceiver class, which we discussed before as a possible vulnerable function (because it was exported).

Here we see the same pattern as the previous function, we create a ProcessBuilder that receives a StringArray and then execute every single command on the String.
We can confirm that by checking the onReceive function:

In this function, if we call the Broadcast Receiver with the WriteCommandReceiver “reason” (action.equalsIgnoreCase), it downloads a package (I didn’t extended my analysis into that), but if we call with operReceiver “reason”, we can execute an arbitrary command injection!