爬虫——记一次破解前端加密详细过程

2020-11-23 09:11:07

参考地址 爬虫——记一次破解前端加密详细过程

摘要:工作差不多快一年了,应工作需要爬过各种各样的航空公司网站,大到B2B平台,小到东南亚某某航空官网,从最初使用webdriver+selenium爬虫到现在利用http请求解析html,经历过各种各样的问题,webdriver+selenium这种办法虽然万能,而且可以用JS写解析脚本方便调试,但是用久了才发现这玩意不管是效率还是稳定性都非常差,放到服务器上动不动就挂掉,两三天就需要重启一次。后面头说让我们改用发http请求(我第一次接触项目的时候就在想为什么不直接用发http请求这种方式,我猜他也是第一次接触爬虫这个技术领域,没什么经验。而我,本来是招JAVA进的公司,后来JAVA、JS、Python写了个遍,emmm...     没事,反正技多不压身 ^_^),这种方式稳定且快,但是用Python编写解析脚本的时候你就知道进行调试有多烦,虽然可以用PyQuery或者BeautifulSoup这种解析库,但是还是不如写JS脚本在浏览器里调试来得舒服。

进入爬虫主题

要爬取的官网https://www.jcairlines.com

接口地址https://www.jcairlines.com/TicketSale/FlightQuery/QuerySeat

目标:根据参数爬取对应的航班信息

请求信息:

响应结果:

接口测试

从上面的第一张图可以看到有一个类似加密过的参数:HashCode,而其他的都是根据需要进行直接填充

{"DepartureIataCode":"TPE","ArrivalIataCode":"PNH","FlightDate":"2018-08-24","RouteIndex":"0","TravelType":"OW","HashCode":"8b112088f6966ea42507d0daff86a1d1"}

下面将这个请求的完整信息放到Postman中跑一下,看看结果:

可以看到是没有问题的,能拿到结果,下面我们准备把HashCode去掉再请求一遍

emmm...   直接不响应!!!

好吧,搞定这个问题就需要破解这个加密参数是怎么来的

正式破解

【逆向思维】这个肯定是Ajax请求之前生成的,那就用关键字找这个Ajax请求, 在Chrome中开发者模式,找到这网站的所有Source

【关键字】"QuerySeat" 一大堆js文件一个一个找吧,运气很好,第一个就是,可以清楚的看到“POST”一词,那这一定就是一个Ajax请求咯,这里有一个技巧,一般情况下,服务器会对静态资源进行压缩,所以需要format才能看个大概

 

这样可以阅读代码了,然后轻松找到设置HashCode的地方,然后打一个断点,随便查一条航线的数据,如下图。

单步执行走到这一步,有些眉目了,执行到了encode指向的匿名函数这,里面代码看似应该是各种加密函数,不用读懂它,因为目标只是执行它,得到相应的结果就行了

继续单步:

继续...

上图中重要的源码:

return e = OOO0.excess.indexOf("Chrome") >= 0 ? "cv3sdf@#$f3" : OOO0.excess.indexOf("Firefox") >= 0 ? "df23Sc@sS" : "vdf@s4df9sd@s2"

返回到上层,没错和我想的一样,当前浏览器是Chrome,返回的是 cv3sdf@#$f3

继续...

继续...

继续...

最终找到了这个匿名函数,复制encode所指向的函数,然后随便取一个名字,方便调用,另外,在另一个窗口中打开Console粘贴代码,如下图:

调用...(报错了)

替换成对应的字符串继续...

重新调用注入到Console 的encode函数,调用,得到结果!!!

对比最开始用Postman请求的地方,结果也一致!!!

还没有完,这里只是得到了js脚本,所以还需嵌入到Python代码中使用,常规方式有两种:使用Python第三方类库js2py和PyV8这两个都是能都执行js的Python类库,但是我还是推荐使用js2py,因为PyV8安装十分繁琐,具体使用我就不再赘述,网上有很多的教程和Case。

最后需要交代的:“sfei#@%%”这的到底是哪来的,也没有寻根,我就直接告诉答案,其实这个值就在当前的网页中,是一个js变量,且是一个固定值,这也是我不想寻根的原因,意义不大。另外在使用http爬虫的时候headers里面的内容也必须和HashCode相匹配,什么意思呢,之前代码出现过通过浏览器种类,生成不同的字符串,也就是说具体HashCode是和浏览器有关,所以在构造headers时需要填写对应的User-Agent,不然服务器进行校验的时候还是不会响应的,可以猜测服务器中也有一段功能相同的代码,它根据请求参数和headers中User-Agent进行加密计算,得到HashCode以此来验证请求的HashCode是否合法。

总结:前端加密还是能够破解出来的,关键在于锁定JS加密源码位置,并且提取出有用的加密代码,只要有使用过js的同学问题都不大。还有很多小细节得注意,服务器需要对请求做进一步验证,方式其实和前端是一样的以此来判断请求是否合法,至少这个网站是如此。


  • 2021-02-03 16:52:27

    ios静态库和动态库区别

    Framework 是 Cocoa/Cocoa Touch 程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件(nib/xib、图片、国际化文本)、说明文档等集中在一起,方便开发者使用。Framework 其实是资源打包的方式,和静态库动态库的本质是没有什么关系。

  • 2021-02-03 16:57:34

    iOS中的动态库和静态库分析

    由于最近研究组件化后调试时二进制映射源码的功能,发现需要对开发中的动态库和静态库需要有一些了解。所以就有了这篇文章,由于只是了解,并没有深入到编译层面,所以本篇文章只是简单了解一些库的知识,并不深入。

  • 2021-02-03 16:58:39

    iOS静态库与动态库的区别与打包

    这篇主要是记录一下 iOS 下静态库与动态库的打包流程,以便以后用到时快速查阅,供自己也供大家学习记录。同时也简述了一下 动态库 与 静态库 的区别。

  • 2021-02-03 16:59:59

    iOS 静态库和动态库全分析

    库就是程序代码的集合,将 N 个文件组织起来,是共享程序代码的一种方式。从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。

  • 2021-02-03 17:01:30

    iOS库 .a与.framework区别

    静态库:连接时完整地拷贝至可执行文件中,被屡次使用就有多份冗余拷贝。 动态库:连接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。

  • 2021-02-03 17:13:58

    iOS - 封装静态库

    静态库:链接时完整的拷贝至可执行文件中,被多次使用就有多份冗余拷贝,.a的静态库 .framework的静态库

  • 2021-02-03 17:16:07

    iOS 中的动态库、静态库和 framework

    首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件。另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间。

  • 2021-02-03 17:17:53

    iOS 同一个工程下打包不同的app

    应用图标,启动画面,应用启动后的首页都不一样。 有些课程(例如公务员考试和高考)是有目标考试的概念,不同的目标考试大纲是不一样的。拿高考来举例,北京的高考和上海的高考,就有着完全不一样的考试大纲。高考的文科和理科,又有着完全不同的考试科目。 有些课程会有一些自定义的界面,例如高考的应用可以设置昵称,有些课程的真题练习中是有推荐真题模块的,而有些课程又没有。 有些课程有扫描答题卡功能,有些课程有考前冲刺功能,有些课程有大题专项查看功能,而有些课程又没有上述功能。另外还有一些微小细节,但是解决方法和类似,所以就不一一展开说明。

  • 2021-02-04 14:02:30

    window软件界面找不到了跑到屏幕外面去了

    一般可以这样操作,按Alt+空格,然后按M,然后用上下左右键把窗口移动到能看到的地方,再按回车。有些第三方的软件可能不能用,大部分都可以这样做。