• 【Reverse】2022 强网杯 game


    【Reverse】2022 强网杯 game

    前言

    复现一下这题,因为手头有环境可以学学。强网的时候根本没看。

    backup还原

    直接GitHub的链接

    可以还原出apk

    摸瓜分析

    在线网站分析
    image-20220813083353778

    发现有个域名,下面还有个URL

    image-20220813083421201

    jadx分析

    虽然主活动是com.silence.scoreboard.SplashActivity,但是我们先看base的东西

    首先是BaseActivity,去BaseApplication注册了一个广播

    然后有一个MyReceiver去接收广播消息

    image-20220813083526999

    跟进BaseApplication

    调用了一个scoreboard的链接库

    同时在onCreate的时候,会有一个RootUtils.check()和一个OoOO.OOOOOooo()

    RootUtils一看就知道是检测root权限的,这个OoOO.OOOOOooo应该是链接库里的方法,也就不去管了

    image-20220813083759586

    再来到主活动SplashActivity进行分析

    image-20220813084526009

    onCreate的时候进行isLogin()的判断

    如果登录了,就去执行autoLogin自动登录,有个回调函数,搞过安卓网路开发的都知道这个是Retrofit

    那么思路先去全局搜索一下http找到RetrofitHelper

    找到了服务器的基地址http://47.93.244.181/re/

    image-20220813084731978

    返回到主活动,继续分析

    登录成功就去MainActivity,失败就去LoginActiviy

    顺着HttpRequest.login,去看API接口

    image-20220813093117264

    有个GetFlag.php

    image-20220813093201998

    需要code、account、username

    结合app下载的界面显示,超过9999分就可以获取flag

    img

    API分析

    register,密码用md5加密后post

    image-20220813095905967

    login,account被encrypt加密了,密码还是md5的形式

    image-20220813100226060

    autologin,多了一个code,account和username都被加密了

    image-20220813100330010

    submit,提交分数,在贪吃蛇的界面有调用

    image-20220813100356816

    image-20220813100420922

    addFriend,添加好友,需要一个code来添加

    image-20220813100439164

    getScoreBoard,查看排行榜
    image-20220813100459765

    getFlag,需要code,account,username

    image-20220813100521181

    API测试

    先去注册一个,获得了一个code

    image-20220813100740086

    去scoreboard看看,有users和admins,因为是复现,所以我怀疑users都是比赛时做出来的,直接把分数改成大于9999了

    image-20220813100926835

    admins中,只有第一个的分数是9999

    image-20220813101010315

    addFriend接口

    因为getFlag这个api,不需要密码的,只需要account和code还有一个username

    观察到registerActivity中,注册后会把注册后的json信息回调给setUserInfo方法

    image-20220813101552665

    image-20220813101853063

    这里调用了decrypt,会想起在注册或者login后,会对accouont、username进行encrypt

    image-20220813102044392

    那么,我们先去尝试加个好友,因为加好友后会显示部分信息

    image-20220813103552402

    api测试,发现给的太多了,甚至给了account

    image-20220813103601039

    这个account和username肯定是经过encrypt的,那么思路有了,直接hook这个OooOoo0.decrypt,把加密后的这个admin的account和username都调用一下这个decrypt,那么可以得到admin的account然后获取flag

    frida调用decrypt

    因为这个app检查了root权限,我手头上的机子用的Magdisk22,可以使用Magdisk Hide功能隐藏root权限,所以打开app是没问题的。

    但是经过测试发现,如果先打开frida-server,再启动app,直接闪退

    那么换个思路,先打开app,在开启frida-server,使用attach模式来附加到进程上面

    hook调用decrypt和encrypt的ts脚本,需要编译成js

    const encrypt = (s: any) => {
        let res = ''
        Java.perform(() => {
            res = Java.use("com.silence.utils.OooOoo0").encrypt(s)
        })
        return res
    }
    
    const decrypt = (s: any) => {
        let res = ''
        Java.perform(() => {
            res = Java.use("com.silence.utils.OooOoo0").decrypt(s)
        })
        return res
    }
    
    rpc.exports = {
        encrypt: encrypt,
        decrypt: decrypt
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    python调用frida

    import sys
    import frida
    
    
    def on_message(message, data):
        if message['type'] == 'send':
            print(f"[frida hook] : {str(message['payload'])}")
        else:
            print(f"[frida hook] : {str(message)}")
    
    
    session = frida.get_usb_device().attach("ScoreBoard")
    
    with open("./ts_script/js/test.js",encoding="utf-8") as f:
        script = session.create_script(f.read())
    
    script.on("message", on_message)
    script.load()   # 加载脚本
    
    tmp = script.exports.encrypt("test114")
    print(tmp)
    
    tmpp = script.exports.decrypt(tmp)
    print(tmpp)
    
    account = script.exports.decrypt("SWeH8ou9yuL8GLThYhY1QlDiWX880+uNZusmIll/Q4Q=")
    print(account)
    
    username = script.exports.decrypt("IbaoQT/3eTXIjHDJ2L5TQE==")
    print(username)
    
    # sys.stdin.read()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    tmptmpp是用来测试加密解密是否成对

    account和username两个解密的都是addFriend的API获取的,直接解密

    image-20220813104955507

    拿到账号&Od987$2sPa?>l

    getFlag

    把参数放到api里,直接获取

    image-20220813105027626

  • 相关阅读:
    Jvm与DVM与ART
    【数据结构】c++栈的应用:波兰式、逆波兰式和中缀表达式计算器
    Python中图像相似性度量方法汇总
    2022年高考都结束了,还有人真觉得程序员下班后不需要学习吗?
    勒索病毒处置
    自从用上这几款软件,才发现原来苹果电脑可以这么6!
    【ijkplayer】read_thread 流程梳理(二)
    Soc系统级芯片
    Vue3+TypeScript
    51单片机热水器温度控制系统仿真设计( proteus仿真+程序+原理图+报告+讲解视频)
  • 原文地址:https://blog.csdn.net/woodwhale/article/details/126317103