假设你已经开启过题目,观察过源码,这里只记录base64逆向解析部分
题目里的关键加密代码
js
function validatePassword(input) {
const correctPassword = "SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU=";
let encoded = btoa(input);
encoded = btoa(encoded + 'xH7jK').slice(3); //
encoded = btoa(encoded.split('').reverse().join(''));
encoded = btoa('aB3' + encoded + 'qW9').substr(2);
return btoa(encoded) === correctPassword;
}
针对该加密流程,写出的逆向代码
js
// 题目
function validatePassword(input) {
const correctPassword = "SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU=";
let encoded = btoa(input);
// console.log(' btoa(input)',encoded) // VDE3MzE2
encoded = btoa(encoded + 'xH7jK').slice(3); // VDE3MzE2xH7jK => VkR FM016RTJ4SDdqSw==
// console.log(` btoa(encoded + 'xH7jK').slice(3)`,encoded) //FM016RTJ4SDdqSw==
encoded = btoa(encoded.split('').reverse().join(''));
// console.log(` btoa(encoded.split('').reverse().join(''))`,encoded) // PT13U3FkRFM0SlRSNjEwTUY=
encoded = btoa('aB3' + encoded + 'qW9').substr(2);
// console.log(` btoa('aB3' + encoded + 'qW9').substr(2);`,encoded) // IzUFQxM1UzRmtSRk0wU2xSU05qRXdUVVk9cVc5
return btoa(encoded) === correctPassword;
}
// const _input=atob("++E3MzE2");
// const rst=validatePassword(_input);
// const rst= validatePassword("ûá7316")
// 下面的密码都可以
// const rst=validatePassword("+A7316");
// const rst= validatePassword("3A7316")
// const rst= validatePassword("CA7316")
// const rst= validatePassword("T17316")
// console.log('rst',rst)
// 解析流程
const getEncoded2 = (encoded1) => {
let encoded2="";
// 1.补充首部字符
const b64CharList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
for (let i = 0; i < b64CharList.length; i++) {
for (let j = 0; j < b64CharList.length; j++) {
const char1 = b64CharList[i];
const char2 = b64CharList[j];
const twoChar = char1 + char2;
const tmpStr=twoChar+encoded1;
const atobValue = atob(tmpStr);
if(atobValue.startsWith('aB3')){
encoded2=atobValue.substring(3,atobValue.length-3);
return encoded2;
}
}
}
return encoded2;
};
const getEncoded4 = (encoded3) => {
let encoded4="";
// 1.补充首部字符
const b64CharList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
for (let i = 0; i < b64CharList.length; i++) {
for (let j = 0; j < b64CharList.length; j++) {
for (let k = 0; k < b64CharList.length; k++) {
const char1 = b64CharList[i];
const char2 = b64CharList[j];
const char3 = b64CharList[k];
const threeChar = char1 + char2 + char3;
const tmpStr=threeChar+encoded3; // 这里不对,结尾的5个字符,永远为真,即第一次得到的 tmpStr 不是正确的
// VDE 3MzE2 xH7jK
const atobValue = atob(tmpStr);
// 3MzE2xH7jK
if(atobValue.endsWith('xH7jK')){
// 满足这个条件后,再检查是否是真实密码
const _encoded4 = atobValue.substring(0, atobValue.length - 5);
try {
const _input=atob(_encoded4);
if(validatePassword(_input)){
// 检查生成的字符是否都在b64CharList中存在,不存在则为非法字符,跳过继续
if(_input.split('').every(char => b64CharList.includes(char))){
// _input 只能以为字母开头
const startReg = /^[a-zA-Z]/;
if(startReg.test(_input)){
encoded4=_encoded4;
return encoded4;
}else{
continue;
}
}else{
continue;
}
}
} catch (error) {
continue
}
}
}
}
}
return encoded4;
};
const getCorrentInput = () => {
const correctPassword = "SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU=";
// 1. 还原correctPassword
const encoded1 = atob(correctPassword);
// console.log('encoded1',encoded1)
// 2.还原 substr(2) 且 btoa('aB3' + encoded + 'qW9' )
const encoded2 =getEncoded2(encoded1);
// console.log('encoded2',encoded2)
// 3. 还原 encoded2 并反转
const encoded3 =atob(encoded2).split('').reverse().join('');
console.log('atob(encoded2)',atob(encoded2))
console.log('encoded3',encoded3)
// 还原 .slice(3); 且 = btoa(encoded + 'xH7jK')
const encoded4 =getEncoded4(encoded3);
// 还原 btoa(input);
try {
const input = atob(encoded4);
console.log('input',input)
return input;
} catch (error) {
console.log(error);
}
console.log('encoded4',encoded4)
};
getCorrentInput();
实际测试运行的结果,都可以登录成功
// 这些密码都能进入
// const rst=validatePassword("+A7316");
// const rst= validatePassword("3A7316")
// const rst= validatePassword("CA7316")
// const rst= validatePassword("T17316")