App逆向案例 X嘟牛 – Frida监听 & WT-JS工具还原(一)


提示:文章仅供参考,禁止用于非法途径;

文章目录

  • App逆向案例 X嘟牛 – Frida监听 & WT-JS工具还原(一)
  • 前言
  • 一、资源推荐
  • 二、App抓包分析
  • 三、反编译逆向分析
  • 四、还原JS加密
    • 1.Hook示例代码
    • 2.JS还原
  • 五、python登录实现代码
    • 1.python示例代码
    • 2.python运行结果
  • 总结

前言

该文章使用了Frida、JDAX-GUI、Charles、夜神模拟器、WT-JS等工具;
主要编程语言:Python,部分涉及到:JavaScript、Java;


提示:以下是本篇文章正文内容,下面案例可供参考

一、资源推荐

Frida – App逆向 概念介绍:https://blog.csdn.net/EXIxiaozhou/article/details/128112421
安装抓包工具以及模拟器 App抓包:https://blog.csdn.net/EXIxiaozhou/article/details/127767808
JS逆向 Frida – 夜神模拟器安装配置 基本使用:https://blog.csdn.net/EXIxiaozhou/article/details/128035059
ApkScan-PKID 查壳工具下载:https://blog.csdn.net/EXIxiaozhou/article/details/127196615
Frida-Dexdump 脱壳工具下载使用:https://blog.csdn.net/EXIxiaozhou/article/details/128208068
JDAX-GUI 反编译工具下载:https://blog.csdn.net/EXIxiaozhou/article/details/127207762
JS逆向加密解密工具 下载使用:https://blog.csdn.net/EXIxiaozhou/article/details/128034062
X嘟牛Apk下载:https://pan.baidu.com/s/1HMxGZx9m8QZwAZSZPBiHwQ?pwd=m1qk
示例代码下载:https://pan.baidu.com/s/1rfFBzLeMQgKaajyUIhCb9Q?pwd=ad7i#list/path=%2F

二、App抓包分析

1、打开Charles、夜神模拟器,开始App抓包;
2、登录接口的url:http://api.dodovip.com/api/user/login

三、反编译逆向分析

提示:可以把反编译的Java代码,复制到IDEA分析运行,这样会提高逆向的效率;
加密参数的关键词:“Encrypt”,点击”转到”来到加密代码处


MD5加密生成sign参数,public static String paraMap(Map addMap, String append, String sign)

DES加密生成encrypt,public static String encodeDesMap(String data, String desKey, String desIV)

四、还原JS加密

1.Hook示例代码

import fridaimport sysdef on_message(message, data):    if message['type'] == 'send':        print("[*] {0}".format(message['payload']))    else:        print(message)               java_code = """    Java.perform(function(){        var hooksClass = Java.use("com.dodonew.online.http.RequestUtil");        hooksClass.paraMap.overload('java.util.Map', 'java.lang.String', 'java.lang.String').implementation = function (addMap, append, sign) {            console.log("MD5加密参数1为:"+addMap);            console.log("MD5加密参数2为:"+append);            console.log("MD5加密参数3为:"+sign);            var result = this.paraMap(addMap, append, sign);            console.log("sign加密结果:"+result);            console.log("sign加密结果:"+result['equtype']);            return result;        }    })    Java.perform(function(){        var hooksClass = Java.use("com.dodonew.online.http.RequestUtil");        hooksClass.encodeDesMap.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function (data, desKey, desIV) {            console.log("DES加密参数1为:"+data);            console.log("DES加密参数2为:"+desKey);            console.log("DES加密参数3为:"+desIV);            var result = this.encodeDesMap(data, desKey, desIV);            console.log("encrypt加密结果:"+result);            return result;        }    })"""       # get_usb_device改成get_remote_device方法,get_usb_device有的电脑会报错process = frida.get_remote_device().attach(3179)  # 'App名称', 或 App应用的 Process Pidscript = process.create_script(java_code)  # 把js的hook脚本注入到进程里面script.on('message', on_message)print('[*] Running CTF')script.load()sys.stdin.read()

2.JS还原

1、运行Hook代码

2、分析加密参数:
sign的加密参数:equtype=ANDROID&loginImei=Android354730613429558&timeStamp=1670240167016&userPwd=123456&username=15888888888&key=sdlkjsdljf0j2fsjk
sign的MD5加密结果:B5BC60EB36B54B683656B56B88714E00
3、WT-JS还原MD5

4、使用WT-JS生成MD5的加密代码

5、查看生成的代码

6、WT-JS还原DES
public static final String BASE_DES_IV = “32028092”;
public static final String BASE_DES_KEY = “65102933”;
这里有个小坑,分析apk源码可以发现,key先进行了MD5加密后才作为参数传入创建DES加密对象

这里先用WT-JS生成DES加密代码

7、查看WT-JS生成的DES加密代码

五、python登录实现代码

1.python示例代码

import timeimport execjsimport urllibimport requestsclass DuDuNiu(object):    def __init__(self):        with open(file="js_code.js", mode='r', encoding='utf-8') as fis:            self.js_code = fis.read()        self.js_obj = execjs.compile(source=self.js_code, cwd=r'D:\software_install\nodejs\node_modules')        self.username = "15888888888"        self.password = "123456"        self.time_string = str(int(time.time() * 1000))        self.headers = {            'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 7.1.2; SM-G9810 Build/QP1A.190711.020)'        }    def get_login_params(self):        items = {            'equtype': 'ANDROID', 'loginImei': 'Android354730613429558', 'timeStamp': self.time_string,            "userPwd": self.password, "username": self.username        }        content = ''        for keys in items:            content += f"{keys}={items[keys]}&"        append = "sdlkjsdljf0j2fsjk"        content += f"key={append}"        print(content)        sign = str(self.js_obj.call('MD5_Encrypt', content)).upper()        print("sign参数:", sign)        items['sign'] = sign        content = str(items).replace(' ', '')        print(content)        encrypt_string = self.js_obj.call('DES_Encrypt', content)        print("login参数:", encrypt_string)        return encrypt_string    def des_decrypt(self, content):        result = self.js_obj.call('DES_Decrypt', content)        return result    def register(self):        pass    def login(self):        login_url = 'http://api.dodovip.com/api/user/login'        params = {"Encrypt": self.get_login_params()}        login_response = requests.post(url=login_url, headers=self.headers, json=params)        login_result = str(login_response.text)        print("login响应:", login_result)        login_result = self.des_decrypt(content=login_result)        print(urllib.parse.unquote(login_result))    def runs(self):        self.login()obj = DuDuNiu()obj.runs()

2.python运行结果


总结

以上就是今天要讲的内容,本文仅仅简单介绍了一个app的逆向案例,需要仔细观察一下加密的参数以及加密结果的变化,该示例用的加密参数都是同一种,希望对大家有所帮助;