安卓渗透第三弹-Apk反编译分析加密编写自动化解密脚本

科技   2024-10-31 09:56   江苏  

0x01 前言

有时候在对APP抓包的时候,经常会遇到参数加密,app也不像web端一样,可以直接打断点进行调试,找到加密方法, 在app没有加壳的情况下,我们可以反编译找加密点,或者是动态调试,这里使用反编译的方法。

0x02 正文

在登陆处点击登录,然后抓包,具体环境配置教程以及抓包教程可以看前两篇文章,可以看到账号密码被加密了,这时候如果apk没有加壳的话,我们可以使用JADX进行反编译

因为抓包的时候,路由是/user/login,我们反编译apk后,直接搜索这个

基本可以确定就是从这里发起网络请求
跟进addRequestMap方法分析

这一看逻辑就清晰了
先添加一个时间戳,在对sign进行加密后在调用encodeDesMap进行加密
最后put到请求中
在分析encodeDesMap

有KEY和IV,不是AES就是DES加密
encrypt64

DES加密后在Base64加密
那么data就是明文了,hook这个方法取到参数

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

let RequestUtil = Java.use("com.xxx.xxx.http.RequestUtil");
RequestUtil["encodeDesMap"].overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function (data, desKey, desIV) {
console.log("**********获取DES明文**********");
console.log(`参数明文----> ${data}, desKey= ${desKey}, desIV= ${desIV}`);
let result = this["encodeDesMap"](data, desKey, desIV);
console.log(`参数加密结果----> ${result}`);
return result;
};

与抓包结果一样,这样明文就拿到了。
sign分析,回到刚刚那个传递sign参数的那个函数

字符串最后拼接了一个key后在进行md5加密,
hook一下md5这个函数

很明显,拼接除了sign参数其余全部在添加一个key=sdlkjsdljf0j2fsjk 的最终字符串在进行md5加密。
这样sign与参数加密都分析完了。
再使用java模拟加密过程,反写解密就OK了。

