JS 逆向基础

1.JS作用域

在JavaScript中,作用域是指变量和函数的可访问范围。JavaScript中有两种作用域:全局作用域和局部作用域。
全局作用域是指在整个JavaScript程序中都可以访问的变量和函数,而局部作用域是指只能在函数内部访问的变量和函数。

2.浏览器对象属性

在JavaScript中,浏览器对象是指浏览器提供的一些对象,可以通过这些对象来访问和操作浏览器的各种属性和方法。以下是一些常用的浏览器对象属性:

  • window:表示当前浏览器窗口或标签页。
  • document:表示当前文档对象。
  • location:表示当前文档的URL。
  • navigator:表示当前浏览器的信息。
  • history:表示当前浏览器的历史记录。

3.浏览器控制台

浏览器控制台是开发者工具中的一个重要组成部分,可以用来调试JavaScript代码、查看网络请求、分析页面性能等。以下是一些常用的浏览器控制台命令:

  • console.log():用于输出日志信息。
  • console.dir():用于输出对象的属性和方法。
  • console.error():用于输出错误信息。
  • console.warn():用于输出警告信息。
  • console.clear():用于清空控制台。

示例代码:

// 输出日志信息
console.log("Hello, world!");

// 输出对象的属性和方法
var obj = {name: "Tom", age: 18};
console.dir(obj);

// 输出错误信息
console.error("Something went wrong!");

// 输出警告信息
console.warn("This is a warning!");

// 清空控制台
console.clear();

1.sha1算法

sha1算法是一种安全性较高的哈希算法,将任意长度的消息压缩成160位的摘要。

  • 以下是Python实现sha1算法的示例代码:
import hashlib

def sha1(data):
    sha1 = hashlib.sha1()
    sha1.update(data.encode('utf-8'))
    return sha1.hexdigest()
  • 以下是JavaScript实现sha1算法的示例代码:
function sha1(data) {
  const sha1 = crypto.createHash('sha1');
  sha1.update(data);
  return sha1.digest('hex');
}

2.sha256算法

sha256算法是一种更安全的哈希算法,将任意长度的消息压缩成256位的摘要。

  • 以下是Python实现sha256算法的示例代码:
import hashlib
def sha256(data):
    sha256 = hashlib.sha256()
    sha256.update(data.encode('utf-8'))
    return sha256.hexdigest()
  • 以下是JavaScript实现sha256算法的示例代码:
function sha256(data) {
  const sha256 = crypto.createHash('sha256');
  sha256.update(data);
  return sha256.digest('hex');
}

3.sha512算法

sha512算法是一种更安全的哈希算法,将任意长度的消息压缩成512位的摘要。

  • 以下是Python实现sha512算法的示例代码:
import hashlib
def sha512(data):
    sha512 = hashlib.sha512()
    sha512.update(data.encode('utf-8'))
    return sha512.hexdigest()
  • 以下是JavaScript实现sha512算法的示例代码:
function sha512(data) {
  const sha512 = crypto.createHash('sha512');
  sha512.update(data);
  return sha512.digest('hex');
}

4.md5算法

md5算法是一种较为常用的哈希算法,将任意长度的消息压缩成128位的摘要。

  • 以下是Python实现md5算法的示例代码:
import hashlib
def md5(data):
    md5 = hashlib.md5()
    md5.update(data.encode('utf-8'))
    return md5.hexdigest()
  • 以下是JavaScript实现md5算法的示例代码:
function md5(data) {
  const md5 = crypto.createHash('md5');
  md5.update(data);
  return md5.digest('hex');
}

5.hmac算法

hmac算法是一种基于哈希函数和密钥的消息认证码算法,常用于数据完整性校验和数字签名。

  • 以下是Python实现hmac算法的示例代码:
import hmac
import hashlib

def hmac_sha256(key, data):
    hmac_sha256 = hmac.new(key.encode('utf-8'), data.encode('utf-8'), hashlib.sha256)
    return hmac_sha256.hexdigest()
  • 以下是JavaScript实现hmac算法的示例代码:
function hmac_sha256(key, data) {
  const hmac_sha256 = crypto.createHmac('sha256', key);
  hmac_sha256.update(data);
  return hmac_sha256.digest('hex');
}

以上是国标哈希算法的介绍,包括sha1算法、sha256算法、sha512算法、md5算法、hmac算法以及Python和JavaScript实现。在实际应用中,需要根据具体需求选择合适的哈希算法。


国标对称加密算法是指由中国国家密码管理局发布的加密算法标准,包括DES算法、AES算法等。在JavaScript逆向中,了解这些算法的原理和使用方法是非常重要的。

1.DES算法

DES算法是一种对称加密算法,密钥长度为56位,分为加密和解密两个过程。在JavaScript中,可以使用crypto-js模块进行DES加密和解密操作。

  • 加密示例代码:
