吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 936|回复: 12
收起左侧

[Android 分享] 某次元信息加密方式探究

  [复制链接]
Tsh4d0wT 发表于 2025-4-14 17:42

目的:探究某次元的信息加密方式

抓包

image.png

如图,在应用中我们搜索一点东西,能抓到这些内容,在句号之前是固定344长度的数据,句号后面是不固定长度的数据,可以猜测这些内容是我们搜索出来的东西的密文。句号之前固定长度的数据应该是key

flutter恢复

image.png

我们解包apk可以发现它是flutter框架的app,那程序的主要内容都在libapp.so里面,这个文件内容庞大且没有符号表,手动定位我们需要的函数是不现实的。

blutter配置

这时候就需要用上我们的blutter工具

直通车https://github.com/worawit/blutter

下好过后进入blutter目录执行初始化环境的脚本

python ../scripts/init_env_win.py

这一步是为了避免出现ICU库报错

然后需要GIT和CMAKE,并在VS的工具中把CMAKE相关扩展都装上

其他问题没遇到,不知道还有没有其他环境支持

使用

把flutter框架的apk解包

python <blutter工具路径> xxx\lib\arm64-v8a <输出路径>

然后就能得到如下文件

image.png

其中,ida_script文件夹下的addNames.py就是我们用来恢复符号表的关键

在IDA中打开我们的libapp.so,然后File -> Script file / Alt + F7,选择刚刚的addNames.py文件即可

逆向

刚刚我们已经恢复了符号表,那就需要在libapp.so中定位关键逻辑了

前文提到过我们猜测那里是加密后的数据,那就搜索Encrypt或者Decrypt函数

image.png

image.png

根据函数名,几乎可以确定加密主体有AES和RSA,

然后我们知道是native层的函数,函数地址也知道,逐条分析逆向的难度也不小,可以用frida尝试去hook

var addr = Module.findBaseAddress('libapp.so');
console.log(addr); // 打印出基地址
var funcAddr = addr.add(0x822d84);
console.log(funcAddr);
Interceptor.attach(funcAddr, {
    onEnter: function (args) {
        console.log("hook 传入参数------------------")
        console.log('arg0,',hexdump(args[0]))
        // console.log('arg1,',hexdump(args[1]))
        // console.log('arg2,',hexdump(args[2]))
    },
    onLeave: function (retval) {
        console.log("-------hook 返回值-------------")
        console.log('返回值:', hexdump(retval, {length:2000}))
    }
})
// onEnter和onLeave都是回调函数,在目标函数被调用,且尚未执行函数体之前触发
// args 是一个数组,包含了传递给目标函数的所有参数
// retval 代表目标函数的返回值

最终我们可以在decrypt的0x822d84处函数hook出密文和明文

  • 这里函数后面的hex数据都是在libapp.so的基地址上的偏移量

image-20250319232709055.jpg

那么这个函数就肯定有用,我们多hook几次仔细看看hook日志

可以发现,我们每次hook这个函数,启动程序后frida一共会hook两次arg0和返回值分别为

image-20250320123535606.jpg

image-20250320123547946.jpg

arg0的值是固定的,都是密文,返回值一共有两次,第一次是固定16字节的字符串,第二次是明文

tips:AES的key一般是16字节

分别去hook 822d84里的函数

image.png

这个是就是关键加密函数,且是根据刚刚的hook结果,我们知道第一次这个函数返回16字节的key,第二次返回明文。所以我们要根据这个函数去追

image.png

交叉引用可以发现只有8ab12c调用了两次,那么这就是最关键的整个加密函数

hook出来的完整密文,以"."分开,前面334字节是key,后面是加密数据

理一下这里面的内容,可以得到:

334字节key -> RSA解密 -> ?
加密数据 -> AES解密? -> 明文

这里就有两个问题,RSA要解密需要私钥;AES解密需要确定其模式,找到key以及可能需要iv

我们先去尝试处理key

过程1 处理key

0x8ab12c函数里我们按0x822d84函数两次调用作分割

由于第二次调用返回值已经是明文了,那么我们只需要关注第一次调用之前和第一次、第二次调用之间的内容

image.png

这个函数名尤为扎眼,分配RSAkey,那么hook这个函数试试

var addr = Module.findBaseAddress('libapp.so');
console.log(addr);
var funcAddr = addr.add(0x832214);
console.log(funcAddr);
Interceptor.attach(funcAddr, {
    onEnter: function (args) {
        console.log("hook 传入参数------------------")
        console.log('arg0,',hexdump(args[0]))
    },
    onLeave: function (retval) {
        console.log("-------hook 返回值-------------")
        console.log('返回值:', hexdump(retval))
    }
})

image-20250320125509767.jpg

这个函数的传入参数就是RSA的私钥,破案了

我们取长一点,把完整私钥提取出来,且hook了好几次,确定了私钥是固定的

