猿人学2023第二届第二题

第二题

有条件的可以先到github上看,图片在github上可以看,这边到时候再补,记得点一个star哦后续继续更新,也有第一届的,需要哪一题我做出来了都会上传的。
https://github.com/cheng0225/yrx2023/tree/main/%E7%AC%AC2%E9%A2%98

debugger右键过掉就好

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9QjSKXja-1692674596536)(/a2md.assets/image-20230821171200618.png)]

分析页面和加密参数

通过f12 抓包可以看见,每一次我们翻页,都会先请求一个png链接,但是看不见内容,肯定有猫腻,我们可以通过抓包工具fiddler或者复制请求用python request请求查看内容,响应体式一串数字,应该是时间戳,初步估计是通过服务器时间戳进行加密生成下面的token。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kcYYwtSO-1692674596537)(./a2md.assets/image-20230821171350232.png)]

因为参数不好跟,我跟了好久没找到就直接hook了,因为他这个token是拼接在url后面的,所以hook url第一次出现token的位置。

(function () {
    var open = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function (method, url, async) {
        if (url.indexOf("token") != -1) {
            debugger;
        }
        return open.apply(this, arguments);
    };
})();

hook到之后直接进堆栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eX3JD2ET-1692674596537)(./a2md.assets/image-20230821172003987.png)]

跟值,可以看到,token在_0x291432 这个值里,而且是已经拼接好的,通过argument赋值得来,而argument我们并不好找,我们看看上面有没有直接生成token值的地方,往上一点我们可以看见有一个值,和token一模一样的,就是这个_0x1419b1,其实我们再仔细一点观察就会发现 _0x1419b1 = _0x380df6['qiUgL'](_$o, _0x8c4029),其实这个值比token少一小段,这个后面再说。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVi5WPvD-1692674596538)(./a2md.assets/image-20230821172556685.png)]

简化一下代码,通过控制台打印,我们可以知道 _0x380df6['qiUgL'] 这个函数ƒ (_0x315a52,_0x5c899f){return _0x315a52(_0x5c899f);}接受两个参数,第一个作为函数第二个作为参数,所以我们直接简化代码然后再扣下来token = _$o(_0x8c4029),然后再把参数和函数都打印出来看一下,我们可以看到,其实这个参数就是时间戳加上一个请求链接,那么开始扣加密函数,然后这个参数我们暂时给他写死。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oNrh9lzt-1692674596538)(./a2md.assets/image-20230821173521114.png)]

然后本着缺啥扣啥的原则,大概扣了四五个函数后就报下面这个错了,这个可能是里面存在格式检测,需要压缩一下,在线压缩工具https://c.runoob.com/front-end/51/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJrw7WxA-1692674596538)(./a2md.assets/image-20230821175027441.png)]

压缩后开始报错如下,其实压缩后是不太方便看,所以也可以准备两个文件,一个是格式化的,一个是压缩的,也可以通过行号啥的定位到报错位置,这里报错不是函数,这里是我们扣东西扣少了,这里用到了大数组,但是开头还有一个自执行函数,里面传参用到包含大数组的函数,把大数组进行重组了,所以我们还是把他扣下来。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CRf7HYx1-1692674596538)(./a2md.assets/image-20230821180946850.png)]

然后我们就可以看到出结果了但是和浏览器的结果不一样,说明里面可能会有环境检测,所以我们搜一下window之类的的关键字,window document global 等。然后就可以发现有typeof window这样的字眼,我们可以到浏览器输出一下 这个在浏览器是object,而在我们本地是

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-67J6lvK5-1692674596539)(./a2md.assets/image-20230821181618652.png)]

我们可以看_0x490e9c = typeof login这个login在我们本地是未定义,在浏览器是一个Boolean类型,所以下面就要开始补环境了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tRPRZJou-1692674596539)(./a2md.assets/image-20230821175815136.png)]

同理的里面还有typeof ( window document Window Document ) 这四个参数,js是大小写敏感的,所以每一个都不一样,都要补。

window = global; 
Window = function (){}; 
document = {}; 
Document = {}; 
login = true;

然后运行报的TypeError: Right-hand side of 'instanceof' is not callable这个错,其实也是一个环境检测,报错在 _0x41bc28=_0x12f054 instanceof _0x46f5dc 这个位置,我们到网站打断点看一下,这里拿到的就是一个true我们直接给他写死看一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KsVttl9c-1692674596539)(./a2md.assets/image-20230822102732356.png)]

有结果了,但是值还是不一样,所以后面基本上都是一些环境监测和代码坑了,所以我就不一一截图主要就是,一般正常查找就先搜一下有没有异常捕获啥的,在try语句上打断点,然后看浏览器那边走的哪,然后修改一下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pyBzCS2f-1692674596540)(./a2md.assets/image-20230822103303508.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qg4jum3O-1692674596540)(./a2md.assets/image-20230822103456020.png)]

TypeError: _0x54be74[_0x497406] is not a function 在浏览器打断点可以看到,其实就是创建了一个canvas元素,最后使得_0x2089ab这个值为true,其实我们搜一下这几个变量使用的位置就可以发现,基本上都是5次左右使用,而且第一次是上面进行定义,其余的都在次进行调用,所以我们删掉也没有关系,对代码进行改写一下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ycQDbdL-1692674596540)(./a2md.assets/image-20230822103902217.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqQxhM2R-1692674596540)(./a2md.assets/image-20230822104340538.png)]

最后值得注意的还有这种三元表达式,其实生成的是一个定值,我们可以看一下后面是不是有一个定值然后给他改写成写死就行了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6Gczefx-1692674596541)(./a2md.assets/image-20230822105846843.png)]

倒刺也差不多了,然后最后就是观察出最终逻辑,首先请求png 链接获取时间戳 t 把t 拼接上请求链接的后半部分进行加密,最后加密结果在拼上t 最终就是token了,关键代码:

session = requests.session()
session.headers = headers
session.cookies.update(cookies)

with open('a2js.js', 'r', encoding='utf-8') as f:
    js_code = f.read()
ctx = execjs.compile(js_code)

s = 0
for page in range(1, 6):
    session.get('https://match2023.yuanrenxue.cn/api/loginInfo')
    response = session.get('https://match2023.yuanrenxue.cn/api/background.png')
    token = ctx.call('get_token', response.text, page)
    print(response, response.text, token)
    params = {
        'page': page,
        'token': token,
    }
    response = session.post('https://match2023.yuanrenxue.cn/api/match2023/2', params=params)
    print(response, response.text)
    s += sum(x['value'] for x in response.json()['data'])

print(s)

js核心代码,写一个请求函数,传入时间和页面,返回token

function get_token(time, page) {
    var _0x8c4029 = time + '/api/match2023/2?page=' + page
    return _$o(_0x8c4029) + time
}

token = get_token(1692672732164, 2)
console.log(token, token === '3b8a54771c4a8c5850ca9032788adf351692672732164')
}

token = get_token(1692672732164, 2)
console.log(token, token === '3b8a54771c4a8c5850ca9032788adf351692672732164')
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值