首页
社区
课程
招聘
[原创]安卓协议逆向之frida hook百例
发表于: 2022-11-12 18:56 25445

[原创]安卓协议逆向之frida hook百例

2022-11-12 18:56
25445

各位下午好 我是一位往Android安全方向走的的小菜鸟一枚 目前也是很努力在学 这个系列也会一直更新 记录自己的学习过程 大佬多担待担待 有出错的地方也帮忙指出

此处是fd抓的password login 的提交

提交的data:

共有三处加密 一个sign 一个pwd 这两个初步看是md5 还有一个udid 一开始还以为是base加密 丢进base全家桶解密结果不是 那就暂定AES或RSA吧

该说不说 是骡子是马直接丢jadx

好家伙搜sign这么多地址 那咱怎么可能一个个看 直接搜login.ashx

那咋办嘛 进来之后 看到这里string了一个对象 是login_url 那就应该会有调用他的地方进行post提交 直接搜这个对象看看

果不其然 这里拼接了一个username 和pwd 还能看到有个encodemd5 里面传了个str3 str3还是一个被传进来的参数 这里应该就是对pwd进行加密的地方 双击进入这个方法 真相就要水落石出了

md5的模子 直接给他hook下来

好家伙 点一下登陆 有两处调用了这里 第一个应该是密码 pwd 第二个可能是sign 经过抓包检验 确实是我们要的sign参数 只是抓到的包里面的sign参数是经过md5到大写


通过我们对sign的劫持 我们取到了一串明文 接下来还是继续分割出来 发现了udid在这里就已经进行了加密 然后pwd也是加密了 pwd没什么好说的 在刚才的hook中已经知道他是先加密了pwd再进行拼接 然后把这个拼接完的数据继续入参进行md5加密成sign 以下是对udid的分析

依旧是无脑定位大法 搜udid 看到getudid直接进
(接下来看图吧 以下是找udid的生成过程)





到这里 就给大家简单说一下 这个udid的生成

udid的生成找到了 最后是通过encode3Des进行加密 如果不懂什么是3Des加密的可以去上网搜一下


key找到了 大概过程也分析完了 我们尝试hook一下拿到明文然后自己还原校验一下

OK 成功 至此分析过程已经完毕

感谢各位的阅读 学逆向很累 但是喜欢的事还是得坚持下去 后面还是输出更好的例子给大家学习 我个人也在很努力的学习 跟大家一共共进步

