猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验

webpack初体验

  • 一、前言
  • 二、逆向过程
  • 三、代码实现
  • 四、结语

一、前言

webpack算是逆向过程中比较常出现的一种加密方式了,本质上是将网页源代码打包进JavaScript ,并对其进行压缩,如果不对其进行其他混淆操作的话还是很好还原的。第十六题虽然标的是简单级别,但对于新手来说,也有一些坑,不注意就会踩到,找不对方法真是头皮要想破。话不多说,开整

二、逆向过程

这题还是老样子,先观察XHR请求,发现有两个加密参数,一个m很明显是主要加密参数,t则看起来是个时间戳:
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第1张图片
跟着请求的调用栈,找一下这个api请求发起的地方,进入webpack.js内:
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第2张图片
一进来就很容易找到了两个参数生成的入口:

猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第3张图片
r.t确定就是时间戳,由下面这段代码生成:

Date[e(496)](new Date)[e(517)]()

还原出来实际上就是:

Date['parse'](new Date)['toString']()

另一个复杂点的参数r.m表面看起来是base64加密,但实际用时间戳自己试了下以后发现并不是,这里应该是重写btoa函数,于是顺着调用的地方找到这个函数的实际内容,这里这个window[u(208)]就是btoa函数:
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第4张图片
在这个函数的底部,找到了最终的返回值,也就是下面这个return返回的内容:
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第5张图片经过一番调试,发现最终的加密字符串是由三个部分拼接成,第一部分和第三部分是通过调用d函数实现加密,构成可加密字符串的首尾部分:
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第6张图片
中间部分则是个md5加密,也是对在window[u(208)]内生成的一段字符串进行加密,这里要注意拿待加密的字符串用标准md5加密看看结果跟网站加密的是否一样,经过验证发现网站把md5也重写了,不过不难找,全局搜索一下就找到了具备位置,直接复制粘贴就完事。
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第7张图片到这里主要的加密逻辑就分析完了,但扣代码的时候还是有两个坑把我绊了一下。

第一个坑在这里,这个叫_0x34e7的变量是个数组,里面放的就是后续各个函数内调用的各种参数,直接扣完所有代码跑,会发现生成的加密结果明显不对:
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第8张图片
经过一番摸索,发现这个数组在函数内生效使用时,顺序被打乱了,而直接粘贴代码跑起来的时候不会把顺序打乱,不知道是不是环境问题,所以最后我的解决方案是直接把打乱后的这个数组复制出来:
在这里插入图片描述
上面这个问题解决了以后,满意欢喜的点击运行,成功得出看起来正确的加密字符串,继续满心欢喜的去模拟请求,结果返回了个token无效,当场懵逼。。。心想没道理啊,逻辑上没啥问题,代码也都抠出来了,加密加过看起来跟网站真实的业没啥差别,为啥就不对呢?这里真的是我脑子没转过弯来,才在这死磕了好久。
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第9张图片btoa函数内部最后返回加密结果之前,window.md5加密的字符串是由这个switch循环生成的,在case 1内是有个try catch语句的,浏览器端正常运行不会走到catch报错这里,而自己在nodejs里运行时,走到catch里了却没有设任何提示,以至于我一直以为自己代码扣全了,实际上还少了个n.g函数,虽然缺失了这个函数,但因为直接捕捉了异常,所以最后生成的字符串是有问题的,自然最后加密结果也不对。
在这里插入图片描述
最后把这段函数补上,就真正算是大功告成了。
猿人学web端爬虫攻防大赛赛题解析_第十六题:webpack初体验_第10张图片

三、代码实现

python实现请求代码如下,js解析文件在此:16_webpack初体验.js:

import requests
import time
import subprocess


headers = {
    'Proxy-Connection': 'keep-alive',
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest',
    'Referer': 'http://match.yuanrenxue.com/match/16',
    'Accept-Language': 'zh-CN,zh;q=0.9',
}

for page in range(1,6):
    t = str(int(time.time())* 1000)
    p = subprocess.Popen(['node','./16_webpack初体验.js',t], stdout=subprocess.PIPE)
    encrypt_time = p.stdout.read().replace('\n', '')

    params = (
        ('page',str(page)),
        ('m', encrypt_time),
        ('t', t),

    )

    # print(params)3

    response = requests.get('http://match.yuanrenxue.com/api/match/16', headers=headers, params=params)
    print(response.json())

运行结果:

{'status': '1', 'state': 'success', 'data': [{'value': 1102}, {'value': 8185}, {'value': 7105}, {'value': 5140}, {'value': 9583}, {'value': 7644}, {'value': 3836}, {'value': 6827}, {'value': 9183}, {'value': 8035}]}
{'status': '1', 'state': 'success', 'data': [{'value': 6882}, {'value': 4050}, {'value': 4127}, {'value': 627}, {'value': 2707}, {'value': 3422}, {'value': 6159}, {'value': 8575}, {'value': 7434}, {'value': 3215}]}
{'status': '1', 'state': 'success', 'data': [{'value': 9207}, {'value': 5728}, {'value': 1859}, {'value': 7689}, {'value': 7515}, {'value': 198}, {'value': 6479}, {'value': 2445}, {'value': 628}, {'value': 8582}]}
{'status': '1', 'state': 'success', 'data': [{'value': 7769}, {'value': 9273}, {'value': 2978}, {'value': 9947}, {'value': 9843}, {'value': 9535}, {'value': 201}, {'value': 3396}, {'value': 8241}, {'value': 4725}]}
{'status': '1', 'state': 'success', 'data': [{'value': 4602}, {'value': 7752}, {'value': 559}, {'value': 6395}, {'value': 7251}, {'value': 8595}, {'value': 1075}, {'value': 4738}, {'value': 8709}, {'value': 7631}]}

四、结语

逆向时对有些小细节的注意往往决定了能不能成功给逆出来,还是要多练习才能有这种敏感性。

你可能感兴趣的:(Python,爬虫,python,爬虫,javascript)