首页 > 编程语言 >Python爬虫 - js逆向之扣出某平台的_signature加密字段

Python爬虫 - js逆向之扣出某平台的_signature加密字段

时间:2024-08-01 15:57:29浏览次数:15  
标签:执行 这个 Python sign 扣出 window 控制台 js

前言

好久没有做逆向案例分析了,最近都在看同行朋友写好的案例,感觉学到很多,算是取长补短了

不多bb,机缘巧合下,拿到个目标网站

分析

首先抓个包,就看到请求参数里带着这几个参数

主要就是_signature了,其他的参数都不重要得想必你一看就知道啥意思了。

行,开始分析_signature了

先,全局搜一下,很好只有一个结果:

 点进去看到主要就这三个地方:

三个地方都打上断点:

继续滑动下拉,发现值已经有了:

鼠标放到变量上面,看到我们需要得_signature其实就是变量a了,而a由函数I(n,e)生成:

其中,n就是V.getUrl生成,e就是传进去的参数:

那取消刚才的断点,重新打上断点看看:

此时,可能你在调试的时候,有时候会出现滑块验证:

这个暂时不管,以后再系统的搞滑块哈

此时发现断上了:

跟进去,发现V.getUri进入到如下,感觉是在处理参数,不知道有没有我们要的sign

 怎么确定有没有,放开断点往下走,如果出现了那就是了,如果没有出现,那多半就不是了,如下:

 这个n的值明显没有sign,那就不是了

当然这个理论在这里行得通,但不绝对哈

好,接着看I,跟进去,发现如下,这里的e就是上面生成的n,t就是上面传进来的参数e,就是而且看到里面有sign相关的变量,90%是了

单步调试,一点一点跟着走看看:

找到关键点

发现上面都是些没有什么用的配置,就到了倒数第二行,貌似才有关键的东西,而且sign也在这一行里,先在这一行打个断点,然后继续走,一点放行,发现走到一个新的js里:

大概的看了一眼,应该是个加密算法,那是不是就是我们要的sign呢?不好说啊,直接点这个跳出去吧:

跳出去之后发现,变量o出现了一个很长的字段

 

拿着跟之前浏览器抓包看的_signature对比下长度,发现一致,那就是这个了,而实际的加密逻辑就是刚才进入的新的js文件alcrawler.js里

关键点找到了,那怎么把核心的加密逻辑扣出来呢?

我大概看了下,这里好像还不好单独把加密的逻辑抠出来,因为有很长的参数调用,而且我抠了下,不好扣,索性整个拿出来吧,结果发现整个也不多,就几百行,复制到本地吧

代码调试

放在本地,取名crawler,用node执行下看看:

发现报了个这个:

什么referrer,那我们搞爬虫的,再熟悉不过了,但是这个是在js里面啊,这就是涉及到补环境了,那么referrer属于哪个js对象里的呢,这个没法展开说了,我就直接说,referrer是document对象里的,js的全局对象有,window,doucument,navigator,global,location

行,这里补齐如下,地址给个主站的地址就行了:

继续执行,报错了:

但其实,懂js的朋友应该知道,其实window.document可以简写成document,这个就你们自己去研究为什么了,如下写,执行立马不报错了:

 当然也可以把window也补一下:

就不会报错了:

那现在我们要把那个生成sign的逻辑拿出来用下,怎么用呢?回到上面这个关键的有sign字段的那一步:

1

2

var o = (null === (n = window.byted_acrawler) || void 0 === n ? void 0 : null === (a = n.sign) || void 0 === a ? void 0 : a.call(n, i)) || "";

            

  

这个懂点js的都不陌生,我们拆开来看:

先看最外层,最外层的括号,如果括号里没有值,那就给o一个空字符串

 那根据上面的断点逻辑,肯定不会是空的,直接省略下,变成如下:

 先把var o 删了:

再通过||符号拆下:

 第一行,null肯定不会全等于(n=window.byted_acrawler)的,所以会走后面的逻辑,但是这一步,同时把window.byted_acrawler复制给了变量n

