我去!爬虫遇到JS逆向AES加密反爬,哭了

大家好,我是辰哥~

今天准备爬取某抑云音乐时,遇到『JS逆向AES加密』反爬。比如这样的:

在发送请求获取数据时,需要用到参数params和encSecKey,但是这两个参数经过JS逆向AES加密而来。

既然遇到了这个情况,那么辰哥就教大家如何去解决这类反爬(JS逆向AES加密

01

网页分析

在开始分析JS逆向AES加密之前,先简单介绍一下要爬取的内容:下载某抑云音乐。其中获取歌曲的真实播放地址m4a的过程涉及到JS逆向AES加密

下面以其中某一首歌为例,讲解如何获取真实播放地址m4a

https://music.163.com/#/song?id=447926067

点击播放,在浏览器中查看抓取到的数据包,如下图所示:

查看响应数据:

可以看到在url字段中存储着真实播放地址,放到浏览器中打开:

可以看到正常播放,说明歌曲的真实播放地址获取正确。

通过python代码模拟刚刚的数据包

import requestsurl = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='headers = { 'origin': 'https://music.163.com', 'referer': 'https://music.163.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}data = { 'params':'kfrpgkCxCqTasItEhNe7042j8xNS7nalB11d9wFaUoezjOuCIDNGoLHPpk07nLyJZ+djempygeNwT9cNTevt+EPoIh7PIt4azw1PCpqATmDINbItDAvRFlNsxD/U2qcklFs6dYKbfv7XNINTN9flwQ==', 'encSecKey':'d24731778bf850f62c59c42b26f48250aec066cc880d15a8481921bb71f73ce02578490065e3c2a7310d8eb3d7a7c4813f9caaa008bdb4b8a4d3473362ec411d259db25adbbe67cad9fe2ae60a090d3d7893e3b8c369c034285fe9e60a93310557a9f09834eceafb73558ba400099184fc318af5f55aa68b77d148ab4688073e',}response = requests.post(url, headers=headers, data=data).json()print(response)

正确返回:

代码中唯一变的就是data,data里面包含两个参数(params和encSecKey),根据辰哥的经验,这八九不离十是经过JS加密而来,并且肯定跟歌曲的地址有关(浏览器页面地址,非真实播放地址)

02

JS逆向过程

既然知道这两个参数是js逆向加密而来,那直接搜索这两个参数存在于哪个js文件中。

搜索到了5个js,那么就查看这两个参数都同时存在于哪个js中,刚好在第一个js中就看到了。

可以看到params对应的是encText,encSecKey对应的是encSecKey。encText和encSecKey来自于bUE3x,而bUE3x来自于window.asrsea。

var bUE3x = window.asrsea(JSON.stringify(i3x), bsf6Z(['流泪', '强']), bsf6Z(WS0x.md), bsf6Z(['爱心', '女孩', '惊恐',并以某抑云'大笑']));

继续搜索window.asrsea

可以看到window.asrsea来源于d,d是一个函数,该函数中返回的h赋值给window.asrsea。这里我们给函数d打断点

点击刷新网页,重新播放

可以看到函数d需要传入四个参数,通过分析多首歌曲,分析参数e、f、g没变化,唯一变是参数d中的id

这个id刚好是歌曲的id

https://music.163.com/#/song?id=447926067

函数d接收到四个参数后,创建一个字典h(用于存放变量),接着调用函数a,我们继续给函数a打断点。

刷新网页

函数a的作用就是生成一个16为的随机数,下面是函数a运行后最终的参数值,其中c是返回值,因此我们可以认为c是一个固定的值(反正也是随机生成的)

a: 16b: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'c: 'z2Ggtvz5ZIsiKO5F'

函数a解析完了,继续分析函数d。

function d(d, e, f, g) {        var h = {}          , i = a(16);        return h.encText = b(d, g),        h.encText = b(h.encText, i),        h.encSecKey = c(i, e, f),        h}

接着经过两次AES加密(执行了两次函数b)

function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse('0102030405060708') , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString()}

需要传入参数a和b,实际上就是函数d中的参数d和g,参数g是固定的,参数d我们刚刚已经分析过了。

一开始分析的两个js逆向参数(params和encSecKey)的parmas我们已经清楚了加密过程(encText就是params)

接着函数d继续看

h.encSecKey = c(i, e, f),

encSecKey是通过函数c得到,函数c的代码如下:

function c(a, b, c) { var d, e;        return setMaxDigits(131), //131 => n的十六进制位数/2+3   d = new RSAKeyPair(b,'',c), e = encryptedString(d, a) }

函数c:通过RSA加密生成encSecKey值。

OK,JS逆向加密分析的过程就完成了。

03

模拟加密过程

分析完加密过程,能够通过代码去实现也是重要的一环

1.AES加密

# AES加密def AES_encpyt(text, key):    '''AES加密'''    # AES加密明文必须为16的整数倍    padding = 16 - len(text.encode()) % 16    text += padding * chr(padding)    aes = AES.new(key.encode(), AES.MODE_CBC, b'0102030405060708')    enctext = aes.encrypt(text.encode())    return b64encode(enctext).decode('utf-8')

创建一个AES的加密函数,传入值text和key就可以返回加密值

2.构造表单

在发送请求过程中,需要传入表单,参数格式如下:

加密得到params和encSecKey后需要构造成上述格式的表单:

# 构造表单def make_form(text): data = { 'encSecKey': '526fa53a5d1d9ba3de5fe30592c98aa95b843ca026618c8ad2067183ec172a8262b6cd1b5000c84b8223525bfca0cfb61808d21040f9a46afdc5dbdea554a714f336e6a63adcc5340b9e1f3ca923e00e1b6352b2ec8e995401267a2d4fd037f3189c6c96179b7eef9ee16cbb2c896c913a33b9fed32496cd01965621a104f7b3' } # 随机秘钥参数,可以用固定值 i = 'Ba6Xk3DAhfidcpqA' key = '0CoJUm6Qyw8W8jud' # 两次加密 first_encrypt = AES_encpyt(text, key) data['params'] = AES_encpyt(first_encrypt, i) # 返回构造好的表单数据 return data

make_form需要传入的参数text内容如下:

text = '{'ids':'[歌曲id]','level':'standard','encodeType':'aac','csrf_token':''}'

通过改变歌曲id即可获取到对应的真实播放地址,比如:

text = '{'ids':'[447926067]','level':'standard','encodeType':'aac','csrf_token':''}'

3.发送请求

url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='headers = {    'origin': 'https://music.163.com',    'referer': 'https://music.163.com/',    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}response = requests.post(url, headers=headers, data=make_form(text)).json()print(response)

其中 make_form(text)就是调用加密的函数。

返回结果:

04

小结

辰哥在本文中主要讲解了『JS逆向AES加密』反爬,并以网抑云获取歌曲真实播放地址为例去实战演示分析。

不明白的地方可以在下方留言或者后台加辰哥微信,一起交流。

(0)

相关推荐

  • 编程语言【JS 逆向百例】如何跟栈调试?某 e 网通 AES 加密分析

    逆向目标 目标:某 e 网通登录接口 主页:aHR0cHM6Ly93ZWIuZXd0MzYwLmNvbS9yZWdpc3Rlci8jL2xvZ2lu 接口:aHR0cHM6Ly9nYXRld2F5Lm ...

  • httprunner学习23-加解密

    前言 有些接口的请求参数是加密的,返回的接口内容也是需要解密才能看到. 加密接口 比如当我们访问下面这个登陆的接口时,请求参数账号和密码都是需要加密,通过parms参数传过去,服务器才能识别到 没加密 ...

  • 126邮箱分析过程

    赠书活动今天结束,师傅们还可参与-获到书的人13号18点中留言中回复. DDOS攻击防护--[文末赠书] 首先到126邮箱登录页面,我们随便输入字符.然后点击登录,抓到一个POST地址 https:/ ...

  • PHP的OpenSSL加密扩展学习(一):对称加密

    PHP的OpenSSL加密扩展学习(一):对称加密 我们已经学过不少 PHP 中加密扩展相关的内容了.而今天开始,我们要学习的则是重点中的重点,那就是 OpenSSL 加密扩展的使用.为什么说它是重点 ...

  • 一个反爬 JS 逆向分析的例子

    定位加密点 在某网站中进行登录请求: 简单抓下包,点击登录按钮之后,可以在浏览器的控制台中看到相关的请求: 接着往下拉,可以看到 POST 请求的参数信息: 从中可以看出,除了 username 中的 ...

  • python爬虫 - js逆向解密之简单端口加密破解v2 -- 修复版

    这篇跟上一篇很像,而且他的端口显示也很类似,是的,它也是一个国外的代理网站 分析 打开网站查看: 发现它的的端口和之前的网站一样,不是直接显示的,那么用SmallProxy这个关键词搜索下在哪,很快就 ...

  • python爬虫反反爬 | 像有道词典这样的 JS 混淆加密应该怎么破

    嘿嘿嘿,小帅b又来跟你说说一些爬虫过程中需要斗智斗勇的事情了,这次咱们就来说说关于一些 JS 混淆加密的事.所谓 JS ,就是 JavaScript ,一种前端的脚本语言,一般情况下每个网站都需要 J ...

  • JS逆向-抠代码的第四天【手把手学会抠代码】

    今天是md5巩固项目,该项目比昨天的复杂一些,但方法思路是一样的. 今天的目标:https://www.webportal.top/ 接下来,就是解析pwd的加密方式,通过全局所搜,可以出如下结果: ...

  • Python 的AES加密与解密

    AES加密方式有五种:ECB, CBC, CTR, CFB, OFB 从安全性角度推荐CBC加密方法,本文介绍了CBC,ECB两种加密方法的python实现 python 在 Windows下使用AE ...

  • 使用Python对数据进行AES加密和解密

    随着网络上爬虫的横行和猖獗,各大网站为了最大限度地限制自家数据被采集,纷纷加入了各种反爬手段,比如: 生成浏览器UA指纹识别: 用各种验证方式(短信.滑块.点选汉字.点击)进行识别: -- 这一类的反 ...

  • Hive 自定义UDF函数实现日期格式化和字段AES加密

    Hive 自定义UDF函数实现日期格式化和字段AES加密 自定义日期格式化UDF函数 自定义字段AES加密函数 函数的临时注册和永久注册 测试UDF函数使用 项目pom.xml 自定义日期格式化UDF ...

  • 【JS 逆向百例】DOM事件断点调试,某商盟登录逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:某商盟登录 ...

  • js逆向之另类思路扣代码

    海绵 日常学python 经常js分析的人来说有些网站检测浏览器指纹是很常见的事,但是我们一点一点分析是很费时间,费脑筋的. 我们扣代码的结果是我们要调用他的加密或解密或某个值的算法,当我们把他的算法 ...