package APP;//import android.util.Base64;  import java.net.URLEncoder;  import java.nio.charset.StandardCharsets;  import java.security.MessageDigest;  import java.util.*;  import java.util.stream.Collectors;  import javax.crypto.Cipher;  import javax.crypto.SecretKey;  import javax.crypto.SecretKeyFactory;  import javax.crypto.spec.DESKeySpec;  import javax.crypto.spec.IvParameterSpec;    /* loaded from: classes.dex */  public class DuDu {      Cipher deCipher;      Cipher enCipher;        public DuDu(String key, String iv) throws Exception {          if (key == null) {              throw new NullPointerException("Parameter is null!");          }          InitCipher(key.getBytes(), iv.getBytes());      }        private void InitCipher(byte[] secKey, byte[] secIv) throws Exception {          MessageDigest md = MessageDigest.getInstance("MD5");          md.update(secKey);          DESKeySpec dsk = new DESKeySpec(md.digest());          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");          SecretKey key = keyFactory.generateSecret(dsk);          IvParameterSpec iv = new IvParameterSpec(secIv);          this.enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");          this.deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");          this.enCipher.init(1, key, iv);          this.deCipher.init(2, key, iv);      }        public String encrypt64(byte[] data) throws Exception {          byte[] encryptedBytes = this.enCipher.doFinal(data);          return Base64.getEncoder().encodeToString(encryptedBytes);      }        public byte[] decrypt64(String data) throws Exception {          return this.deCipher.doFinal(Base64.getDecoder().decode(data));      }        public String sign(String data) throws Exception {          String append = "sdlkjsdljf0j2fsjk";            // 将 JSON 字符串转换为 Map        Map<String, String> paramMap = Arrays.stream(data.replace("{", "").replace("}", "").split(","))                  .map(pair -> pair.split(":"))                  .collect(Collectors.toMap(                          kv -> kv[0].trim().replace("\"", ""),                          kv -> kv[1].trim().replace("\"", "")                  ));            // 对 Map 中的键进行排序          List<String> keys = new ArrayList<>(paramMap.keySet());          Collections.sort(keys);            // 拼接参数字符串          String paramStr = keys.stream()                  .filter(key -> !"sign".equals(key))                  .map(key -> {                      return key + "=" + URLEncoder.encode(paramMap.get(key), StandardCharsets.UTF_8);                  })                  .collect(Collectors.joining("&")) + "&key=" + URLEncoder.encode(append, StandardCharsets.UTF_8);            System.out.println("sign明文:" + paramStr);          // 对拼接后的参数字符串进行 MD5 加密          MessageDigest md = MessageDigest.getInstance("MD5");          byte[] digest = md.digest(paramStr.getBytes(StandardCharsets.UTF_8));          StringBuilder hexString = new StringBuilder();            for (byte b : digest) {              String hex = Integer.toHexString(0xFF & b);              if (hex.length() == 1) {                  hexString.append('0');              }              hexString.append(hex);          }            return hexString.toString().toUpperCase();      }      public static void main(String[] args) throws Exception {          DuDu du = new DuDu("65102933","32028092");                    String enc = "";          String decryptedString = new String(du.decrypt64(enc));          System.out.println("明文:" + decryptedString);            System.out.println("sign密文:" + du.sign(decryptedString));      }  }
Frida hook脚本
function duduhook() {    Java.perform(function () {        let RequestUtil = Java.use("com.xxx.xxx.http.RequestUtil");        RequestUtil["encodeDesMap"].overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function (data, desKey, desIV) {            console.log("**********获取DES明文**********");            console.log(`参数明文----> ${data}, desKey= ${desKey}, desIV= ${desIV}`);            let result = this["encodeDesMap"](data, desKey, desIV);            console.log(`参数加密结果----> ${result}`);            return result;        };
let Utils = Java.use("com.xxx.xxx.util.Utils"); Utils["md5"].implementation = function (string) { console.log("**********获取SIGN明文**********"); console.log(`SIGN明文----> ${string}`); let result = this["md5"](string); console.log(`MD5加密结果----> ${result}`); return result; };

let RequestUtil1 = Java.use("com.xxx.xxx.http.RequestUtil"); RequestUtil1["paraMap"].overload('java.util.Map', 'java.lang.String', 'java.lang.String').implementation = function (addMap, append, sign) { console.log(`RequestUtil.paraMap is called: addMap=${addMap}, append=${append}, sign=${sign}`); let result = this["paraMap"](addMap, append, sign); console.log(`RequestUtil.paraMap result=${result}`); return result; }; });}

setImmediate(duduhook);
效果如下:

0x03 文末

工具下载

本文所涉及的工具,均打包网盘,后台回复“安卓渗透”即可获取。


实习/校招/社招



长期持续内推长亭、360、绿盟等安全大厂,已累计内推2000+人
长亭科技25校招投递链接:https://join.chaitin.cn/campus 
内推码:NTAWkpg
或微信扫码投递

25校招持续内推中~~~明年毕业的同学欢迎加我,1对1简历辅导,全程跟踪内推情况

安全服务工程师、安全攻防工程师、安全研发工程师、前后端开发工程师、测试工程师等等,所有岗位均可内推




内推|长亭科技2024届秋招开启,附内推码~


你能拿她学校的shell,但永远拿不了她的shell


渗透实战|记一次简单的Docker逃逸+反编译jar接管云主机


渗透实战|NPS反制之绕过登陆验证


渗透实战|记一次曲折的EDU通杀漏洞挖掘


渗透实战|记一次RCE+heapdump信息泄露引发的血案


免责声明
由于传播、利用本公众号藏剑安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号藏剑安全及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
好文分享收藏赞一下最美点在看哦

藏剑安全
知识面决定攻击面
 最新文章