浅谈安卓逆向协议(四)- ida pro - 小红书

文章仅提供思路,千里之行,还要靠各位自己努力,不喜勿看。

重头戏-小红书。这是相比前几个最难的了。为什么?看下面娓娓道来。

小红书互联网上真是没搜到解决方案,主要是sign验签和shield验签,sign签名网上有个python版,经过我验证,正确,我就没细看(2019.12.12文尾补充出来代码)。因为这几天比较忙,还没把小红书方案上线。但小红书shield,让我困扰了整整两周多,最后搞定。

小红书做了模拟器检测,如果你是模拟器一直提示你要升级,这块我没细细研究,我直接换了真机。后来我发现了它更多的验证,绕了很多路,重刷了原生系统。不过后来我解决了native的验证,那时我才觉得,可能我不需要这么麻烦。小红书是我弄的最久的,可能接近三周,也学到了很多东西。

小红书shield在libshield.so中。所以jdax不用搜了,浪费时间。最初我也百搜不得其姐,后来我得到了姐姐,思路就打开了。

JAVA层:

小红书做了Debug.isDebuggerConnected的防调试验证,xposed绕过,其他方式绕过都行。这里我采用了其他方式绕过。因为xposed我不是很精通。

然后小红书Retrofit调用create唤起okhttp3的addInterceptor劫持再调用RedHttpInterceptor的intercept函数再调用native函数process

当然初始化native函数initializeNative在引入这个类的时候就调用了,本来想直接引入SO构造Retrofit实现获取sign,但是它上下文太强了,根本无法猜测到它到底是什么类型,传入一模一样的值进去。通过抓包发现,它在so里调用了process方法,根本不会让你在外拿到sign,所以它上下文关联和复杂,相比之前的快手、抖音、最右是最麻烦的。试了几次,抓包发现,模拟构造后发送的shield都为空。

这时候就会发现xposed和frida在这种上下文关联太强的apk中,分析起来也比较乏力。因为参数类型太复杂。

当然后来跟大神们交流中得知,还是有人通过xposed完成对它的模拟调用

NATIVE层:

初始版的libshield.so,inline-hook技术是用不了的,因为它里面加了两层验证。验证不过就给你while(1)循环

sub_E9AC处的"proc/%d/status",获取"TracerPid"判断自己是否被调试

为了这个,花了我一周多时间刷小米8青春的boot.img,因为我要找一个原生anroid8.1支持xposed的系统。

但实际上并不需要这样操作,直接绕过就好了,但是既然走上了逆向的路,一定要一个完美的逆向真机系统。

还有sub_F104处的Signature的hashCode都得绕过

最后hook-inline

最后通过对native层的hook和ida pro分析,才完成了对小红书shield的逆向。附上成功截图

-----------------------

2019.12.12,最近已经在弄6.2*的版本了,新版shield基本已经过了。

6.2* hook_inline截图

 

之前,有人找不到sign的算法,我把之前网上的python版本经过我的简单修正版(更满足伸手党直接测试)的贴出来。里面的deviceId、device_fingerprint、versionName、t我做了***,因为涉及我的设备信息,我不能因为共享算法把自己的设备弄封了,你们可以根据自己实际遇到的url进行操作,我在python3.7下测试过,有截图。

import hashlib

Arr ={"platform":"android","deviceId":"*******","device_fingerprint":"******","device_fingerprint1":"","versionName":"*****","channel":"Guanfang","sid":"","lang":"zh-Hans","t":"1575096***"};
def md5hex(word):
    m = hashlib.md5()
    m.update(word.encode("utf-8"))
    return m.hexdigest()

def sortedDictValues3(adict):
    keys = adict.keys()
    keys.sort
    return map(adict.get, keys)

def get_sign(Arr):
    Str=''
    Keys=sorted(Arr.keys())

    for item in Keys:
        if item!='':
            Str=Str+item+'%3D'+Arr[item]
    deviceId=Arr['deviceId']
    v1_2 = bytearray(Str, 'utf-8')
    v5_1 = ''
    v3_2 = 0
    v2 = 0
    v4_1=bytearray(deviceId, 'utf-8')

    while v2<len(v1_2):
        v5_1 = v5_1 + str(v1_2[v2] ^ v4_1[v3_2 ])
        v3_2 = (v3_2 + 1) % len(v4_1)
        v2 = v2 + 1

    sign=md5hex(md5hex(v5_1)+deviceId)
    return sign

print(get_sign(Arr))

算法我校验过再发的,我只能帮你们到这了,shield是逆向的一个分水岭,加油了各位

 

拿到签名的方式有很多例如,1:xposed的hook,2:嵌入SO调用native层函数,3:unicorn模拟arm中调用函数,4:Ida pro 逆向汇编翻译成C++等。

android逆向交流QQ群:290081995,这个行业比较封闭,让我们共同进步。转载请保留版权。

发布了51 篇原创文章 · 获赞 17 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/wq57885/article/details/94591628
今日推荐