吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 38708|回复: 118
收起左侧

[Android 原创] 2014某比赛apk逆向分析

  [复制链接]
JoyChou 发表于 2014-7-28 22:55
本帖最后由 JoyChou 于 2014-7-29 17:11 编辑

原文链接:点我

博客:www.joychou.org
邮箱:shellcode@joychou.org
作者:JoyChou

apk没什么其他保护,直接看smali和java代码。

0x1. 关键位置
很明显看到一个关键比较,经过对程序分析,要想得到str6,就必须得知道str5。要想得到str5就必须得知道str4,不过MainActivity.b(this.a).getText().toString().substring(2, 9);  的getText的内容是已知的,为ccfd02dec871e41eae537f6bdc755441。最后要想知道str4,就必须得对8374207E83372393B9B8964F6D7415E7F88FC24BDD1B2201A924C8723A3AE668FCDF7BFFB7EFD4AA1E64832345264B7FF99A2D145A8D1FB4解密。分析到此over,很简单的一个流程。
[Java] 纯文本查看 复制代码
  public void onClick(View paramView)
  {
    String str1 = MainActivity.a(this.a).getDeviceId();
    String str2 = MainActivity.a(this.a).getSubscriberId();
    String str3 = MainActivity.a(this.a).getSimSerialNumber();
    String str4 = str1 + "@" + str2 + "@" + str3;
    try
    {
      if ("8374207E83372393B9B8964F6D7415E7F88FC24BDD1B2201A924C8723A3AE668FCDF7BFFB7EFD4AA1E64832345264B7FF99A2D145A8D1FB4".equals(b.a(str4)))
      {
        String str5 = str4.toString().substring(10, 19) + MainActivity.b(this.a).getText().toString().substring(2, 9);
        String str6 = com.wow.dbm.a.a.a(a("439288a71bb2b74c077f0237f21d8696053d60f2ada12cbbc18406808d2fb34d7e94ebb575949bf9e25a304051a385f8"), str5);
        Toast.makeText(this.a.getApplicationContext(), "快抄下来!" + str6, 1).show();
        Log.d("dbi_AES_De_n", str6);
        return;
      }
      Toast.makeText(this.a.getApplicationContext(), "身份校验失败,请使用预设手机!", 0).show();
      return;
    }
    catch (Exception localException)
    {
      Toast.makeText(this.a.getApplicationContext(), "解密失败!", 0).show();
    }
  }
}

0x2. 怎样解密

如果直接修改smali会发现不好操作。那就写java代码。
分析下des的加密过程:
Plain_Text进行des加密成byte类型,再转换成16进制字符串。(其实相当于,des加密成byte类型后,转换为String不一定是规则的ascii,所以为了字符能够显示,最好人为进行一个编码,平时一般用base64,这里只是转化成了16进制的字符串)。
比如des加密后的字节的16进制为0x12, 0x34,那最后的结果为"1234"字符串。
所以解密的时候,要先将16进制的字符串转换为byte类型,再进行des解密。
比如"1234"字符串,转换为0x12, 0x34的byte数组,再进行des解密。

Tips:在看java算法代码的时候,如果对代码不是很熟悉,一般把代码比较有特征的部分进行百度,就能够看出这段算法代码的功能。

将8374207E83372393B9B8964F6D7415E7F88FC24BDD1B2201A924C8723A3AE668FCDF7BFFB7EFD4AA1E64832345264B7FF99A2D145A8D1FB4转化成字节的形式,可以写java代码转,或者用py转,我这里写了一个py

[Python] 纯文本查看 复制代码
#coding:utf-8
def Add_Something(c):
    n = ""


    while c:
        f = c[0:2]
        n += "(byte)0x" + f + ','
        c = c[2:]

    return n

if __name__ == '__main__':

    fp = open('1.txt', 'wb')
    str = Add_Something('8374207E83372393B9B8964F6D7415E7F88FC24BDD1B2201A924C8723A3AE668FCDF7BFFB7EFD4AA1E64832345264B7FF99A2D145A8D1FB4')
    fp.write(str)
    fp.close();


解密代码为:
Main.java
[Java] 纯文本查看 复制代码
byte[] des_encode = {(byte)0x83,(byte)0x74,(byte)0x20,(byte)0x7E,(byte)0x83,(byte)0x37,(byte)0x23,(byte)0x93,(byte)0xB9,(byte)0xB8,(byte)0x96,(byte)0x4F,(byte)0x6D,(byte)0x74,(byte)0x15,(byte)0xE7,(byte)0xF8,(byte)0x8F,(byte)0xC2,(byte)0x4B,(byte)0xDD,(byte)0x1B,(byte)0x22,(byte)0x01,(byte)0xA9,(byte)0x24,(byte)0xC8,(byte)0x72,(byte)0x3A,(byte)0x3A,(byte)0xE6,(byte)0x68,(byte)0xFC,(byte)0xDF,(byte)0x7B,(byte)0xFF,(byte)0xB7,(byte)0xEF,(byte)0xD4,(byte)0xAA,(byte)0x1E,(byte)0x64,(byte)0x83,(byte)0x23,(byte)0x45,(byte)0x26,(byte)0x4B,(byte)0x7F,(byte)0xF9,(byte)0x9A,(byte)0x2D,(byte)0x14,(byte)0x5A,(byte)0x8D,(byte)0x1F,(byte)0xB4};

String des_result = b.a_decry(des_encode);
System.out.println(des_result);

