希望点个赞!
如果本文有任何问题错误,欢迎评论指正!
前面文章:
爬虫(js逆向)网络基础协议与抓包原理-chrome开发工具-fiddler抓包-重放攻击(1)
https://blog.csdn.net/weixin_44238683/article/details/118468491
爬虫(js逆向)js基础-函数进阶-原型链(prototype、proto、构造函数-this绑定对象(2)
https://blog.csdn.net/weixin_44238683/article/details/118503753
eval(c)
就调用了函数unescape
:解码方法
ECMAScript v3 已从标准中删除了 unescape() 函数,并反对使用它,因此应该用 decodeURI() 和 decodeURIComponent() 取而代之
unescape('hello%20稳稳%21')
Function
:函数实例方法
var fun = new Function("a", "return a") //前面是形参,后面是返回的内容
等价于
function fun(a){
return a
}
eval
:把字符串当做js代码执行,并且会执行一个虚拟机
eval('alert("12312312")')
Array
:数组对象
arr = new Array()
Object
:对象
person = new Object()
Date
:内置时间方法
Date()
"Tue Jul 06 2021 22:33:02 GMT+0800 (中国标准时间)"
a = new Date() // 实例化一个对象
Tue Jul 06 2021 22:33:09 GMT+0800 (中国标准时间)
a.getDate() // 实例化对象后,可以使用对象的内置方法
6
RegExp
:正则匹配的方法
https://www.runoob.com/jsref/jsref-obj-regexp.html
常用
test()判断是否符合要求,返回True或者false
exec()返回数组形式
match()返回第一个匹配对象
//1、定义正则对象,qq邮箱
var re = /^\d{5,12}@qq\.com$/
//2、test true,false
console.log(re.test("[email protected]"))
console.log(re.test("[email protected]"))
var msg = "hello1,world2"
var re = /[a-zA-Z]+/
console.log(re.exec(msg))
//字符串中也有方法支持正则,比如match
var msg = "hello1,World2"
// i忽略大小写,g全局
console.log(msg.match(/[a-z]+/ig))
indexof
:会返回索引值
indexOf() 方法可返回某个指定的字符串在字符串中首次出现的位置
indexOf() 方法可返回某个指定的字符串在字符串中首次出现的位置
数组使用
arr = ['cookie', 'ck', 'cck']
arr.indexOf('cookie') //会返回cookie的索引值 0
字符使用
var str="Hello world, welcome to the universe.";
var n=str.indexOf("welcome"); //13
hasOwnProperty
:检测一个属性是否是一个对象的自有属性
function F(){
this.name = "自有属性"
}
F.prototype.name = "继承属性"
var f = new F()
f.hasOwnProperty("name") //True
decodeURIComponent
、encodeURI
、encodeURIComponent
:加密解密
encode('a 2') // -> a%202
decodeURIComponent('a%202') // ->'a 2'
Math
:Math.random
四舍五入 Math.round
取整保留
Math.round(0.5) // -> 1
parseInt
:数据类型转换,还有很多
parseInt('1555') // -> 1555
parseInt(15.55) // -> 15
parseInt('15.55') // -> 15
Array
:相关操作
var arr = new Array()
arr.push(4)
arr.push(3)
arr.push(2)
arr.push(1)
-->[4,3,2,1]
arr2 = arr.concat(arr1, ar3) //合并数组,没有去重功能
String
:字符串操作
拆分
// slice() 提取字符串的某个部分并在新字符串中返回被提取的部分。
var str = "Apple, Banana, Mango";
var res = str.slice(7,13); //Banana
// splice() 指定起始位,删除位置,插入数据
var arr = new Array(6)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
arr[3] = "James"
arr[4] = "Adrew"
arr[5] = "Martin"
arr.splice(2,3,"William")
// split() 方法用于把一个字符串分割成字符串数组
var str="How are you doing today?"
console.log(str.split(" ")) //How,are,you,doing,today?
console.log(str.split("")) // H,o,w, ,a,r,e, ,y,o,u, ,d,o,i,n,g, ,t,o,d,a,y,?
console.log(str.split(" ",3)) // How,are,you
查找
// substring() substring() 类似于 slice()。不同之处在于 substring() 无法接受负的索引。
var str = "Apple, Banana, Mango";
var res = str.substring(7,13);// Banana
// substr() 类似于 slice()。不同之处在于第二个参数规定被提取部分的长度。
var str = "Apple, Banana, Mango";
var res = str.substr(7,6);//Banana
合并
//concat() 连接两个或多个字符串
var text1 = "Hello";
var text2 = "World";
text3 = text1.concat(" ",text2);
fromCharCode
charCodeAt
:字符串与ascii码转换
charCodeAt:把字符串转为ascii码
fromCharCode:把ascii码转变为字符串
atob
btoa
Uint8Array
ArrayBuffer
Int32Array
Int16Array
:与加密有关
btoa -> binary to ascii //编码操作
atob -> ascii to binary //解码操作
setTimeout
、setInterval
、 clearTimeout
:定时器
// setTimeout:延迟多少多少秒时间执行一次
// setInterval:按照时间间隔一直执行
// clearTimeout:清除定时器
setTimeout(function(){}, 500)
js加密很多手段,会借助三元表达式,进行操作,让读的人非常困难
条件 ? 为正返回结果:为假返回结果
a > b ? c : d // a 大于 b 吗?大于的话返回c,反之 d
二层嵌套 x = a > 10 ? 1 : a > 1 ? 2 : 3
三层嵌套 x = a > 10 ? 1 : a > 1 ? 2 : a > -5 ? 3:4
三层嵌套加赋值 a = a > 10 ? 1 : a > 1 ? 2 : a > -5 ? 3:4
三层嵌套加赋值加函数调用 错误情况1
function a(a){ a *= a};
a = a() > 10 ? 1 : a > 1 ? 2 : a > -5 ? 3:4
三层嵌套加赋值加函数正常调用 错误情况2
function a(a){ a *= a};
a = a(4) > 10 ? 1 : a > 1 ? 2 : a > -5 ? 3:4
三层嵌套加赋值加函数正常调用 正确情况
function a(a){ return a *= a};
a = a(4) > 10 ? 1 : a > 1 ? 2 : a > -5 ? 3:4
简单来说:
arguments 是一个对应于传递给函数的参数的类数组对象
arguments 对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:arguments.callee:指向当前执行的函数(在 严格模式 下,第5版 ECMAScript (ES5) 禁止使用)
argunments.length:指向传递给当前函数的参数数量在
严格模式
下,剩余参数、默认参数和解构赋值参数的存在不会改变 arguments对象的行为,但是在非严格模式下就有所不同了
function exm(a, b, ...rest) {
console.log('a = ' + a);
console.log('b = ' + b);
console.log(rest);
}
exm(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]
exm(1);
// 结果:
// a = 1
// b = undefined
// Array []
https://www.jianshu.com/p/e7246218f424
false => ![]
true => !![]
undefined => [][[]]
NaN => +[![]]
0 => +[]
1 => +!+[]
2 => !+[]+!+[]
10 => [+!+[]]+[+[]]
Array => []
Number => +[]
String => []+[]
Boolean => ![]
Function => []["filter"]
eval => []["filter"]["constructor"]( CODE )()
window => []["filter"]["constructor"]("return this")()
那么有些混淆加密
+!+[]
1
a = 'abcd'
"abcd"
eval(a[+[]] + 'lert(111)')
那么通过文章,一、二、三、四小节可以引出以下(不完全)的混淆加密方法,骚操作
利用fn1,fn2两个函数的返回值当做a,b传入进去
一般都不用管,直接分析也可以
可以通过AST,递归就能解决
那么如何确定呢,就通过 new c(
这样的方式去找函数入口,不一定找的到
前面提到了
现在很多JavaScript代码的发展,很多都不是自己写的,都是用原生的,就是单纯的打包,提高运行速度,自带了一些混淆,
导致分析增加难度
将简单的流程复杂化,跳来跳去
简单的控制流:
程序自顶向下运行,执行的顺序很平坦,不会来回跳跃
function abc(){
a = 1;
a = a+1;
a = a + 123;
console.log(a);
}
undefined
abc() // 125
对js的内置的方法,进行了重改,国内网站很少见到
(风控爬虫,既一个用户不可能在一个小时内,访问上百万次,不同类型店铺)
反爬虫的两大基本要求和问题:
那么从爬虫,执行脚本程度要处理到发送请求,拿到数据
对于浏览器而言,就需要将请求响应后的数据,通过css+js渲染执行到浏览器显示,因此在这些部分就能做很多操作
本篇文章结合前面两篇文章
爬虫(js逆向)网络基础协议与抓包原理-chrome开发工具-fiddler抓包-重放攻击(1)
https://blog.csdn.net/weixin_44238683/article/details/118468491
爬虫(js逆向)js基础-函数进阶-原型链(prototype、proto、构造函数-this绑定对象(2)
https://blog.csdn.net/weixin_44238683/article/details/118503753
得出如下结论:
目标数据接口,进行重放攻击(重复请求)