1. pycharm(python,JavaScript)
2.安卓模拟器(觉得哪个好用就用哪个)
3.frida配置(frida是配置在python的)
4.jadx-gui (反编译工具)
(后续有其他工具再贴 以上的工具论坛已经有很多大佬教过安装和配置了 这里就不赘述了)
1. pycharm(python,JavaScript)
2.安卓模拟器(觉得哪个好用就用哪个)
3.frida配置(frida是配置在python的)
4.jadx-gui (反编译工具)
(后续有其他工具再贴 以上的工具论坛已经有很多大佬教过安装和配置了 这里就不赘述了)
SHB9Bp8hYYgXQMYBQViZQF==(题目:仿射后的base)
SHB9Bp8hYYgXQMYBQViZQF==(题目:仿射后的base)
appid (app标识) 
sign(加密)
appversion(app版本)
channelid(好像也是一个标识吧反正固定的)
pwd (密码(加密))
udid (加密)
username (手机号)
appid (app标识) 
sign(加密)
appversion(app版本)
channelid(好像也是一个标识吧反正固定的)
pwd (密码(加密))
udid (加密)
username (手机号)
#####python代码块
import frida  # 导入frida模块
import sys  # 导入sys模块
def on_message(message, data):  # js中执行send函数后要回调的函数
print(message)# 打印回调的函数
session = frida.get_remote_device().attach('name'# app名字
with open("./hook.js",encoding='utf-8') as f:script = session.create_script(f.read())# 找到我们写好的hook脚本 然后进行注入
script.on('message', on_message)  # 加载回调函数,也就是js中执行send函数规定要执行的python函数
script.load()  # 加载脚本
 
sys.stdin.read()#进行程序阻塞 让我们进行调试  如果不加这段会直接允许会直接结束代码 CTRL+D可以直接结束程序
#####python代码块
import frida  # 导入frida模块
import sys  # 导入sys模块
def on_message(message, data):  # js中执行send函数后要回调的函数
print(message)# 打印回调的函数
session = frida.get_remote_device().attach('name'# app名字
with open("./hook.js",encoding='utf-8') as f:script = session.create_script(f.read())# 找到我们写好的hook脚本 然后进行注入
script.on('message', on_message)  # 加载回调函数,也就是js中执行send函数规定要执行的python函数
script.load()  # 加载脚本

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-11-12 19:06 被xiaoc996编辑 ,原因:
收藏
免费 15
支持
分享
最新回复 (9)
雪    币: 711
活跃值: (1427)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
没人给我点赞? 那我自己给自己点
2022-11-12 19:17
1
雪    币: 2334
活跃值: (10386)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
点赞点赞
2022-11-12 20:54
0
雪    币: 2926
活跃值: (1407)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
zan
2022-11-13 01:23
0
雪    币: 303
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
学习了
2022-11-13 18:41
0
雪    币: 1672
活跃值: (2272)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习了
2022-11-15 00:28
0
雪    币: 265
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
学习了,不过这类java层的加解密,直接算法助手跑一遍啥都有了
2022-11-15 11:37
0
雪    币: 1490
活跃值: (9913)
能力值: ( LV9,RANK:240 )
在线值:
发帖
回帖
粉丝
8
军哥i [em_63]学习了,不过这类java层的加解密,直接算法助手跑一遍啥都有了
算法助手我碰到个bug。搜索的时候就报错。好像是说数据太多的异常。修bug呀,大佬
2022-11-15 16:20
0
雪    币: 124
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
样本是什么apk呢, 能讲下怎么吗 不理解【仿射后的base】
2022-11-21 11:47
0
雪    币: 58
活跃值: (274)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
from pyDes import CBC, PAD_PKCS5
from pyDes import triple_des
import base64
import time
import random
import hashlib
import requests

"""
加密模式:DES/CBC/pkcs5padding
需pip先安装依赖包
> pip install pyDes
"""

 # 3des key 只支持24位,并且 java 版也是截取了前24位
 # hook 【com.autohome.ahkit.AHAPIHelper.getDesKey】 得到key,一般不会变
key = 'appapiche168comappapiche168comap'[:24]
# com.autohome.ahkit.utils.SecurityUtil.iv
iv = 'appapich'


def des_encrypt(s, key=key, iv=iv):
    """
    DES 加密
    :param s: 原始字符串
    :param key: 加密密钥24位
    :return: 加密后字符串, base64
    """
    secret_key = key
    k = triple_des(key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s.encode(), padmode=PAD_PKCS5)
    return base64.b64encode(en).decode()

def des_descrypt(s, key=key, iv=iv):
    """
    DES 解密
    :param s: 加密后的字符串
    :return:  解密后的字符串
    """
    secret_key = key
    k = triple_des(key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(base64.b64decode(s), padmode=PAD_PKCS5)
    return de


# imei,deviceid同一设备不会变
imei = "354360070284377"
deviceid = '331827'
# 加入随机值来模拟程序已运行时间
r_time = random.randint(20,300)

def get_udid():
    nano_time  = int(time.perf_counter()) + r_time
    # 改为纳秒
    nano_time = str(nano_time * 10e9)
    
    # 构造加密字符串
    s = '|'.join([imei,nano_time, deviceid])
    udid = des_encrypt(s)
    return udid


pwd = 'edcrfv'
def get_pwd_md5():
    m = hashlib.md5(pwd.encode())
    return m.hexdigest()

_appid="atc.android"
appversion='2.9.3.1'
channelid='csy'
pwd=get_pwd_md5()
udid=get_udid()
username="xxxxxxx"


def get_sign(udid):
    s = f'W@oC!AH_6Ew1f6%8_appid{_appid}appversion{appversion}channelid{channelid}pwd{pwd}udid{udid}username{username}W@oC!AH_6Ew1f6%8'
    m = hashlib.md5(s.encode())
    return m.hexdigest().upper()


header = { 
    "Host": "dealercloudapi.che168.com",
    "cache-control": "public, max-age=0" , 
    "traceid": "atc.android_40d56fc7-f30e-4e77-9b3f-0b71d073d88e" ,
    "content-type": "application/x-www-form-urlencoded",
    "user-agent": "okhttp/3.14.9"
}

def login():
    url = "https://dealercloudapi.che168.com/tradercloud/sealed/login/login.ashx"

    # udid 每次都会变所以每次都要生成
    udid = get_udid()
    data = {
        '_appid':_appid,
        'appversion': appversion,
        'channelid':channelid,
        'pwd': pwd,
        'udid':udid,
        'username':username,
        '_sign':get_sign(udid)
    }
    res = requests.post(url,headers=header,data=data)

    print(res.json())


if __name__ == '__main__':
    login()

贴上模拟登录代码


最后于 2022-11-21 18:18 被gwljt编辑 ,原因:
2022-11-21 18:16
0
游客
登录 | 注册 方可回帖
返回
//