再看第二行,第二行是个三目运算,首先,0 ==== n肯定是不成立的,直接走后面的null=== (a = n.sgin),这个逻辑就跟第一行类似了,反正最后会把n.sign复制给变量a

再看第三行,这个跟第二行类似,同样的,会走到最后a.call(n,i)

不信可以看看这个下面:

先做简单的替换,本质的运算逻辑是没有区别的

 意思就是,那么长一句,最后会直接执行:window.byted_acrawler.sign.call(n, i)

那么,这两个参数,n,i是啥,先看看n:

再看看i,i就是个url的路径,没有带参数的那种

ok,i变量好说,这个n变量就有点不好搞了,这样,直接在控制台看下需要啥参数:

 这个报错就很有价值了,它只需要一个url就行了,根本不需要那个什么n变量,那就好说了

如下测试,发现不行,需要一个带有url属性的object对象 

 那行,整一个:

芜湖,出来了,行的,就是这么调用,放到本地掉就完了

结果一执行,完蛋,卧槽

报错的意思就是,这个对象没有sign属性,很奇怪啊,在控制台都可以用的,在node里不能用,那说明有检测环境的,把那个检测环境的部分改下试试,先把代码缩一下:

先看那个三目运算,复制到控制台执行看看:

实际就还是window,那就改成window:

卧槽,这里才看到是jsvmp啊,这他妈,大名鼎鼎啊,说实话我有点慌了,本篇博文到此结束?

不不不,还是要挣扎下的,先把它当作普通的函数看待,先看,上面主要的两段代码,第一段是定义,第二段是调用,最后的console打印是我自己加的

那行,那看看参数有没有问题:

定义的时候用的b,e,f

看看下面穿的参数是啥,好家伙,不看不知道,一看传了这么多的东西,用sublime 打开看到:

上面一大段全是b变量,后面的中括号里的值,最后会变成e和f变量,而这里面又有三目运算符

把三目运算符整理下,先看第一个:

 那说明,这个三目运算符就是void 0了,把这相关的都替换成void 0,搜索看,只有一个,

 替换之后再执行,貌似刚才那个sign属性解决了,但是又出现了新的错

这个一看还是补环境的问题了,把这个补了,href是location对象里的,补完又发现新的报错

到这一步的时候,因为报length的话,大概率是补环境除了问题,那么说明刚才的href没有补对,那我们直接再目标网站的控制台copy一下,

 回车即可,一定要在目标网站的控制台里copy,copy完执行,至少当前的问题解决了,再搞新的问题

这个userAgent就再熟悉不过了,咋办呢?也直接copy吧,因为userAgent属于navigator,直接如下copy:

 再次强调,目标网站控制台里执行

copy完放到代码里执行看看:

发现,卧槽,终于tmd没报错,而且有结果了

但是,这个长度好像不大对劲,短这么多,好像差点啥,到底差什么东西呢

仔细推敲,网上也查了相关的,有说补齐cookie的,我补齐之后执行的结果还是很短,所以,应该还有什么东西没有注意到的

在目标网站的控制台里执行,就是可以拿到很长的字段,这就很骚了

 

那我觉得应该还是环境的问题,应该有个我们忽视了的地方

先打印window看看:

location基本没有太大区别:

 不一样的主要是window.document和window.navigator,以及window.localStorage,但是恰恰这三个对象是没法直接copy的:

因为你发现,粘贴出来的要嘛是undefined,要嘛是{}:

 

这他妈就很秀了,难道这就是jsvm的威力吗?

我另开一个浏览器标签,把刚才抠出来的代码放到控制台执行,然后测试看看:

 首先,至少说明,补的基础环境没问题,就差一些特征值了

再看,目标控制台里的这个arguments,

新开的控制台的这个arguments的值:

所以这里就看出区别了,目标控制台里多了个这个:

但是就不知道是不是这里不同导致的原因了。

跟着断点接着走,新开控制台:

看这个c值

 

目标的控制台里的:

看这个c值:

 差距也太大了,而且c就是window.document对象,也就是上面没法copy对象其一

而且,新开标签页,走到后面进入到了这里:

目标控制台,进入到了这里:

