爬虫-Javascript混淆技术

1、极简壁纸网址:极简壁纸_海量电脑桌面壁纸美图_4K超高清_最潮壁纸网站极简壁纸,4K高清电脑桌面壁纸图库,海量4K电脑壁纸,壁纸网站,美女,动漫,风景,4k高清,4k超清,电脑壁纸桌面icon-default.png?t=N7T8https://bz.zzzmh.cn/index

一、混淆简介

1、为什么要进行混淆

  1. 保护开发工程师源码
  2. 反爬
  3. js代码运行于客户端,它必须在用户浏览器端加载并运行
  4. js代码是公开透明的,也就是说浏览器可以直接获取到正在运行的javascript的源码

1、压缩、混淆、加密技术

代码压缩:

           去除js代码中的不必要的空格、换行等内容。使源码压缩为几行内容,降低代码可读性,提高网站的加载速度。

代码混淆:

            使用变量替换、僵尸函数、字符串阵列化、控制流平坦化、调试保护等手段,使代码变得难以阅读和分析,达到最终保护的目的,不影响代码原有功能,是理想、实用的javascript保护方案。

代码加密:

            可以通过某种手段将js代码进行加密,转成人无法阅读或者解析的代码,如将代码完全抽象化加密,如eval加密,.......

二、OB混淆。

ob混淆官网:JavaScript Obfuscator ToolJavaScript Obfuscator is a free online tool that obfuscates your source code, preventing it from being stolen and used without permission.icon-default.png?t=N7T8https://obfuscator.io/

两个代码,实现方式是一样的。

1、ob混淆的特点:

  1. 一般由一个大数组或者含有大数组的函数,一个自执行函数、解密函数和加密后的函数四部分组成。
  2. 函数名和变量名通常以_0x或者0x开头,后接1~6位数字或字母组合
  3. 自执行函数,进行移位操作,由明显的push、shift关键字

2、ob混淆结构

一般obfuscator 混淆的代码分为以下几部分

  1. 定义一个数组:
  2. 重构数组
  3. 自解密函数
  4. 真实代码
  5. 可以删除的垃圾代码

3、ob混淆介绍

Javascript混淆完全是在javascript上进行的处理,它的目的就是使得javascript变得难以阅读和分析,大大降低代码可读性,是一种很实用的javascript保护方案。

Javascript混淆技术主要有以下几种

1、变量混淆:

2、字符串混淆:

        进行MD5或base64加密存储,使代码中不出现明文字符串,可以避免使用全局搜索字符串的方式定位到入口点。

3、属性加密:

4、控制流平坦化:

        打乱函数原有代码执行流程及函数调用关系,使代码逻辑变得混乱无序。

5、僵尸代码:(假代码)

        随机在代码中插入无用的僵尸代码、僵尸函数,使代码逻辑变得混乱

6、调试保护:

        加一些强制调试debugger语句,使其在调试模式下难以顺利执行js代码。

7、多态变异:

8、锁定域名:

        使js代码只能在指定域名下执行

9、反格式化,

        如果对js代码进行格式化,则无法执行,导致浏览器假死

10、特殊编码:

表情符号,特殊表示内容等

4、实现ob混淆

1、安装ob混淆库:npm install javascript-obfuscator -g(-g是安装到全局)

npm install javascript-obfuscator -s
安装完成后,javascript-obfuscator就是一个独立的可执行命令了。

三、案例一-极简壁纸_逆向分析

1、逆向目标

网址:极简壁纸_海量电脑桌面壁纸美图_4K超高清_最潮壁纸网站极简壁纸,4K高清电脑桌面壁纸图库,海量4K电脑壁纸,壁纸网站,美女,动漫,风景,4k高清,4k超清,电脑壁纸桌面icon-default.png?t=N7T8https://bz.zzzmh.cn/index

目标:result `ak+9VCsq4dEdB+UdVfGo8kh5JDEbMHGTCmF/`

2、逆向分析

1、XHR断点,点击页数发包,ajax错误的回调。(这是一个ajax错误请求的发包)