var key = CryptoJS.enc.Utf8.parse("1234567890123456");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var encrypted = CryptoJS.DES.encrypt("Hello World", key, {
  iv: iv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
});
console.log(encrypted.toString());
  • 解密示例代码:
var key = CryptoJS.enc.Utf8.parse("1234567890123456");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var decrypted = CryptoJS.DES.decrypt(encrypted, key, {
  iv: iv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));

2.AES算法

AES算法是一种对称加密算法,密钥长度可以是128位、192位或256位,分为加密和解密两个过程。在JavaScript中,可以使用crypto-js模块进行AES加密和解密操作。

  • 加密示例代码:
var key = CryptoJS.enc.Utf8.parse("12345678901234567890123456789012");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var encrypted = CryptoJS.AES.encrypt("Hello World", key, {
  iv: iv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
});
console.log(encrypted.toString());
  • 解密示例代码:
var key = CryptoJS.enc.Utf8.parse("12345678901234567890123456789012");
var iv = CryptoJS.enc.Utf8.parse("1234567890123456");
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
  iv: iv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));

3.crypto-js模块使用

crypto-js是一个JavaScript加密库,支持多种加密算法,包括DES、AES、SHA-1、SHA-256等。在使用之前,需要先引入crypto-js库。

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

4.pycryptodome

pycryptodome是一个Python加密库,支持多种加密算法,包括DES、AES、SHA-1、SHA-256等。在使用之前,需要先安装pycryptodome库。

pip install pycryptodome
  • 使用示例:
from Crypto.Cipher import AES

key = b'1234567890123456'
iv = b'1234567890123456'
cipher = AES.new(key, AES.MODE_CBC, iv)
msg = b'Hello World'
encrypted = cipher.encrypt(msg)
print(encrypted)

cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(encrypted)
print(decrypted)

1.RSA算法原理:

RSA算法是一种非对称加密算法,它的安全性基于大数分解的困难性。RSA算法的核心是选择两个大质数p和q,计算它们的乘积n=pq,然后选择一个整数e,使得1<e<φ(n)且e与φ(n)互质,其中φ(n)=(p-1)(q-1)。接着计算d,使得d*e mod φ(n)=1,d称为e的模反元素。公钥为(n,e),私钥为(n,d)。

  • 非对称特征:
    非对称加密算法有两个密钥,一个是公钥,一个是私钥。公钥可以公开,任何人都可以使用公钥对数据进行加密,但只有私钥的持有者才能解密。非对称加密算法的安全性基于数学难题,如大数分解、离散对数等,这些问题在计算机领域内是非常困难的。

  • JavaScript算法还原:

// 在JavaScript中,可以使用BigInt类型来处理大数运算。首先,需要实现一个函数来判断一个数是否为质数:
function isPrime(n) {
  if (n <= 1) {
    return false;
  }
  for (let i = 2; i <= Math.sqrt(n); i++) {
    if (n % i === 0) {
      return false;
    }
  }
  return true;
}
// 接着,可以实现一个函数来生成大质数:
function generatePrime(bits) {
  let p;
  do {
    p = BigInt(Math.floor(Math.random() * 2 ** bits));
  } while (!isPrime(p));
  return p;
}
// 然后,可以实现一个函数来计算两个数的最大公约数:
function gcd(a, b) {
  if (b === 0) {
    return a;
  }
  return gcd(b, a % b);
}
// 接着,可以实现一个函数来计算两个数的模反元素:
function modInverse(a, m) {
  let [x, y, u, v] = [0n, 1n, 1n, 0n];
  while (a !== 0n) {
    let q = m / a;
    let r = m % a;
    let m1 = x - u * q;
    let m2 = y - v * q;
    m = a;
    a = r;
    x = u;
    y = v;
    u = m1;
    v = m2;
  }
  return x < 0n ? x + m : x;
}
// 最后,可以实现一个函数来生成RSA密钥对:
function generateRSAKeyPair(bits) {
  let p = generatePrime(bits / 2);
  let q = generatePrime(bits / 2);
  let n = p * q;
  let phi = (p - 1n) * (q - 1n);
  let e = 65537n;
  let d = modInverse(e, phi);
  return {
    publicKey: [n, e],
    privateKey: [n, d],
  };
}
  • ras模块
// 在Node.js中,可以使用crypto模块来实现RSA加密和解密。首先,需要生成RSA密钥对:
const { generateKeyPairSync } = require('crypto');
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
  modulusLength: 2048,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem',
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
  },
});
// 接着,可以使用公钥对数据进行加密:
const crypto = require('crypto');
const data = 'hello world';
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(data));
console.log(encrypted.toString('base64'));
// 使用私钥对数据进行解密:
const decrypted = crypto.privateDecrypt(privateKey, encrypted);
console.log(decrypted.toString());
  • jesencrypt

