Android下恶意代码隐藏的一种方式

一、背景

在Android操作系统中,APK文件是一个包含多种普通文件和可执行文件的ZIP格式文件。在一个正常的APK文件中,其压缩的根目录下会包含一个名为classes.dex的DEX可执行文件,并且可能在lib目录下包含一个或多个ELF格式的动态链接库文件。如果在这个APK文件中,在其他位置还包含其他的APK、DEX或ELF格式的可执行文件或动态链接库文件,我们称之为出现了异常的可执行文件。

安全软件在检测恶意代码的时候,不仅会对APK,classes.dex以及相关动态链接库文件的特征进行匹配检测,并且同时会对APK中异常的可执行文件特征进行检测。

这里以egdata家族的样本为例,介绍其采用的一种对异常的可执行文件的隐藏方式,来逃避安全软件对相关恶意代码文件的检测,并增加检出的难度。

二、篡改的万年历 — egdata.a

样本egdata.a是一个被攻击者篡改并重新打包过的万年历应用,在运行时会提示程序更新,但是由于签名不同,更新会失败。

图 1 egdata.a运行截图

图1 egdata.a运行截图

对样本的APK文件结构和官方应用的结构进行比较,发现样本在/assets目录下多了一个eg.data文件,对eg.data的文件头部内容进行识别发现开始2个字节为PK,进行解压,其根目录下包含AndroidManifest.xml,classes.dex,为标准的APK文件。

图 2 egdata.a(左)和官方应用(右)APK结构对比

图2 egdata.a(左)和官方应用(右)APK结构对比

图 3eg.data文件内容

图3 eg.data文件内容

通过对样本APK的分析,其在类com.android.commond.Egrecvol中的createSingleInstall()方法实现了从/assets中提取eg.data。

InputStream v6 = Egrecvol.context.getAssets().open(“eg.data”);
FileOutputStream v7 = new FileOutputStream(this.fJar);
Egrecvol.Log(“eg.data len=” + v6.available());
while (true) {
v1 = new byte[1024];
v9 = v6.read(v1);
if (v9 > 0) {
goto lable_142;
}
break;
lable_142:
v7.write(v1, 0, v9);
}
v6.close();
v7.close();

释放eg.data后,使用动态的方式调用所需的代码,方式如下:

使用DexClassLoader动态加载释放的eg.data文件,返回ClassLoader;
调用loadClass方法加载关键类,这里加载的类“com.suntu.engine3.engine.Main1”;
获取该类的Constructor
调用newInstance创建类,并初始化,至此恶意代码被彻底调用起来

当eg.data这个APK文件被动态加载执行后,它会执行自身的com.suntu.engine3.engine.jni.JNIEngine类下的realeseFile()方法释放一个.so的本地动态链接库文件。这个被释放文件的实际内容以byte数组的形式存储在Java代码中。

以下是这个数组的一个片段:

static
{
byte[] arrayOfByte = new byte[5556];
arrayOfByte[0] = 127;
arrayOfByte[1] = 69;
arrayOfByte[2] = 76;
arrayOfByte[3] = 70;
arrayOfByte[4] = 1;
arrayOfByte[5] = 1;
arrayOfByte[6] = 1;
arrayOfByte[16] = 3;
arrayOfByte[18] = 40;
arrayOfByte[20] = 1;
arrayOfByte[24] = -116;
arrayOfByte[25] = 9;
arrayOfByte[28] = 52;
arrayOfByte[32] = 12;
arrayOfByte[33] = 19;
arrayOfByte[36] = 2;
arrayOfByte[39] = 5;
arrayOfByte[40] = 52;
arrayOfByte[42] = 32;
arrayOfByte[44] = 5;
arrayOfByte[46] = 40;
arrayOfByte[48] = 17;
arrayOfByte[50] = 16;
arrayOfByte[52] = 1;
arrayOfByte[55] = 112;
arrayOfByte[56] = -72;
arrayOfByte[57] = 16;
arrayOfByte[60] = -72;
arrayOfByte[61] = 16;
arrayOfByte[64] = -72;
arrayOfByte[65] = 16;
arrayOfByte[68] = 72;
arrayOfByte[72] = 72;
arrayOfByte[76] = 4;
arrayOfByte[80] = 4;
arrayOfByte[84] = 1;
arrayOfByte[101] = 17;

在这个样本中,依旧采用了常规的添加异常的APK文件并动态加载的方式[1],但是通过在代码中存储.so动态链接库文件内容的方式实现对异常的动态链接库文件的隐藏。

三、被感染的酷我音乐 — 变种egdata.c

变种egdata.c是一个被攻击者篡改的酷我音乐应用【2】,其采用了更加隐蔽的方式来隐藏包含有恶意代码的APK文件,从而来增加安全软件对其特征提取和识别的难度。

其APK文件结构如下所示。

图 4 egdata.c APK结构

图4 egdata.c APK结构

在/assets目录下有两个jpg图片文件emg.jpg,wkag.jpg,其中emg.jpg不能正常显示为图片。在变种APK的cn.kuwo.player.MainActivityyb类中的releaseClassData()方法实现从wkag.jpg文件中提取APK文件并动态加载。这里是从wkag.jpg文件的1024字节偏移处开始到文件最后为隐藏的APK文件内容,并且每个字节做了减一变换。