2、在调用堆栈分析,从上往下找,直到找到ajax发包的位置。

post、then关键字

进入该方法:

进入第三个方法的内部:

2.1分析解密数据 

1、分析代码:(对数据解密的代码)

扣代码结果:

2.2 分析壁纸信息

1、清空浏览器发包数据,清除断点,点击壁纸重新发包。

这里的数据其实是一样的。

重定向多半会响应一个location

2、复制python代码,结果报错

1、怎么获取响应头的location

禁止当前请求地址跳转

需要注意当前参数,后面都跟着一个21,所以需要在代码里面拼接上,才能执行代码成功输出Location

注意:后面报错,可能是壁纸文件夹没有创建。

2、源代码:
import requests
import execjs
class JiJian():
    def __init__(self):
        #1.请求头
        self.headers = {
            "referer": "https://bz.zzzmh.cn/",
            "user-agent": "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320"
        }
        #2 .请求网址
        self.url = "https://api.zzzmh.cn/bz/v3/getData"
        # 3.js文件进行初始化
        self.js = execjs.compile(open('06-极简壁纸.js', encoding='utf-8').read())
    def get_data(self):
        #4.发上请求需要跟上对应的参数。???数据哪里来的
        data = {"size":24,"current":11,"sort":0,"category":0,"resolution":0,"color":0,"categoryId":0,"ratio":0}
        #发送请求
        response = requests.post(self.url, headers=self.headers, json=data)
        return response.json()
    def parse_data(self, response):
        #5.解密数据
        res = self.js.call('_0x58b5da', response['result'])
        print(res)
        for i in res['list']:
            #6、拼接新的网址
            # print(i['i'])
            res = requests.get('https://api.zzzmh.cn/bz/v3/getUrl/' + i['i']+"21", headers=self.headers, allow_redirects=False)
            print(res.headers)
            self.save_data(res.headers['Location'], i['i'])
    def save_data(self, img_url, name):
        with open('壁纸/' + name + '.jpg', 'wb')as f:
            result = requests.get(img_url, headers=self.headers)
            f.write(result.content)
            print('正在下载{}'.format(name))
    def main(self):
        res = self.get_data()
        self.parse_data(res)
if __name__ == '__main__':
    jj = JiJian()
    jj.main()

运行成功

3、解除无限debugger
Function.prototype.__constructor_back = Function.prototype.constructor;
Function.prototype.constructor = function() {
    if(arguments && typeof arguments[0]==='string'){
        if("debugger" === arguments[0]){
            return
        }
    }
   return Function.prototype.__constructor_back.apply(this,arguments);
}

四、案例二-产业政策大数据平台

1、逆向目标

名称:octet-stream指任意类型的二进制流数据。

地址:http://www.spolicy.com/

http://www.spolicy.com/

参数:

2、逆向分析

1、网页一打开就有一个无限debugger,可以判断这个网址是OB混淆自动防护。

2、点击下一个栈分析数据

3、观察传递的两个参数是什么。(通过构造器创建debbuger的信息)

4、注意ob混淆无限debbuger,可能会导致你的网站很卡。因为ob会不断生成,我们需要置空,用【解除无限debugger】代码在控制台运行即可.

5、分析发包内容。点击发包

6、具体传什么参数,和标头请求头有关系。

这传递的其实是一个进制内容。byte.

如果是请求载荷就传json,但是最准确的是看content-Type.

那载荷数据是怎么生成的呢。

7、触发XHR(加断点),请求的是当前的r、r是一个byte内容

8、我们需要定位这个byte数据是在哪里生成的。看它发包的位置,看数据是不是一个明文。

9、可以看到已经是加密的,可以判断是在上一步生成的。e的值是加密的,下个断点看一下。

这种情况,可能会在哪里进行加密。

三种情况

  • 可能是在异步中间的代码生成的。
  • 要么就在请求的拦截器里面(概率大一些)
  • 或者是在之前的代码中生成的。
找拦截器的方式

