共计 2975 个字符,预计需要花费 8 分钟才能阅读完成。
关注微信公众号:K 哥爬虫,继续分享爬虫进阶、JS/ 安卓逆向等技术干货!
申明
本文章中所有内容仅供学习交换,抓包内容、敏感网址、数据接口均已做脱敏解决,严禁用于商业用途和非法用处,否则由此产生的所有结果均与作者无关,若有侵权,请分割我立刻删除!
逆向指标
- 指标:社会主义外围价值观加密原理剖析
- 主页:
aHR0cHM6Ly93d3cuYXBwbWl1LmNvbS9rZXkv
逆向剖析
K 哥的共事明天发来一个比拟乏味的加密,不论你输出什么字符串,加密后的后果都是由 24 个字的社会主义外围价值观随机组合而成,如下图所示:
首先咱们尝试抓包,看看是否有网络上的发包操作,实际上是没有的,这阐明加密解密的逻辑都在已加载结束的 JavaScript 代码里,这里介绍三种办法去定位加密入口:
1、咱们留神到加密后果始终由社会主义外围价值观组成,必定是在原 24 字的根底上做了一些操作,也就是说在某个中央必定定义了这 24 个字,咱们任意全局搜寻其中一个词即可,如下图所示:
2、加密解密的后果都是点击了按钮才生成的,那么这个按钮必定绑定了某些事件,比方鼠标点击事件,咱们能够通过 DOM 事件断点的形式定位加密入口,如下图所示:
3、咱们留神到加密解密的 button 都有一个 id,那么有可能 JavaScript 里会获取到这个 id 后,应用 addEventListener()
办法向这个元素增加鼠标点击事件句柄,所以也能够全局搜寻其 id,即 encode-btn 和 decode-btn,也能够搜寻 getElementById("encode-btn")
或者 getElementById("decode-btn")
,当然也能够搜寻办法关键字 addEventListener。如下图所示:
定位到加密地位后,埋下断点进行调试,咱们来看看加密的逻辑:
加密过程:变量 v 通过元素 id(decoded-area)拿到明文文本区域(textarea),点击加密按钮(encode-btn)会触发事件,进入前面的函数,v.value
就是明文值,通过 l()
函数加密后赋值给 n,而后再把 n 赋值给 p.value
,也就是显示在密文的文本区域(encoded-area)。
解密过程:变量 p 通过元素 id(encoded-area)拿到密文文本区域(textarea),点击解密按钮(decode-btn)会触发事件,进入前面的函数,p.value
就是密文值,通过 s()
函数解密后赋值给 n,而后再把 n 赋值给 v.value
,也就是显示在明文的文本区域(decoded-area)。
整个代码逻辑比较简单,用到的这些函数也都在一起,间接全副 copy 下来即可。
残缺代码
GitHub 关注 K 哥爬虫,继续分享爬虫相干代码!欢送 star!https://github.com/kgepachong/
JavaScript 加密解密代码
var e = function () {for (var t = arguments.length, n = Array(t), r = 0; r < t; r++)
n[r] = arguments[r];
var e = n.length
, i = "string" == typeof n[e - 1] ? n[e - 1] : "Assert Error"
, o = !0
, u = !1
, c = void 0;
try {for (var f, a = n[Symbol.iterator](); !(o = (f = a.next()).done); o = !0) {if (!f.value)
throw new Error(i)
}
} catch (t) {
u = !0,
c = t
} finally {
try {!o && a.return && a.return()
} finally {if (u)
throw c
}
}
}
, i = function () {return Math.random() >= .5
}
, o = function (t) {var n = /[A-Za-z0-9\-\_\.\!\~\*\'\(\)]/g
, r = t.replace(n, function (t) {return t.codePointAt(0).toString(16)
});
return encodeURIComponent(r).replace(/%/g, "").toUpperCase()}
, u = function (t) {e("string" == typeof t, "utfs Error");
var n = t.length;
e(0 == (1 & n));
for (var r = [], i = 0; i < n; i++)
0 == (1 & i) && r.push("%"),
r.push(t[i]);
return decodeURIComponent(r.join(""))
}
, c = function (t) {e("string" == typeof t);
var n = []
, r = !0
, o = !1
, u = void 0;
try {for (var c, f = t[Symbol.iterator](); !(r = (c = f.next()).done); r = !0) {
var a = c.value
, s = Number.parseInt(a, 16);
s < 10 ? n.push(s) : i() ? (n.push(10),
n.push(s - 10)) : (n.push(11),
n.push(s - 6))
}
} catch (t) {
o = !0,
u = t
} finally {
try {!r && f.return && f.return()
} finally {if (o)
throw u
}
}
return n
}
, f = function (t) {e(t instanceof Array);
for (var n = [], r = t.length, i = 0; i < r;)
t[i] < 10 ? n.push(t[i]) : 10 === t[i] ? (i++,
n.push(t[i] + 10)) : (i++,
n.push(t[i] + 6)),
i++;
return n.map(function (t) {return t.toString(16).toUpperCase()}).join("")
}
, a = function (t) {return t.map(function (t) {return h[2 * t] + h[2 * t + 1]
}).join("")
}
, s = function (t) {var n = []
, r = !0
, i = !1
, o = void 0;
try {for (var c, a = t[Symbol.iterator](); !(r = (c = a.next()).done); r = !0) {
var s = c.value
, l = h.indexOf(s);
-1 !== l && (1 & l || n.push(l >> 1))
}
} catch (t) {
i = !0,
o = t
} finally {
try {!r && a.return && a.return()
} finally {if (i)
throw o
}
}
var v = f(n);
e(0 == (1 & v.length));
var p = void 0;
try {p = u(v)
} catch (t) {throw t}
return p
}
, h = "富强专制文化谐和自在平等公正法治爱国敬业诚信友善"
function encrypt(t) {return a(c(o(t)))
}
function decrypt(t) {return s(t)
}
// 测试样例
// console.log(encrypt("1234"))
// console.log(decrypt("谐和专制谐和文化谐和谐和谐和自在"))