首页
社区
课程
招聘
[原创]猿人学-Android端爬虫比赛第一关解题笔记
2022-5-20 14:54 6675

[原创]猿人学-Android端爬虫比赛第一关解题笔记

2022-5-20 14:54
6675

一、环境


frida 12.8.20

python 3.8.10

jadx-gui-1.2.0

fiddler


二、实战步骤:

1、安装APP,来到第一关,翻页时抓包

jadx打开APP 。根据page= 查找到 com.yuanrenxue.match2022.fragment.challenge.ChallengeOneFragment 类

此处有sign函数,很大几率为翻页调用函数,hook当前函数查看 this.page 和 oooOO0O.OooO00o().longValue()的值:

function hook_ChallengeOneFragment(){
    //访问内部类函数
    Java.perform(function(){
 
        var InnerClasses = Java.use("com.yuanrenxue.match2022.fragment.challenge.ChallengeOneFragment");
        // console.log(InnerClasses);
        InnerClasses.lambda$initListeners$2.overload('o00O000.OooOO0O').implementation = function(age){
            console.log("this.page.value:",this.page.value);//查看page的值
            console.log("age.OooO00o().longValue() :",age.OooO00o().longValue());//查看值
            console.log("age:",age)//查看参数
 
            var res = this.lambda$initListeners$2(age)//运行函数
            console.log("res:",res,"type:",res.$className);//返回值和返回值类型
 
            var Map = Java.use('retrofit2.adapter.rxjava2.BodyObservable');//根据返回值类型创建对象
            var NewP = Java.cast(res, Map); //将返回值转成相应类型
            console.log("NewP:",NewP.toString());//输出返回值
            return res;
        };
 
    });
}

分析代码:

StringBuilder 为可变字符串。

根据代码得出 sb的值为页码+时间戳 "page=21652931584"

再次hook Sign函数查看参数和返回值并与fiddler对比。

function hook_SignClass(){
    //访问内部类函数
    Java.perform(function(){
 
        // 访问内部类时,在当前类后加$符号,后跟内部类名
        var InnerClasses = Java.use("com.yuanrenxue.match2022.security.Sign");
        // console.log(InnerClasses);
        InnerClasses.sign.overload('[B').implementation = function(arge1){
            console.log("参数和参数类型:",arge1,arge1.$className);//数组类型一般会返回null
            console.log("数组类型转码:",JSON.stringify(arge1));//数组类型可尝试使用json解析
            var res = this.sign(arge1);//运行函数
            // return true;
            console.log("res",res);//返回值
            return res;
        };
 
    });
}

此时已经可以断定,这个Sign就是翻页的加密函数 

根据jadx反汇编代码:

 new Sign().sign(sb.toString().getBytes(StandardCharsets.UTF_8))

我们用python实现一下



time_ = '1652932157'
s = 'page=1' + time_
print("s:",s)
bArr = [x for x in bytearray(s,'utf_8')]
print("bArr:",bArr)
 
#s: page=11652932157
#bArr: [112, 97, 103, 101, 61, 49, 49, 54, 53, 50, 57, 51, 50, 49, 53, 55]

此时直接调用sign生成加密参数,抓取100页的值相加得出flag:


#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import frida
import requests
import time
 
#发送接收frida_js信息
def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)
 
js = open('hook.js', 'r', encoding='utf8').read()   #读取frida脚本
 
session = frida.get_remote_device().attach('com.yuanrenxue.match2022')#根据包名启动APP
 
script = session.create_script(js)
script.on('message', on_message)
script.load()#加载frida脚本
 
 
if __name__ == '__main__':
 
    time_ = int(time.time())#获取世家戳
 
    header2 = {
         'Accept-Language':'zh-CN,zh;q=0.8',
         'User-Agent':'Mozilla/5.0 (Linux; U; Android 10; zh-cn; Mi9 Pro 5G Build/QKQ1.190825.002) AppleWebKit/533.1 (KHTML, like Gecko) Version/5.0 Mobile Safari/533.1',
         'Content-Type':'application/x-www-form-urlencoded',
         'Content-Length':'57',
         'Host':'appmatch.yuanrenxue.com',
         'Connection':'Keep-Alive',
         'Accept-Encoding':'gzip',
         'Cache-Control':'no-cache',
    }
    count = 0  #记数
    for i in range(1,101):
 
        s = f'page={i}' + str(time_)
        bArr = [x for x in bytearray(s,'utf_8')]
        res = script.exports.callsecretfunctionedy(bArr) #调用frida_js函数获取加密参数
 
        payload = {
            'page': str(i),
            'sign': res,
            't': time_,
        }
 
        r = requests.post("https://appmatch.yuanrenxue.com/app1", data=payload, headers = header2, verify = False )
 
        data = r.json()['data']
        for v in data:
            count += int(v['value'])
 
    print("flag count:",count)



var result;
function callDYFun(bArr) { //定义导出函数
    Java.perform(function () {
        console.log("bArr:",bArr);
        var ss = Java.use('com.yuanrenxue.match2022.security.Sign');
        var str = Java.use("java.lang.String");
        var res = str.$new(ss.$new().sign(bArr));
        result = str.valueOf(res)
        console.log("result:",result);
 
    });
    return result;//返回值给python
}
rpc.exports = {
    callsecretfunctionedy: callDYFun,
};

类中有两个函数一模一样lambda$initListeners$2和lambda$initListeners$0 

经测试调用的是 lambda$initListeners$2

东西比较基础,仅作为和我一样的小白入门看。大佬勿喷。



[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2022-5-25 11:36 被网络枭红编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (3)
雪    币: 1671
活跃值: (3987)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小黄鸭爱学习 2022-5-20 16:56
2
0
感谢大佬分享
雪    币: 334
活跃值: (392)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_yvvzfcdo 2022-5-22 07:13
3
0
牛逼,学到了
雪    币: 208
活跃值: (1475)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
falconnnn 2022-5-23 15:39
4
0
apk可以分享一下吗
游客
登录 | 注册 方可回帖
返回