爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)

文章目录

  • 一、常见非指纹built-in函数
  • 二、三元表达式:
  • 三、函数内的内置arguments参数
  • 四、位运算符和逻辑运算符
    • 1、位运算符
    • 2、逻辑运算符
    • 3、jsfuck
  • 五、js混淆,伪代码,操作都有哪些
    • 1. 自执行函数嵌套执行 function(a, b){}(fn1,fn2)
    • 2、变量名混淆
    • 3、函数名不一致(1.构造函数 2.重新复制)
    • 4、三元表达式
    • 5、流程平
    • 6、打包
    • 7、控制流平坦化
    • 8、 重构解释器
  • 六、JS反爬原理
    • 1、反爬虫设计要求
    • 2、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


javascript很熟的话,直接跳过前面部分
下面罗列出,混淆,加密会用到的一些方法,手段!!!!!!!!!!!!

一、常见非指纹built-in函数

  1. js加密,数组偏移等一些骚操作,就是通过push,unshift等一些列操作合成加密,如有一个数据表 [‘data’,‘data2’],那么正常来说[0]代表值就是"data",那么从服务端返回数据后,如[0,1] 进行数组偏移 +500 [500,501] ,然后,仅仅凭这个数组,根本不知道索引的数据表值是什么
  2. 自实现eval函数等都会用到,比如,将一个函数复制给一个变量c,那么 eval(c)就调用了函数
  3. 了解定时器,可能存在,定时更新cookie等操作,就得观察定时器函数
  4. 加密请求参数,url,等操作也是,需要调试看懂,可以通过非指纹built-in方法
  • 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
    
  • decodeURIComponentencodeURIencodeURIComponent:加密解密

    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:相关操作

    • unshift:在数组前面添加一个元素
    • shift:删除数组内指定元素,若有多个相同的,默认删除第一个
    • pop:删除数组最后一个元素,并返回这个元素
    • concat:合并数组并返回,可以传参多个数组,没有去重功能
    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、splice、split (splice改变原数组,slice:不改变原数组)
    • 查找:substring、substr
    • 合并:concat

    拆分

    // 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 //解码操作
    
  • setTimeoutsetIntervalclearTimeout:定时器

    // setTimeout:延迟多少多少秒时间执行一次
    // setInterval:按照时间间隔一直执行
    // clearTimeout:清除定时器
    setTimeout(function(){}, 500)
    

二、三元表达式:

js加密很多手段,会借助三元表达式,进行操作,让读的人非常困难

条件 ? 为正返回结果:为假返回结果
a > b ? c : d // a 大于 b 吗?大于的话返回c,反之 d
  • 基本的使用
    在这里插入图片描述
  • 稍微加深
    爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第1张图片
  • 一般来算,三元表达式会多嵌套使用,就算俄罗斯套娃~~
二层嵌套 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 对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:

arguments.callee:指向当前执行的函数(在 严格模式 下,第5版 ECMAScript (ES5) 禁止使用)
argunments.length:指向传递给当前函数的参数数量

严格模式下,剩余参数、默认参数和解构赋值参数的存在不会改变 arguments对象的行为,但是在非严格模式下就有所不同了

  1. 这种加密情况,就是想混淆返回
    爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第2张图片
  2. 其实ES6给了新的rest参数,用在函数最后,多余的参数以数组的形式交给变量rest,如果传入的参数未填满函数定义的参数,rest会是一个空数组,这种也能做手脚
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 []

四、位运算符和逻辑运算符

  • 位运算符有 7 个,分为两类
    • 逻辑位运算符:位与(&)、位或(|)、位异或(^)、非位(~)
    • 移位运算符:左移(<<)、右移(>>)、无符号右移(>>>)

1、位运算符

爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第3张图片
爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第4张图片

2、逻辑运算符

爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第5张图片

3、jsfuck

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)')

爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第6张图片

五、js混淆,伪代码,操作都有哪些

那么通过文章,一、二、三、四小节可以引出以下(不完全)的混淆加密方法,骚操作

  1. 自执行函数嵌套执行 function(a, b){}(fn1,fn2)
  2. 变量名混淆:_0x319289 _$SW Oo0o00o0 a b c
  3. 函数名与不一致原因(1.构造函数、2. 重新赋值)
  4. 三元表达式嵌套
  5. 控制流平坦化
  6. 打包
  7. 魔改加密包
  8. 重构解释器
  9. 剩下后面文章

1. 自执行函数嵌套执行 function(a, b){}(fn1,fn2)

利用fn1,fn2两个函数的返回值当做a,b传入进去

2、变量名混淆

一般都不用管,直接分析也可以
可以通过AST,递归就能解决

3、函数名不一致(1.构造函数 2.重新复制)

爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第7张图片
那么如何确定呢,就通过 new c( 这样的方式去找函数入口,不一定找的到

4、三元表达式

前面提到了

5、流程平

6、打包

现在很多JavaScript代码的发展,很多都不是自己写的,都是用原生的,就是单纯的打包,提高运行速度,自带了一些混淆,
导致分析增加难度

7、控制流平坦化

将简单的流程复杂化,跳来跳去

简单的控制流:

  • 常见if
  • switch

程序自顶向下运行,执行的顺序很平坦,不会来回跳跃

function abc(){
    a = 1;
    a  = a+1;
    a = a + 123;
    console.log(a);
}
undefined
abc() // 125

爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第8张图片
将简单的事情复杂化
爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第9张图片

8、 重构解释器

对js的内置的方法,进行了重改,国内网站很少见到

六、JS反爬原理

1、反爬虫设计要求

(风控爬虫,既一个用户不可能在一个小时内,访问上百万次,不同类型店铺)

反爬虫的两大基本要求和问题:

  1. 让浏览器正常访问
  2. 让爬虫脚本无法访问
  3. 不影响用户体验
  4. 能严重阻止爬虫工程师的编程难度

那么从爬虫,执行脚本程度要处理到发送请求,拿到数据

对于浏览器而言,就需要将请求响应后的数据,通过css+js渲染执行到浏览器显示,因此在这些部分就能做很多操作
爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第10张图片

2、JS反爬手段的特点

  1. cookie加密
    翻页,或者一定条件,出现set-cookie操作,或者刷新cookie
  2. 参数加密
    翻页的时候url参数是变化的,url加密,每次fiddler重放攻击还不行,比如url拼接了一个奇怪的参数
  3. headers加密
    明显反爬特点:sign safe,abcde 乱码等 fnesewq123

七、爬虫逆向方法论

本篇文章结合前面两篇文章

爬虫(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

得出如下结论:

目标数据接口,进行重放攻击(重复请求)

  1. 重放攻击成功
    1. 成功,自行模拟其它参数再请求同一个,成功略过,
    2. 失败原因(IP检测、模拟请求参数格式错误、等等,后续完善此方法论)
    3. 一段时间内成功【是否请求url拼接的参数有变化,就要寻找加密参数,刷新cookie?headers中某个字段变化生成?XX参数等等】
  2. 重放攻击失败
    1. 寻找加密参数

爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)_第11张图片

你可能感兴趣的:(爬虫逆向-javascript,javascript,js,python,web,加密解密)