var addr = Module.findBaseAddress('libapp.so');
console.log(addr);
var funcAddr = addr.add(0x832214);
console.log(funcAddr);
Interceptor.attach(funcAddr, {
    onEnter: function (args) {
        console.log("hook 传入参数------------------")
        console.log('arg0,',hexdump(args[0],{length:0x1000}))
    },
})

得到完整私钥:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxm2Kzu9L/FNX42em9Xo73JXtJCtrhleKN9jqclpK6/Iyah/T
UjH5RCNItWiTKHg6LcsGxZs9+4fP6uU8oO5Qp1akaOrJTg3QTQQFyRxDrv+LN/nL
6/MpSf3SnihyVPQWwlkj3yHZWrVC9HI3q2JmzGV/kzwnpVIj2as8zl4cO7OZr0F9
bR+G4jblqLPmB/x/BBOGrWWCxn+YI2RVHw23dev9jql284eN/KV4tlDlbtoJGy4+
Cb7nEV/THvRVZYbHAp+fMY0+NyqyslLX/btJqT8eSH6Hb8c+BSC77Dry4G8/m/wU
YPdvXiL3cVhZmEaqjs8rUafGyQmW3mrflAbIJwIDAQABAoIBAQCbRhUdIbzAUyev
V+kapvA5CUlsyF133wDV+vRbT7TZNcmlqgnfhCOe4k1/R7oALTS5qOo/r9+s+PYG
xiPPey26BN7bCv9ECSM7YS511ZxRUL9MqjidBscEk49BHD17pRY6Ny8O6JoBlV4z
kz1k67etsq9GNAiCIejT6F/IzXQicmO5MaJWCjBNSP+IPTvd5NW3DUNlt2NcCBvO
2sCgSq2Z4B0IdNWeSvd4ZmA2qSkqk60A8glNR4HdRTG9VWR0fUOd/qzpN1vjBUKM
aIHeUX50NCRdK8EGqrVOCq4uUgBRj7bjt0DOb9ck4vYxgBdkyK4HMYsAGdirYKxd
DkseicqhAoGBAOZ750Vky38kq3MucAE/uaFpaDUSeOKDy03fumM6TLlkeAxnTQZW
NBDzlrqNgQPMLu+tmm+ZsEN5buF8C2oKc97+Rz21rvrOufr4sX2PqHfj/kerYGq/
NzX1jpRbqsmcs+3JxveeozHuXBbOFpd8teCGZPFPHREFDe4sZFtFmwX1AoGBANxl
JNlKIz0TVmPgGCUZ4j8BRBiLPHMeFkUoam6Djou2iJLYey3ZNHhyMiRER7Smia0f
Y/QjqJIeSRWQlZExu6s9ijl4VSmoh4hLanOxxAE+gFnuhgK4XwMV0hvHbqSaupQd
fkULZ+t3rGKzt+t+0ob7xx+LjYWEwpLsKCQKRKgrAoGADLPvfyea/5rpyCNbEPaO
KJNCpwopl3JkFhqqjyV7bQxYgXaADEVcAUMrn4SFA8yRGaybwmLaEB31OoA3sNR6
pmOlUYVd63zRSz/BqIXuZw0tyo1rdvaq+FJcVVjoBMyaLhTc3nDj1bCpaqhZHmhF
Lea6UYJmu7VnmyTfMxiW/rECgYAh4MJLTGQiTUioTZgoi9QFT1KCW1TNdUCDHPVP
S5Wr0EEqIXC92XeBVDx06rIDCN586ChbLOgKnfEqCXGUQgrRBcKrlt2wa6F5x+3z
Hs48Srk8Gbgrzt97/+yuLHfLgaVQg0AXqOsufNTYzztkTbha23T+WltEvOWT5A0/
jPyExQKBgCGbq62piyIEeMNoP/SoLvh4hTq/eeNw5yCcLEsLrgt45Xb/2YgeyXWv
xTXl4c8bPdZTFYQ9A7IUYvhizpH032tDouqCsvgu3KtDO/pW6IteL17YBco7fRMQ
JhBuQjGDCMEGEJW76GwlXj/xUW32TN/5KeQXtHHZ4z2lZlJLU81B
-----END RSA PRIVATE KEY-----

写脚本试试解密key,试了几个填充方式过后发现为PKCS1_no_padding

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
import base64

def RSA_Decrypt(private_key_pem, ciphertext_base64):
    # 加载私钥
    private_key = serialization.load_pem_private_key(
        private_key_pem.encode(),
        password=None,
        backend=default_backend()
    )
    # 解码 Base64 编码的密文
    ciphertext = base64.b64decode(ciphertext_base64)
    # 使用 PKCS1 无填充方式解密
    plaintext = private_key.decrypt(
        ciphertext,
        padding.PKCS1v15()
    )
    return plaintext

