JS逆向基础(个人总结)

JS逆向基础(个人总结)

函数相关

(function auto(){
   console.log("自动执行");
})();
$(function auto(){
   console.log("自动执行");
})
function second(){
   console.log(first());
}

function first(){
   return "hi there.";
}
function say(){
   return "定义函数";
}
var say = function(){
   return "定义函数";
}
var obj = {
   "say":function(){
       return "对象内的成员";
   }
};

Base64 编码函数

let value = 'hello';
console.log(btoa(value));
let value = 'aGVsbG8=';
console.log(atob(value));
const CryptoJS = require("crypto-js");
let value="hello";
let trans=CryptoJS.enc.Utf8.parse(value);
let encrypted=CryptoJS.enc.Base64.stringify(trans);
console.log(encrypted)
function Base64(){
   this.encode = function(val){
       //编码逻辑
       return val
   }
   this.decode = function(val){
       //解码逻辑
       return val
   }
}
encrypt = new Base64();
console.log(encrypt.encode("encode"));

JSON 对象

var params={
   "username":"null119",
   "password":"123456"
}
console.log(JSON.stringify(params));
var params='{"username":"null119","password":"123456"}';
console.log(JSON.parse(parms));

Array 数组基本操作

let mousePos=[];
let mousePos=new Array();
mousePos.push([100,50,200]);
console.log(mousePos);
console.log(mousePos.pop());
let mousePos = new Array();
mousePos.push([100,50,123]);
console.log(mousePos.join(";"));
let mousePos = new Array();
mousePos.push([100,50,123]);
console.log(mousePos.toString());

字符和Unicode编码值互转

let value=String.fromCharCode(72,69,76,76,79); //HELLO
console.log(value);
let value='h';
console.log(value.charCodeAt());

toString 函数

let param=[5,6,8];
console.log(param.toString());
let value=6;
console.log(value.toString(2));
let value=6;
console.log(value.toString(16));
let value=false;
console.log(value.toString());
let arr=[1,2,3];
console.log(toString.call(arr));

Val取值和设置值

<html
<head
<script type="text/javascript" src="/jquery/jquery.js"</script
<script type="text/javascript"
$(document).ready(function(){
   $("button").click(function(){
       $(":text").val("hello");
   });
});
</script
</head
<body
<pName:<input type="text" name="user" value="Hello world" /</p
<button改变文本域值</button
</body
</html
<html
<head
<script type="text/javascript" src="/jquery/jquery.js"</script
<script type="text/javascript"
$(document).ready(function(){
   $("button").click(function(){
       alert($("input:text").val());
   });
});
</script
</head
<body
FirstName:<input type="text" name="fname" value="Bill" /<br/
LastName:<input type="text" name="lname" value="Gates" /<br/
<button获得第一个文本域的值</button
</body
</html

return也是有语法的

function _tokenValue(v){
   //.....
   let _token= v.join("-");
   return _token
}
console.log(_tokenValue([56,78,33]));
function first(){
   console.log("调用1");
   return "first";
}
let second = function(){
   console.log("调用2");
   return "second";
}
function _tokenValue(v){
   let _token= v.join("-");
   return first(),
       second(),
       _token;
}
console.log(_tokenValue([56,78,33]));
function first(){
   console.log("调用1");
   return "first";
}
let second = function(){
   console.log("调用2");
   return "second";
}
function _tokenValue(v){
   let _token= v.join("-");
   return first(),
       _token,
       second();
}
console.log(_tokenValue([56,78,33]));

代码混淆

let objects = {
   "\x66\x69\x6c\x74\x65\x72": function(){
       return "\x6c\x74\x65";
   }
}
let objects = {
   "\u0073\u0069\u0067\u006e\u0056": function(){
       return "ENG987KJS732njH7273NH23";
   }
}
let vales = ["sign","publicKey","Base64","encrypt","toString","decode","atob","btoa"];
let url = "http://www.null119.cn"
vales[0] ="SI209U+230D86+7NB=";
let full = url+"?"+vales[0]+"_";
console.log(vales[0]);
console.log(full);
let _sh78x6 = ["sign","publicKey","Base64","encrypt","toString","decode","atob","btoa"];
let _ac87x5 = "http://www.null119.cn"
_sh78x6[0] ="SI209U+230D86+7NB=";
let _sh87x6 = _ac87x5+"?"+_sh78x6[0]+"_";
console.log(_sh78x6[0]);
console.log(_sh87x6);
...

XHR 和 Ajax请求方式

$.ajax({
   //构造请求头
   url: loginurl + "?uuid=" + uuid +"&r=" + Math.random(),
   type: 'POST',
   dataType: "text",
   contentType: "application/x-www-form-urlencoded; charset=utf-8",
   data: {
       uuid:$('#uuid').val()
   },
   error: function(){
       //错误触发
   },
   success: function(result){
       //成功返回响应正文时触发
   }
});
function SendXHR(){
   var xhr = new XMLHttpRequest();    //实例化xhr对象
   xhr.open('GET','http://www.null119.cn/index.html?p=123') //设置发送方法、URL
   xhr.send(null);//发送数据
   xhr.onreadystatechange = function(){    //回调函数,拿到数据后执行相关操作
       if (xhr.readyState==4){
           console.log(xhr.responseText);
       }
   };
}

逆向中偶有,Hook常用