b.java
[Java] 纯文本查看 复制代码
package Test;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class b
{
//整个加密流程为,加密的字符串先加成
public static String a(String paramString)
  {

    try{
         DESedeKeySpec localDESedeKeySpec = new DESedeKeySpec("ebcd3c24a64c2e056f430d11".getBytes());
            SecretKey localSecretKey = SecretKeyFactory.getInstance("desede").generateSecret(localDESedeKeySpec);
            Cipher localCipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
            localCipher.init(Cipher.ENCRYPT_MODE, localSecretKey, new IvParameterSpec("01234567".getBytes()));
            return a(localCipher.doFinal(paramString.getBytes("utf-8")));

            //return localCipher.doFinal(paramString.getBytes());

    }


    catch(Exception e){
        System.out.println("exception_jc");
         e.printStackTrace();
    }

    return null;

  }

  // 作用:将字符串123转换为字符串313233
  // 可以动态调用a("123".getBytes())
  public static String a(byte[] paramArrayOfByte)
  {
    if (paramArrayOfByte == null)
      return "";
    StringBuffer localStringBuffer = new StringBuffer(2 * paramArrayOfByte.length);
    for (int i = 0; ; i++)
    {
      if (i >= paramArrayOfByte.length)
        return localStringBuffer.toString();
      a(localStringBuffer, paramArrayOfByte);
    }
  }
  private static void a(StringBuffer paramStringBuffer, byte paramByte)
  {
    paramStringBuffer.append("0123456789ABCDEF".charAt(0xF & paramByte >> 4)).append("0123456789ABCDEF".charAt(paramByte & 0xF));
  }
 public static String a_decry(byte[] paramString)
  {
    try{
         DESedeKeySpec localDESedeKeySpec =
                 new DESedeKeySpec("ebcd3c24a64c2e056f430d11".getBytes());
            SecretKey localSecretKey = 
                    SecretKeyFactory.getInstance("desede").generateSecret(localDESedeKeySpec);
            Cipher localCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            localCipher.init(Cipher.DECRYPT_MODE, localSecretKey, new IvParameterSpec("01234567".getBytes()));
            //return a(localCipher.doFinal(paramString));
           byte[] decry_data = localCipher.doFinal(paramString);
            return new String(decry_data);
    }



    catch(Exception e){
        System.out.println("exception_jc");
         e.printStackTrace();
    }


    return null;

  }


 }
结果为A00000381F8F05@460030767299044@89860313100281802653

搞定掉DES,接下来是AES,由于在java中并没有AES/ECB/ZeroBytePadding这种AES加密,在android有,所以不能用java代码来解,这里纠结了很久。

那就改smali吧。
[Java] 纯文本查看 复制代码
if("8374207E83372393B9B8964F6D7415E7F88FC24BDD1B2201A924C8723A3AE668FCDF7BFFB7EFD4AA1E64832345264B7FF99A2D145A8D1FB4".equals(b.a(str4)))
      {
        String str5 = str4.toString().substring(10, 19) + MainActivity.b(this.a).getText().toString().substring(2, 9);
        String str6 = com.wow.dbm.a.a.a(a("439288a71bb2b74c077f0237f21d8696053d60f2ada12cbbc18406808d2fb34d7e94ebb575949bf9e25a304051a385f8"), str5);
        Toast.makeText(this.a.getApplicationContext(), "快抄下来!" + str6, 1).show();
        Log.d("dbi_AES_De_n", str6);
        return;
      }


只需要将str5改为正确的值即可解密出来,还是用上面的java代码,得到str5为8F05@4600fd02dec,作为AES解密的密钥key,128个bytes。

修改smali的地方:

198行, if-nez v0, :cond_0 #change 1 原始为:if-eqz
118行,.locals 7 原始为.locals6
256行,改为

[Asm] 纯文本查看 复制代码
  move-result-object v1
  const-string v6, "8F05@4600fd02dec" 
  invoke-static {v1, v6}, Lcom/wow/dbm/a/a;->a([BLjava/lang/String;)Ljava/lang/String;

最后打包,运行,即可看到flag,
11.jpg

或者adb logcat -s
21.png

0x3. 总结

这题的关键就是逆向解密,最基本的思想。

假设对字符串A加密:经过md5加密,再经过base64加密。
那解密为:先base64解密,再md5解密。

就是这样最基本的思想就可以解决这题了。


附件: DBM_OUT_0910.7z (69.33 KB, 下载次数: 56)

免费评分

参与人数 7热心值 +7 收起 理由
abmin521 + 1 谢谢@Thanks!
runner + 1 谢谢@Thanks!
sivycoffee + 1 已经处理,感谢您对吾爱破解论坛的支持!
小野 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
cjl498 + 1 谢谢@Thanks!
无邪 + 1 学习到了!安卓逆向一直是空白..
H2o + 1 我是来抱大腿的

查看全部评分

本帖被以下淘专辑推荐:

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

H2o 发表于 2014-7-28 23:12
我是来抱大腿的
七情哥哥 发表于 2014-7-28 23:07
hejie821 发表于 2014-7-28 23:00
索马里的海贼 发表于 2014-7-28 22:58
分析的很详细 学习一下。
小生是书痴 发表于 2014-7-29 00:21
。。我是来请楼主吃麻辣烫的

你们谁都别劝我!
阿萨德22 发表于 2014-7-29 08:41

分析的很详细 学习一下。
小河水 发表于 2014-7-29 13:14
学习一下
924410377 发表于 2014-7-29 13:25 来自手机
额。。。看不懂
博波世界 发表于 2014-7-29 13:38 来自手机
表示看不懂。。。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-3-19 12:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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