吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 37918|回复: 67
收起左侧

[移动样本分析] 【双码锁机】对"卡Iphone7 plus永久在线"的逆向分析+加密源码

  [复制链接]
1595901624 发表于 2016-11-4 16:15
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 1595901624 于 2016-11-7 19:47 编辑

昨天,一位坛友,给我发消息,说有款锁机,让我看看,我看了一下,现在把分析过程与大家分享一下

I  首先认识一下这款软件

知彼知己,才能百战百胜,现在我们看看软件长啥样,如图(左为图标,右为锁屏界面):

1.JPG             2.JPG

随便输入密码,显示“输入不正确”





II  反编译


这反编译工具,我在这里有必要说明一下,许多坛友好像使用的是Android改之理或者AndroidKiller,但是我建议大家使用JEB,关于好处,
大家可以自己对比一下,我在这儿就不多说了。

我们看目录得知,锁屏界面对应的是MainActivity,定位到关键位置(因为这里有密码不正确)
3.JPG

从图中,可以看到,v3是获取编辑框的值,然后判断,v3和jb * 6如果不相等,就会显示密码错误,那么我们的密码就是jb*6;那么这jb是什么呢,我们网上找(如图)
4.JPG

发现是个随机数,那么,他就是锁屏界面的随机码,得知 随机码 * 6就是密码输入看看,对不对(我这里是39442 * 6 = 236652)



重点来了->锁机确实解开了,但是锁机软件还设置了pin码(如图),这锁机是双码锁机

5.JPG

我们再看目录,还有一个pin(也可以看一下manifest,入口Activiy是pin),那么这个就是pin码的锁机了


6.JPG

这个szmm()就是关键函数,划圈的就是设置密码的语句,所以我们现在就是吧pass这个变量作为重中之重,pass有个初始值6088,输入试试,
提示不对,但是,现在有些人可能输入6088会成功解锁,原因我后面再说【疑问一
10.JPG

我们看看这个szmm()是从哪调用来的,找到OnCreate()函数,这个函数相当于我们学各种语言的main()函数,当程序进入Activity时,会执行它
7.JPG

看这个OnCreate()函数:
红圈就是调用的地方,看上面
看蓝圈,特殊字符,乍一看是base64加密的,网页上找工具,解出是乱码,暂时先不管;
看青色的圈,decoder解密俩字符,一个赋值到pinm,一个赋值到url;
(这个解密函数在enorde类里面,这个类我稍后分析,暂时跳过)【疑问二
看绿圈,启动了一个线程,我们定位到这里,看看

8.JPG

线程里,又有个get(url),又把url传到get函数里面,再看get()函数

9.JPG

发现是联网获取数据,现在的锁机真实可怕啊,获取的什么数据(但是我们需要知道url)

【疑问一解答】这里是获取了网络上的锁机密码,但是如果当前APP没有联网,则会直接设置密码为6088,
这也就是为什么,有些人刚才输入6088,会解锁的原因

接着分析,这里调用了正则表达式,获取了网络上的密码,最后赋值给pass

11.JPG


因此,我们的重中之重是加解密函数


【疑问二解答】
加解密类是enorde,我就不上图了,作者采用的是Zlib+Base64回合加密,但是又在原来的基础上修改了,
加入了加密密钥,这款软件的加密密钥是“password”(加解密都需要用到它)
我试着还原了作者这个加解密函数,文章最后奉上源码的下载链接


解码之后的url是 http://www.wencaojun.top/in.html,网站截图如下


UC截图20161107194334.png
因为网页是gbk编码,要用utf8编码,否则会显示乱码,经过zhengze()函数之后,留下的就只有7593
因此7593就是当手机在网络良好状况下的锁机pin码








III  总结


软件双码加密,普通锁机密码是 随机码*6 ;在断网和网络不好的情况下,pin码是6088;
在网络良好的状况下,pin码【暂时是】7593——(作者可以更改网页内容,来修改锁机密码)


源码里面有加解密例子,在这里就不写例子了

IV 源码

最后公开【锁机中的Zlib + Base64】加解密源码

[Java] 纯文本查看 复制代码
import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

/**
 * 被修改的Zlib + Base64加解密算法
 * 
 * @author lhy 2016-11-03
 * @version 1.1.0.5
 *
 */
public class Enorde {
        private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
        private String key = ""; // 自定义加密的密钥

        /**
         * 初始化base64字符集表
         */
        private static byte[] codes = new byte[256];

        static {
                for (int i = 0; i < 256; i++)
                        codes[i] = -1;
                for (int i = 'A'; i <= 'Z'; i++)
                        codes[i] = (byte) (i - 'A');
                for (int i = 'a'; i <= 'z'; i++)
                        codes[i] = (byte) (26 + i - 'a');
                for (int i = '0'; i <= '9'; i++)
                        codes[i] = (byte) (52 + i - '0');
                codes['+'] = 62;
                codes['/'] = 63;
        }