jesencrypt是一个基于JavaScript实现的RSA加密库,可以在浏览器中使用。它的使用方法与Node.js中的crypto模块类似。首先,需要生成RSA密钥对:

const { generateKeyPair } = require('jesencrypt');
generateKeyPair().then(({ publicKey, privateKey }) => {
  console.log(publicKey);
  console.log(privateKey);
});
// 接着,可以使用公钥对数据进行加密:
const { encrypt } = require('jesencrypt');
const data = 'hello world';
encrypt(data, publicKey).then((encrypted) => {
  console.log(encrypted);
});
// 使用私钥对数据进行解密:
const { decrypt } = require('jesencrypt');
const encrypted = '...';
decrypt(encrypted, privateKey).then((decrypted) => {
  console.log(decrypted);
});

全局导出加密函数

全局导出加密函数的实现步骤如下:

  • 1)将需要加密的JavaScript代码通过加密算法进行加密。
  • 2)将加密后的代码作为一个函数的返回值。
  • 3)将这个函数通过module.exports导出,从而可以在全局范围内调用。

示例代码如下:

const encrypt = require('encrypt');
const code = 'console.log("Hello, World!");';
const encryptedCode = encrypt(code);
module.exports = function() {
  return eval(encryptedCode);
};

在上面的代码中,encrypt函数是一个加密函数,它将JavaScript代码进行加密,并返回加密后的代码。然后,将这个加密后的代码通过module.exports导出,从而可以在全局范围内调用。最后,通过eval函数执行加密后的代码。


acw_sc_v2调试

在进行cookie反爬处理时,经常会遇到acw_sc_v2这个参数。这个参数是阿里云CDN的一种反爬机制,用于检测请求是否来自于正常的浏览器。如果请求中没有正确的acw_sc_v2参数,CDN会返回403错误。

为了解决这个问题,我们需要了解acw_sc_v2的生成方式和调试方法。

acw_sc_v2的生成方式:
acw_sc_v2参数的生成方式比较复杂,需要使用一些加密算法。一般来说,生成acw_sc_v2参数需要以下步骤:

  • 获取当前时间戳,单位为毫秒。
  • 将时间戳转换为16进制字符串,并在前面补0,使其长度为13位。
  • 将13位时间戳字符串和一个随机字符串拼接起来,得到一个新的字符串。
  • 对新字符串进行MD5加密,得到一个32位的字符串。
  • 将32位字符串的前6位和后6位分别取出来,得到两个6位的字符串。
  • 将两个6位字符串拼接起来,得到12位的字符串,即为acw_sc_v2参数的值。

acw_sc_v2的调试方法
在进行cookie反爬处理时,我们需要调试acw_sc_v2参数的生成过程,以便正确地生成该参数。下面介绍几种调试方法:

使用浏览器开发者工具
在浏览器中打开目标网站,按下F12键打开开发者工具。在Network选项卡中找到一个请求,查看该请求的请求头信息。一般来说,acw_sc_v2参数会出现在请求头的Cookie字段中。将该Cookie字段复制下来,然后使用MD5加密算法对其进行加密,得到32位的字符串。最后按照上述步骤,将32位字符串转换为acw_sc_v2参数的值。

使用Python脚本
使用Python脚本可以自动化生成acw_sc_v2参数。下面是一个Python脚本示例:

import time
import random
import hashlib

def generate_acw_sc_v2():
    timestamp = str(int(time.time() * 1000))
    random_str = ''.join(random.sample('abcdefghijklmnopqrstuvwxyz0123456789', 6))
    new_str = timestamp + random_str
    md5_str = hashlib.md5(new_str.encode('utf-8')).hexdigest()
    acw_sc_v2 = md5_str[:6] + md5_str[-6:]
    return acw_sc_v2

该脚本会生成一个随机的acw_sc_v2参数值。

evaluate方法学习

evaluate方法是JavaScript中的一个内置函数,它可以将字符串作为代码执行。在AST中,我们可以通过evaluate方法执行AST节点中的代码。

evaluate方法的使用非常简单,只需要将AST节点中的代码转换为字符串,然后传入evaluate方法即可。需要注意的是,由于evaluate方法会执行任意的代码,因此在使用时需要谨慎,避免执行恶意代码。


JS HOOK

hook就是钩子函数,劫持原有函数并做一些操作,由于网络上相关教程有很多,这里贴上几个链接:
1.0基础入门通杀型 js hook:
2.JS hook大全:
3.详解JavaScript常用的Hook脚本:

posted @ 2023-09-20 17:06  愺様  阅读(266)  评论(0编辑  收藏  举报