Amidst my usual adventure with Android malware analysis, I saw this snippet of code while skimming through a particular sample's class modules.
Late last year, I was looking deeper into the Portable Network Graphics (PNG) image format, especially the fields that hold textual information. Upon seeing the code, it immediately triggered my suspicion as to why would the application need to check for the existence of the "tEXt" chunk of a PNG file.
I continued to glance through the code and found out where this particular code gets called to identify the image file of interest.
This part of the code tells that the file of interest uses the resource name "icon.png" and is bundled with the application. The image would then be opened and passed to the method where the code that checks for the PNG chunk (Figure 1) is called.
Inspection of the APK package's resources yields three files with similar name. Since it is only interested in the first occurrence of the tEXt chunk, I quickly pulled out a hex viewer and inspected the first tEXt chunk in every file. They all contain the same binary data for that specific chunk. Here is how the image appears when rendered as well as its internal representation in a hex viewer.
This image is also used as the application's icon, therefore, it would be very visible during and after its installation on a device.
As of this moment, the data in Figure 3 made little sense to me but it is also not normal for the tEXt chunk to have a binary data or unreadable string, so I continued to analyze the rest of the code in Figure 1. Further analysis revealed that it reads the hidden data in Figure 3 and performs XOR bitwise operation against a hardcoded text streams (the "key") for each and every byte read.
I am more of a Python person so I created this small script to decode the hidden information from Figure 3, which algorithm is based on what I understood with the rest of the code in Figure 5. After executing the script (Figure 6.a), and to my surprise, I saw some readable English words and numbers!
While it still doesn't give a clear picture of what those plain text information signify to the application, at this point I figured out that it employs steganography to hide these data (Figure 6.b) from within the tEXt chunk data of the PNG file (Figure 3). Looking at the strict definition of steganography though, it's debatable whether this sample would really be considered steganographic, since it is just a simple embedding of encoded data in one of the chunks of the PNG file.
Continuing with the analysis of the rest of the code in Figure 5, it further strengthens the fact that those hidden information (partial screenshot shown below) are used to support the main motive of the application (i.e., sending SMS to premium numbers).
In addition to discovering the code above, I've also run the application on an Android device emulator to verify that it is indeed using those information for the SMS sending operation. And here it shows that an outgoing SMS event was captured with details similar to the decoded data in Figure 6.b (except for the last four digits of the "Message" below). The event happened as soon as I hit the "Next" button from the main UI of the newly installed application.