能走不一样的原因就是,这里的B[e]

 目标控制台的B[e]是空的,所以,G穿的最后一个值是0,而新开控制台的B[e]有值,所以传的最后一个参数是1,也就导致上面走了不同的逻辑

那么这个B到底是啥:

我去,这他妈的,最后经过我的调试,发现,主要是穿的这个参数的不同:

 导致取值不同,上面是目标控制台的,下面是新标签页控制台的:

但是这一个值的变化,不是我们能控制的,写死也是没用的,唉,这就是jsvmp的强大吗?唉,想想后怕了。

但是中途放弃不是我的作风,我就不信了,我开始在漫无目的的找特征,回到最底部调用部分看这个window对象,突然的看到localStorage部分,我激动了,这个是目标网站里的:

新标签的控制台,window部分,明显感觉有问题对吧,

但是,刚才我们分析的,就是那个this里的window对象不一样,那么我们尽量的去贴靠原网站的window里需要的值,我们给赋值下localstorage,用copy看看呢:

哎,发现这个倒是可以复制哈

把这段封装成一个自执行函数:

放到新标签的控制台里,然后放到控制台里执行,回车,再访问下验证是否成功了,发现可行的

 好,现在再在控制台执行下sign:

把localStorage部分放进去之后,再次执行:

卧槽,说实话,有点小激动,至少这个长度看着很像了,就不知道能不能用了,在代码里看看呢?

直接复制刚才的sign生成好的字段,执行测试,卧槽,牛逼啊,数据结构终于有了

还没完哈,现在要搞一个在本地能够直接生成的,而不是每次生成需要去浏览器的控制台执行再复制出来的

当把那段自治性函数放到node环境里执行的时候:

很奇怪,提示的是没有setItem这个属性,这咋办呢?

尝试jsdom

理一下思路,目前就差一个localstorage的赋值了,但是上面的代码的setItem无法用,因为localstorage对象是window对象里的,那么我们直接用node伪造一个window吧,咋伪造呢?用jsdom,安装nodejs就不说了,网上一堆教程

在本地搞一个node项目,npm init命令初始化后,然后执行命令npm install jsdom安装jsdom,具体过程也省略了,网上教程同样一堆

现在创建一个js文件,把window对象引入,这里注意一下,因为我们要用localstorage,new JSDOM的时候必须要给个主域名,不然没法用localstorage

测试下现在setItem成功没有:

ok了,现在把刚才抠出来的代码整合到一起,结果出现了这个,卧槽,心累啊

说明这段代码还验证了其他很多东西导致这个sign属性没有正常赋值,换路子吧

本地html文件生成

把抠出来的代码放到一个html文件里,同时要注意的,url里的时间戳,必须要跟sign生成时传进去的url里的时间戳保持一致,不然用不了

ok,用pycharm自带的轻量服务器执行查看:

点击那个谷歌浏览器图标,自动打开并展示如下页面:

拿到这两个值去请求测试,哭了,这他妈终于有数据了

那会过头想想,这个没法运用到实际啊,这个第一,还是用了浏览器自带的window对象,第二,这个服务端是pycharm,还不好控制,就算把这一部换成flask,用requests去请求这个接口,拿结果?也不行啊,为啥,因为请求拿到的是源码,这里的时间戳和sign是js生成的

要走这条路的话,只有用浏览器驱动,puppeter或者selenium了,那这里就会有人说了,这都上浏览器驱动了,那还抠啥代码啊,直接一开始就用浏览器驱动了呗,是的,所以这套路也不是我喜欢的

怎么办

构造localStorage对象

上面试了两个路子都不行,那究其原因就还是那个setItem没法用,没法用的原因是我们构造的window对象里的localStorage不是正确的对象,这里构造一个出来,行不行呢?理论上是可以,试下:

1

2

3

4

5

6

7

8

9

10

11

window.localStorage = {

    removeItem: function (key) {

        delete this[key]

    },

    getItem: function (key) {

        return this[key] ? this[key]: null;

    },

    setItem: function (key, value) {

        this[key] = "" + value;  // 将数字转为字符串

    },

};

把这段代码放到最开始抠出来的代码里,并在执行setItem前面,代码如下:

