Mobile Hacking Lab - Cyclic Scanner Writeup

Hello, in today’s writeup, I will walk you through Cyclic Scanner lab MobileHackingLab.
In this lab we will explore how to analyze Android Services to find vulnerabilities. We will find a misconfiguration which will allow us to achieve Remote Code Execution (RCE) on an Android device.
To understand what services are in more details, you can explore it in Android Components Tutorial.
So, let’s start by downloading the .apk and running it in an Android emulator to get an overview of how the application works at runtime.
At first glance, it asks for permission to access all files on the system and then shows a switch button to enable/disable a scanner.
.png)

So, let’s move to static analysis and open the APK in JADX-GUI to analyze the source code.

We can see above that the application contains:
The following Permissions:
MANAGE_EXTERNAL_STORAGEpermission manages the access to files on the device’s external storage.INTERNTpermission gives your app permission to access the internet both Wi-Fi and mobile data.FOREGROUND_SERVICEpermission allows the app to run a service in the foreground.
And The Following Activities:
MainActivity, which is the first screen that appears in the app and is exported totrue.ScanService, a service which is exported asfalse.
Let’s move to MainActivity and analyze it.
The activity contains many UI implementations and the permission setup process, as we see at runtime.
I scrolled down until I found functions related to the switch button:

setupSwitch() Analysis:
It is used to check whether the button is checked or not. If checked, it starts the ScanService service.
setupSwitch$lambda$3() Analysis:
- It is used to perform an action based on the state change.
- If
isCheckedis true:- The scanning service is started using
startForegroundService(). - A Toast message containing the text
Scan service started, your device will be scanned regularly.is displayed.
- The scanning service is started using
- If
isCheckedis false:- A Toast message is displayed indicating that the scanning service cannot be stopped:
Scan service cannot be stopped, this is for your own safety!.
- A Toast message is displayed indicating that the scanning service cannot be stopped:
StartService() Analysis:
- A Toast message is displayed notifying the user that the scanning process has started:
Scan service started. - A foreground service named
ScanServiceis started. - The scanning process is started and runs continuously in the background without interruption.
Let’s navigate to ScanService service and check it:

First, we will check onStartCommand:
- Defines a message
- Check that the intent is not null
- Define notification to notify user that scan is started
We can navigate to handleMessage in the same file and see the following:

handleMessage Analysis:
- It checks that the message is not null.
- It prints
starting file scan.... - It gets the external storage directory
/sdcard/and checks that it is not null. - It checks whether it is a file and can be read.
- It prints the file path, then starts to scan it using
scanFile().
Move to ScanFile

ScanFile Analysis
- It checks that the file object is not null.
- It takes the file path and inserts it into the command
toybox sha1sum <File_Path>. - It passes the command variable to the
command()function directly without validation, which means the command will be executed as a system command. This indicates command injection and can lead to remote code execution. - It starts to read it and checks it is not null.
- The SHA1 hash value is read and compared with the list of known malware.
- If the hash is not in the list, the file is marked as
SAFE.
Our approach now is to achieve RCE by injecting a malicious filename; when the scanner reads the path, it will inject it into the command variable and execute it as a system command.
So, we need to create a file with a name that contains a system command: touch "; $(id) > rce.txt"

The final command will be:
toybox sha1sum; $(id) > rce"
And while the app scans the system files in /sdcard/ (external storage), it will see the file path and execute $(id) as a system command.