private_key_pem = """
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxm2Kzu9L/FNX42em9Xo73JXtJCtrhleKN9jqclpK6/Iyah/T
....
JhBuQjGDCMEGEJW76GwlXj/xUW32TN/5KeQXtHHZ4z2lZlJLU81B
-----END RSA PRIVATE KEY-----
"""
ciphertext_base64 = "gsXZuK1P5zPQYUG3v/6pFLQhvxHzKpbLdYCPcoqAR8fzq48YOz04N+fqwd/Rev+K+8srxUkEiWUvRday9f6uGWzbsB1XbpodWyOTLctMIkh+lYSAIjEkIKRR/ebTK/oo2kIiifsTPpeDySCQPKsFQtkz8QayWhcVxkXRQKBqBTfxg6jQY+gRVYJtIcajks7CB7Pii7MbaDDnEBnnip8r2y/AdqbyOaIXJgjF6NxtROnxgE3dRZTuyyuZtUqCytMWb2xRicVqkrg03tHU0r2pUBI3dihSaQF+FQ448RYYuxQePDVU6IEuVSwcYQZbgu8QcG3/n0cdYbq0RFcBDs1xFg=="

plaintext = RSA_Decrypt(private_key_pem, ciphertext_base64)
print(plaintext.decode())

# PD6QJUZVT2STJ641

这里刚好是16字节的数据

过程2 得到明文

16字节的数据,结合hook 822d84函数时两次调用第一次返回值为16字节数据,可以猜测这个16字节就是第一次调用的返回值

验证

我们重新hook一组

image.png

密文对上了,那么我将前面334字节密文key解密,应该就和左边hook的结果一致

image-20250320131418439.jpg

没问题,我们推测成功

这个十六字节的数据大概率就是解密加密数据时的AES key

image.png

通过1,能发现是有分配IV的,那么可以确定是AES-CBC模式

而在设想中,AES的key我们已经找到,那么就需要找IV,这里的2有reverse,比较扎眼,hook试试

image-20250320134637707.jpg

可以发现,确实只是把key做了一个反向操作

第一次调用和第二次调用822d84之间,把其他疑似函数都hook尝试了,没有找到我们需要的iv

那么,我们又可以来猜,AES的key和iv就是互为反向的16字节字符串

image.png

尝试成功,转成UTF-8导出

image.png

总结

还是比较复杂的过程,hook和看逻辑给我看麻了,不过最后搞成功

把加密数据提取出来,以"."为分界线分为key_enccipher,最终逻辑为

key_enc -> RSA私钥解密(PKCS1_Nopadding) -> AES_KEY
AES_KEY -> 反向 -> AES_IV
cipher -> AES_CBC解密 -> 明文

免费评分

参与人数 7吾爱币 +12 热心值 +7 收起 理由
qmsy273 + 1 我很赞同!
芽衣 + 4 + 1 用心讨论,共获提升!
漁滒 + 4 + 1 我很赞同!
Issacclark1 + 1 谢谢@Thanks!
xsk666 + 1 热心回复!
Arcticlyc + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
beihai1314 + 1 + 1 我很赞同!

查看全部评分

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

 楼主| Tsh4d0wT 发表于 2025-4-15 00:13
feiyuya 发表于 2025-4-14 22:31
大佬 blutter 这个用的python版本是多少,我这边用的一直提示elftools这个包装不上,我看介绍是让装这个pye ...

我自用的python版本是3.8.10,blutter是当时装的最新的
你可能是没有执行blutter的初始化环境脚本
也可以排查一下是不是没有配置git和cmake,vs中有没有配置相关cmake扩展
 楼主| Tsh4d0wT 发表于 2025-4-16 23:52
menglv 发表于 2025-4-15 19:49
apk有吗?新版好像不是flutter了。

通过网盘分享的文件:囧次元.apk
链接: https://pan.baidu.com/s/1qR-G5W1zHUyLu8u8uJjnaQ?pwd=sh4d 提取码: sh4d
--来自百度网盘超级会员v4的分享

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
menglv + 2 + 1 热心回复!

查看全部评分

RabbitBearLove 发表于 2025-4-14 19:48
feiyuya 发表于 2025-4-14 21:18
学到了大佬,感谢大佬分享
feiyuya 发表于 2025-4-14 22:31
大佬 blutter 这个用的python版本是多少,我这边用的一直提示elftools这个包装不上,我看介绍是让装这个pyelftools,这个装上了执行还是报错
PhoenixOe 发表于 2025-4-15 09:10
学到了大佬,感谢大佬分享
3266384950 发表于 2025-4-15 09:29
牛牛牛,
xhr2025 发表于 2025-4-15 11:06
大佬有空再看看 请求头里的 authentication
feiyuya 发表于 2025-4-15 11:14
Tsh4d0wT 发表于 2025-4-15 00:13
我自用的python版本是3.8.10,blutter是当时装的最新的
你可能是没有执行blutter的初始化环境脚本
也可 ...

有可能是我没有git和cmake导致的
menglv 发表于 2025-4-15 19:49
apk有吗?新版好像不是flutter了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-25 03:55

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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