执行看看,激动万分啊,这个长度,看着就跟目标网站出来的sign长度一致了

放到程序里执行测试:

执行,哇的一声就哭出来了,ok

标签:执行,这个,Python,sign,扣出,window,控制台,js
From: https://blog.csdn.net/2401_86078658/article/details/140850069

相关文章

  • Next.js 中为什么 App Router 可能是未来,但 Pages Router 仍然重要?
    Next.js作为一个强大的React框架,为开发者提供了两种路由系统:AppRouter和PagesRouter。这两种路由系统各有特色,适用于不同的场景。本文将深入探讨这两种路由系统的区别、优缺点和使用场景,帮助你做出最佳选择。AppRouter:新一代的路由革命AppRouter是Next.js13引入的......
  • python 音频处理(1)——重采样、音高提取
    采集数据->采样率调整使用torchaudio进行重采样(cpu版)首先导入相关包,既然使用torch作为我们的选项,安装torch环境我就不必多说了,如果你不想用torch可以使用后文提到的另一个库1importtorch2importtorchaudio3fromtorchaudio.transformsimportResample4fromtime......
  • 用于从连接到 LAN 交换机的四个 Arduino 扩展板读取/保存数据的 Python 代码
    我有四个Arduino扩展板连接到LAN交换机。每个人都会发出一条“HelloJane”消息。LAN交换机已连接到我的PC。我需要将每个Arduino的数据/消息保存在PC上的单独文件夹中。请帮助使用Python脚本/代码。我能够看到来自所有四个Arduino的消息,但无法将它们保存到文......
  • 使用 Python 生产者和消费者在 Kubernetes minikube 上设置 Kafka Kraft
    我正在尝试从kubernetes集群外部连接到kubernetesminikubekafkapod。服务器启动没有任何问题,但我无法设法将本地kafka生产者/消费者连接到外部kafkapod。在集群内的kafka服务器映像上,我将bootstrap-server设置为:bin/kafka-topics.sh--create--bootst......
  • python llama_index.indices.list.retrievers 导入错误
    fromllama_indeximportGPTListIndexfromllama_index.indices.list.retrieversimportListIndexLLMRetrieverdocuments=SimpleDirectoryReader('./data').load_data()index=GPTListIndex.from_documents(documents,service_context=service_context)r......
  • 如何使用 python 和 bs4 修复抓取 web 表输出 csv
    请帮帮我,,我想在“td”、“Barcode”和“namaproduk”中获取2个数据,但我得到的数据非常糟糕。我应该修复什么?importcsvimportrequestsfrombs4importBeautifulSoupoutfile=open("dataaa.csv","w",newline='')writer=csv.writer(outfile)page=0whilepag......
  • 基于Django的超市小程序+47822(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫、APP、小
    基于django超市小程序摘 要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,超市小程序被用户普遍使用,为方便用户能够可以随时进行超市小程序的数据信息管理,特开发了基于djan......
  • 【优秀python django系统案例】基于python的医院挂号管理系统,角色包括医生、患者、管
    随着信息技术的迅猛发展,传统的医院挂号管理方式面临着效率低下、排队时间长、信息不对称等诸多问题。这些问题不仅影响患者的就医体验,也加重了医院工作人员的负担。在此背景下,基于Python的医院挂号管理系统应运而生。该系统旨在通过信息化手段优化挂号流程,提高管理效率,提升医疗......
  • Python-PLAXIS自动化建模技术与典型岩土工程
    原文链接:Python-PLAXIS自动化建模技术与典型岩土工程https://blog.csdn.net/2301_78164062/article/details/140607885?spm=1001.2014.3001.5501一:Plaxis软件及PlaxisPythonAPI环境搭建1、Plaxis2D\Plaxis3D软件2、面向对象编程语言Python及其开发环境Spyder3、Plaxis输......
  • 在Conda环境中安装python内核
    我刚刚开始使用jupyter笔记本进行我的开发过程。我首先创建一个新的python环境:$condacreate-ntestenv然后激活它:$sourceactivatetestenv并安装python内核模块:$pipinstallipykernel现在,模糊性开始了。我只想专门为我的活动环境创建一个新内核。......