1、先找响应拦截器。(会容易一些)往下调试,找响应拦截器的位置。要多注意观察Intercepors

2、还是关注有没有axios关键词旁边有没有interceptors

跳出当前函数

3、请求拦截器也可以找该关键字。下个断点,重新发包

在请求拦截器里面是明文,加密多半是在拦截器里面生成的。

正常网站都是先考虑拦截器的问题。

4、下一步调试,数据如果还是明文就下一步。

5、后面又把数据赋值给了r    观察r

6、说明在上面部分进行了加密。

7、分析各部分。

8、分析第一个部分

9、这其实是一个VM文件,VM文件后面会讲。

m传递的是一个数组

2、扣代码一
  1. PolicyInfoByTypeIdParam$encode
    
  2. w为underfined  ,if(!w)这部分可以删掉
  3. copy(m)
  4. 调用PolicyInfoByTypeIdParam$encode(m)
  5. 运行报错: Writer is not defined
  6. 点击writer.create
  7. 赋值这个js文件里面全部的代码,找到 return new d
  8. 现在需要找到调用这个js代码的位置。 
  9. 看【return new d】这个方法是包含在哪里的。
  10. 再往上走,发现包含在一个自执行方法中。把这个自执行方法放到自己需要分析的代码中。扣方法的时候不单单只扣方法,还可以扣整个js代码。
  11. 我们需要的代码在38方法里面,说明这里是一个加载器。是一个webpack打包的方式。
  12. 通过下面的一些参数可以判断i是一个webpack的加载器。
  13. 调用-  var  aaa;      把i赋值给aaa 输出aaa, 不用调用i,因为i是自执行的方法。                       之前调用加载器的时候一般是aaa('1111'),现在不需要写东西。
  14. 运行报错:commonjsGlobal is not defined     ,在网页js代码里面找commonjsGlobal。找到该参数打断点,分析该参数是什么。有问题是我可能不会触发这个断点。
  15. 为什么不会触发这个断点。(因为这个方法已经被初始化过了,刷新才会执行当前方法。
  16. 在随便断住的时候,在控制台输出commonjsGlobal。当前数据就是window对象的赋值。补window即可,加window = global;
    commonjsGlobal = window;
    即可
  17. 输出报错:aaa is not a function  改aaa()  为aaa,aaa不要调用。输出了数据,说明aaa已经获取到了i的值。
  18. 输出报错:Writer is not defined,我其实是现在有这个方法的  需要通过aaa调用
  19. 我们扣代码需要扣的多一些,看是不是有自执行方法和加载器
3、扣代码二、三

4、怎么调用加载器数据

导出到aaa

需要定义var aaa;

aaa=i;

输出aaa

5、python怎么调用。
5.1、爬虫工具库网址:

爬虫工具库-spidertools.cn爬虫工具库-spidertools.cn 是专为爬虫工程师打造的在线工具库,集合了爬虫工程师常用的工具,如json格式化、header格式化、cookie格式化、curl转python等,致力于提高爬虫开发效率icon-default.png?t=N7T8https://spidertools.cn/#/

5.2、源代码
import  requests
import execjs
class dsj():
    def __init__(self):
        self.url = 'http://www.spolicy.com/info_api/policyType/showPolicyType'
        self.headers = {'User-Agent':'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320',
                       'Content-Type':'application/octet-stream'
                        }
        self.data = {
    "policyType": "4",
    "province": "",
    "city": "",
    "downtown": "",
    "garden": "",
    "centralId": "",
    "sort": 0,
    "homePageFlag": 1,
    "pageNum": 1,
    "pageSize": 7
}
        self.js = execjs.compile(open('08-产业政策大数据平台.js',encoding='utf-8').read())
    def request_data(self):
       data =  self.js.call('PolicyInfoByTypeIdParam$encode',self.data)
       print(data)
       res = requests.post(self.url,headers =self.headers,data=bytes(data['data']))
       print(res.text)

if __name__ == '__main__':
    ds = dsj()
    ds.request_data()

  • 31
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值