        public Enorde(String key) {
                this.key = key;
        }

        /**
         * 被修改的 Zlib 压缩算法
         * 
         * @author lhy
         * @param str
         *            : 需要压缩的String数组
         * [url=home.php?mod=space&uid=155549]@Return[/url] 压缩之后的String数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
        public String encoder(String str) throws Exception {
                return new String(encoder(str.getBytes()));
        }
        
        /**
         * 被修改的 Zlib 解压缩算法
         * 
         * @author lhy
         * @param str
         *            : 需要解压缩的String数组
         * @return 解压缩之后的String数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
        public String decoder(String str) throws Exception {
                return new String(decoder(str.getBytes()));
        }

        /**
         * @author lhy
         * @param str
         *            : 需要编码成Base64的String数组
         * @return : 编码后的String数组
         */
        public String encodeToBase64(String str) {
                return new String(encodeToBase64(str.getBytes()));
        }

        /**
         * @author lhy
         * @param str
         *            : 需要解码Base64的String数组
         * @return : 解码后的String数组
         */
        public String decodeFromBase64(String str) {
                return new String(decodeFromBase64(str.getBytes()));
        }

        /**
         * @author lhy
         * @param byteArray
         *            : 需要编码成Base64的Byte数组
         * @return : 编码后的Byte数组
         */
        public byte[] encodeToBase64(byte[] byteArray) {
                byte[] b = new byte[(byteArray.length + 2) / 3 * 4];
                for (int i = 0, index = 0; i < byteArray.length; i += 3, index += 4) {
                        boolean quad = false;
                        boolean trip = false;
                        int val = (0xFF & (int) byteArray[i]);
                        val <<= 8;
                        if ((i + 1) < byteArray.length) {
                                val |= (0xFF & (int) byteArray[i + 1]);
                                trip = true;
                        }
                        val <<= 8;
                        if ((i + 2) < byteArray.length) {
                                val |= (0xFF & (int) byteArray[i + 2]);
                                quad = true;
                        }
                        b[index + 3] = (byte) alphabet[(quad ? (val & 0x3F) : 64)];
                        val >>= 6;
                        b[index + 2] = (byte) alphabet[(trip ? (val & 0x3F) : 64)];
                        val >>= 6;
                        b[index + 1] = (byte) alphabet[val & 0x3F];
                        val >>= 6;
                        b[index + 0] = (byte) alphabet[val & 0x3F];
                }
                return b;
        }

        /**
         * Base64解码
         * 
         * @author lhy
         * 
         * @param byteArray
         *            : 需要解码的Base64的Byte数组
         * @return : 解码后的Byte数组
         */
        public byte[] decodeFromBase64(byte[] byteArray) {
                int length = (byteArray.length + 3) / 4 * 3;
                if (byteArray.length > 0 && byteArray[byteArray.length - 1] == '=') {
                        --length;
                }

                if (byteArray.length > 1 && byteArray[byteArray.length - 2] == '=') {
                        --length;
                }

                byte[] b = new byte[length];
                int shift = 0;
                int accum = 0;
                int index = 0;
                for (int ix = 0; ix < byteArray.length; ix++) {
                        int value = codes[byteArray[ix] & 0xFF];
                        if (value >= 0) {
                                accum <<= 6;
                                shift += 6;
                                accum |= value;
                                if (shift >= 8) {
                                        shift -= 8;
                                        b[index++] = (byte) ((accum >> shift) & 0xff);
                                }
                        }
                }

                try {
                        if (index == b.length) {
                                return b;
                        }
                } catch (Exception e) {
                        System.err.println("miscalculated data length!");
                }

                return b;
        }