let person = {
   fullInfo: function(city,country){
       return this.name + "-" + this.age +"-"+country+"-"+city;
   }
}
let person1 = {
   name:"Jor",
   age:"25"
}
console.log(person.fullInfo.apply(person1,["Oslo","Norway"]));
let person = {
   fullInfo: function(city,country){
       return this.name + "-" + this.age +"-"+country+"-"+city;
   }
}
let person1 = {
   name:"Jor",
   age:"25"
}
console.log(person.fullInfo.call(person1,"Oslo","Norway"));

AES

window = this;
navigator = {};

const JSEncrypt = require("jsencrypt")
const value = "123456781";
const key="......"

let encrypt = new JSEncrypt.JSEncrypt();
encrypt.setPublicKey(key)
let res = encrypt.encrypt(value);
console.log(res)

RSA

const NodeRSA = require("node-rsa");
const key = new NodeRSA({b:512});

const text='hello RSA';
const encrypted = key.encrypt(text,'base64');
const decrypted = key.decrypt(encrypted,'utf8');

console.log('encryted:',encrypted);
console.log('decryted:',decrypted);

CryptoJS 加密库

const CryptoJS = require("crypto-js");

let value = '123456'  //待加密字符串
let secret_value = 'af25-87hk=a35v-5';  //密钥16位
let iv_value = 'af25-87hk=a35v-5';  //初始向量IV 16位

//密钥和向量处理
let secret = CryptoJS.enc.Utf8.parse(secret_value);
let iv = CryptoJS.enc.Utf8.parse(iv_value);

//加密
let encrypted = CryptoJS.AES.encrypt(value,secret,{
  iv: iv,
  //加密模式: CBC,CFB,CTR,ECB,OFB  默认CBC
  mode: CryptoJS.mode.CBC,
  //填充模式: Pkcs7,Pkcs5
  padding: CryptoJS.pad.Pkcs7
});

//加密结果转字符串
encrypted = encrypted.toString();

//解密,传入密文、密钥、向量并设置加密与填充模式
let decrypted = CryptoJS.AES.decrypt(encrypted,secret,{
  iv: iv,
  mode:CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
});

//解密结果转字符串
decrypted = CryptoJS.enc.Utf8.stringify(decrypted);

//打印明文、密文、解密结果
console.log(value);
console.log(encrypted);
console.log(decrypted);

Base64

const CryptoJS = require("crypto-js");

//编码
let value = "http//www.nul119.cn";
let trans = CryptoJS.enc.Utf8.parse(value);
let encrypted = CryptoJS.enc.Base64.stringify(trans);

//解码
let trans_encrypted= CryptoJS.enc.Base64.parse(encrypted);
let decrypted = trans_encrypted.toString(CryptoJS.enc.Utf8);

//打印明文、编码结果、解码结果
console.log(value);
console.log(encrypted);
console.log(decrypted);

MD5

const CryptoJS = require("crypto-js");

let value="Message";
let encrypted = CryptoJS.MD5(value);
console.log(encrypted.toString());

SHA

const CryptoJS = require("crypto-js");

let value="message";

//加密可切换 SHA1/SHA224/SHA256/SHA384/SHA512
let hash = CryptoJS.SHA256(value);

console.log(value);
console.log(hash.toString()) //结果与CryptoJS.enc.Hex相同
console.log(hash.toString(CryptoJS.enc.Hex));
console.log(hash.toString(CryptoJS.enc.Base64));

© 允许规范转载

CryptoJS AES 一般人不知道的小秘密

CryptoJS 是前端最好用的加密框架,然而这个加密框架在处理 AES 加密时有点小心机你知道吗?

0x1、最为常见的AES加密方式,使用固定长度key

encrypt: function (cipher, message, key, cfg) {
    * @param {Cipher} cipher The cipher algorithm to use.
    * @param {WordArray|string} message The message to encrypt.
    * @param {WordArray} key The key.
    * @param {Object} cfg (Optional) The configuration options to use for this operation.
    * @return {CipherParams} A cipher params object.

    cfg = this.cfg.extend(cfg);
    var encryptor = cipher.createEncryptor(key, cfg);
    var ciphertext = encryptor.finalize(message);
    var cipherCfg = encryptor.cfg;
    return CipherParams.create({
        ciphertext: ciphertext,
        key: key,
        iv: cipherCfg.iv,
        algorithm: cipher,
        mode: cipherCfg.mode,
        padding: cipherCfg.padding,
        blockSize: cipher.blockSize,
        formatter: cfg.format
    });
}

0x2、较少见的AES加密方式,可以使用任意长度key,返回结果次次不同

encrypt: function (cipher, message, password, cfg) {
    * @param {Cipher} cipher The cipher algorithm to use.
    * @param {WordArray|string} message The message to encrypt.
    * @param {string} password The password.
    * @param {Object} cfg (Optional) The configuration options to use for this operation.
    * @return {CipherParams} A cipher params object.

    cfg = this.cfg.extend(cfg);
    var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
    cfg.iv = derivedParams.iv;
    var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
    ciphertext.mixIn(derivedParams);
    return ciphertext;
}

0x3、总结

第一种方式传入的第三个参数key类型为WordArray , 这是由我们最常见的 CryptoJS.enc.Utf8.parse() 或 CryptoJS.enc.Latin1.parse() 处理过后的类型,这个WordArray传入后会直接用作Key,所以:相同key,相同内容,每次加密结果均相同
第二种方式传入的第三个参数password类型为string , 它会被 CryptoJS.lib.PasswordBasedCipher 处理,并用 cfg.kdf 生成一个新的 WordArray,这个生成出来的东西才是实际的 key。这个生成出来的东西是具有随机性的,所以:相同password,相同内容,每次加密结果均不相同