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

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

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


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

    文章目录


    前言

    该文章使用了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、登录接口的urlhttp://api.dodovip.com/api/user/login
    在这里插入图片描述
    在这里插入图片描述

    三、反编译逆向分析

    提示可以把反编译的Java代码复制到IDEA分析运行这样会提高逆向的效率
    加密参数的关键词“Encrypt”点击"转到"来到加密代码处
    在这里插入图片描述
    在这里插入图片描述
    MD5加密生成sign参数public static String paraMap(Map<String, String> addMap, String append, String sign)
    在这里插入图片描述
    DES加密生成encryptpublic static String encodeDesMap(String data, String desKey, String desIV)
    在这里插入图片描述
    在这里插入图片描述

    四、还原JS加密

    1.Hook示例代码

    import frida
    import sys
    
    def 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 Pid
    script = 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 time
    import execjs
    import urllib
    import requests
    
    
    class 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的逆向案例需要仔细观察一下加密的参数以及加密结果的变化该示例用的加密参数都是同一种希望对大家有所帮助

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6