本文介紹了JavaScript中隱藏eval關(guān)鍵字的多種方法,從簡(jiǎn)單的字符串拼接和Function構(gòu)造函數(shù),到使用字符編碼動(dòng)態(tài)生成字符串。更復(fù)雜的方案包括通過JS混淆工具(如JShaman)將代碼轉(zhuǎn)換為難以辨識(shí)的格式,甚至模擬虛擬機(jī)執(zhí)行字節(jié)碼來重構(gòu)eval。這些技術(shù)通過層層包裝,使原始eval調(diào)用在代碼審計(jì)中難以被發(fā)現(xiàn)。
JavaScript中隱藏eval關(guān)鍵字的技巧
某些情況下,我們?cè)谶M(jìn)行JS編程時(shí),可能想要用eval執(zhí)行一些特殊的代碼,但想不想讓他人輕易看出是使用了eval。那么,就得想辦法隱藏eval關(guān)鍵字了。
簡(jiǎn)單的隱藏方法
// 方法1:使用字符串分割
const ev = "ev"
const al = "al"
const hiddenEval = window[ev + al]
// 使用
hiddenEval('console.log("隱藏的eval執(zhí)行")')
// 方法2:通過Function構(gòu)造函數(shù)
const executeCode = new Function('code', 'return eval(code)')
executeCode('2 + 2')
復(fù)雜的隱藏方法
// 使用字符編碼
const encodedEval = () => {
const chars = [101, 118, 97, 108]
const str = String.fromCharCode(...chars)
return window[str]
}
const myEval = encodedEval()
更更更復(fù)雜的隱藏方法
如果還想隱藏的更深,可以再用JShaman進(jìn)行JS代碼混淆加密,上面代碼會(huì)變成:
const encodedEval = () => {
const _0x35ea38 = {
"\u006d\u004f\u0067\u006c\u0048": function (_0x55d02e, _0x5cdb2b) {
return _0x55d02e ^ _0x5cdb2b
},
"\u0076\u006a\u0048\u0044\u0073": function (_0x4c98c3, _0xa2b4f0) {
return _0x4c98c3 ^ _0xa2b4f0
}
}
const _0x2cd5ff = [0x47a4d ^ 0x47a28, _0x35ea38["\u006d\u004f\u0067\u006c\u0048"](0xd8290, 0xd82e6), _0x35ea38['vjHDs'](0xb9759, 0xb9738), _0x35ea38["\u0076\u006a\u0048\u0044\u0073"](0x7b450, 0x7b43c)]
const _0x3d45d7 = String['fromCharCode'](..._0x2cd5ff)
return window[_0x3d45d7]
}
const myEval = encodedEval()
或:
function _0x927a(opcode) {
var op = {
push: 32,
add: 33,
sub: 34,
mul: 35,
div: 36,
pop: 37,
xor: 38
}
var stack = []
var ip = -1
var sp = -1
while (ip < opcode.length) {
ip++
switch (opcode[ip]) {
case op.push:
{
ip++
stack.push(opcode[ip])
sp++
break
}
case op.add:
{
stack.push(stack[sp - 1] + stack[sp])
sp++
break
}
case op.sub:
{
stack.push(stack[sp - 1] - stack[sp])
sp++
break
}
case op.mul:
{
stack.push(stack[sp - 1] * stack[sp])
sp++
break
}
case op.div:
{
stack.push(stack[sp - 1] / stack[sp])
sp++
break
}
case op.xor:
{
stack.push(stack[sp - 1] ^ stack[sp])
sp++
break
}
case op.pop:
{
return stack[sp]
}
}
}
}
const encodedEval = () => {
const chars = [_0x927a([32, 865932, 32, 866025, 38, 37]), _0x927a([32, 625917, 32, 625803, 38, 37]), _0x927a([32, 750963, 32, 750866, 38, 37]), _0x927a([32, 753540, 32, 753640, 38, 37])]
const str = String['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'](...chars)
return window[str]
}
const myEval = encodedEval()
怎么樣,還能找到eval關(guān)鍵字嗎?
轉(zhuǎn)自https://juejin.cn/post/7566171225708068864
該文章在 2025/11/6 16:05:11 編輯過