        /**
         * 被修改的 Zlib 解压缩算法
         * 
         * @author lhy
         * @param byteArray
         *            : 需要解压缩的byte数组
         * @return 解压缩之后的数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
        public byte[] decoder(byte[] byteArray) throws Exception {
                Enorde e = new Enorde(key);
                if (byteArray == null) {
                        throw new Exception("Data error!");
                }

                byteArray = e.decodeFromBase64(byteArray);
                if (!key.equals("")) {
                        for (int i = 0; i < byteArray.length; ++i) {
                                byte[] keyByte = key.getBytes();
                                byteArray[i] = ((byte) (((char) (byteArray[i] ^ keyByte[i % keyByte.length]))));
                        }
                }
                Inflater in = new Inflater();
                in.reset();
                in.setInput(byteArray);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                byte[] b = new byte[1024];
                while (!in.finished()) {
                        bos.write(b, 0, in.inflate(b));
                }

                return bos.toByteArray();
        }

        /**
         * 被修改的 Zlib 压缩算法
         * 
         * @author lhy
         * @param byteArray
         *            : 需要压缩的byte数组
         * @return 压缩之后的数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
        public byte[] encoder(byte[] byteArray) throws Exception {
                Enorde e = new Enorde(key);
                if (byteArray == null) {
                        throw new Exception("Data error");
                }

                Deflater df = new Deflater();
                df.reset();
                df.setInput(byteArray);
                df.finish();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                byte[] b = new byte[1024];
                while (!df.finished()) {
                        bos.write(b, 0, df.deflate(b));
                }

                byte[] bosArray = bos.toByteArray();
                if (!key.equals("")) {
                        for (int i = 0; i < bosArray.length; ++i) {
                                byte[] keyByte = key.getBytes();
                                bosArray[i] = ((byte) (((char) (bosArray[i] ^ keyByte[i % keyByte.length]))));
                        }
                }

                return e.encodeToBase64(bosArray);
        }
}



锁机APK+加解密源码
土豪下载通道: 卡Iphone7plus在线.rar (944.87 KB, 下载次数: 181)   解压密码:52pojie
屌丝下载通道:链接:https://eyun.baidu.com/s/3pLo5y8j 密码:6666


免费评分

参与人数 42威望 +2 吾爱币 +9 热心值 +41 收起 理由
快乐交友 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
jiyisa + 1 + 1 用心讨论,共获提升!
c4951491235 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wangzhe10 + 1 + 1 我很赞同!
suadzh + 1 + 1 已答复!
若即若离 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
MXWXZ + 1 + 1 我很赞同!
也曾有过梦想 + 1 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
时光机任意门 + 1 + 1 我很赞同!
我要笑 + 1 谢谢@Thanks!
Valkyrie-Madoka + 1 我很赞同!
孤胆枪手 + 1 鼓励转贴优秀软件安全工具和文档!
Anonyomus + 1 谢谢!如此详细的分析小白也长知识了!
晓白同学 + 1 鼓励转贴优秀软件安全工具和文档!
lawlier + 1 我很赞同!
China-小豪 + 1 谢谢@Thanks!
rmvbrmb + 1 我很赞同!
夏夜X回忆 + 1 用心讨论,共获提升!
GG0 + 1 我很赞同!
pass101 + 1 谢谢@Thanks!
我为笔狂 + 1 用心讨论,共获提升!
最黑不过阿宝 + 1 6666666666
Hmily + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
www.52pojie.cn + 1 鼓励转贴优秀软件安全工具和文档!
lpdswing + 1 很详细,适合小白学习
庄澄 + 1 详细具体
Sp4ce + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
迷失丶泪 + 1 腻害,大神
1369452145 + 1 用心讨论,共获提升!
SumMer丶 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hack523 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
尼霸Rc_ + 1 感谢大神技术贴
性野丶 + 1 用心讨论,共获提升!
三日月宗近 + 1 谢谢@Thanks!
zxc1164428120 + 1 用心讨论,共获提升!
120001215 + 1 用心讨论,共获提升!
绍离 + 1 最近也是锁机横行,需要这样的技术贴
懒惰的上帝 + 1 挺有味道的
huang0817 + 1 谢谢@Thanks!
雅熙; + 1 厉害了word哥,虽然我看不懂,我还是看完了。
慢慢的拼凑 + 1 用心讨论,共获提升!
55555555 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

1343450392 发表于 2017-1-25 23:14
http://pan.baidu.com/s/1slfcxsT   大神求破这个锁机软件   作者说很牛逼  模拟器都不能开了     我QQ邮箱1343450392@qq.com    求大神破解
 楼主| 1595901624 发表于 2016-11-7 19:35
Hmily 发表于 2016-11-7 19:16
@1595901624 附件样本压缩包上传时必须使用压缩密码保护,压缩密码:52pojie,防止下载样本的时候被杀软拦截 ...

知道了,H大,现在马上改
505547425 发表于 2016-11-4 16:29
iloveheaven 发表于 2016-11-4 16:29
我其实可想直接把第一张图里的
v0.tv1.setText("密码不正确"); 改成 v0.finish();
融化的泪记忆中 发表于 2016-11-4 16:30
厉害啊就是!
iloveheaven 发表于 2016-11-4 16:30

Java.
adadcc 发表于 2016-11-4 16:32
楼主好厉害呀
ShadowY 发表于 2016-11-4 16:32
楼主这不是广告吗?
55555555 发表于 2016-11-4 16:33
这个锁机app比较厉害貌似
有梦人 发表于 2016-11-4 16:38
NB大神....
老衲法号小甜甜 发表于 2016-11-4 16:41
威武霸气,谢谢楼主
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 11:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表