js 逆向系列04-常见混淆原理

admin 2024年2月22日11:46:05评论9 views字数 2227阅读7分25秒阅读模式

js混淆有两种:

变量代码执行流程混淆代码的执行流程一般通过控制流混淆来实现,下面主要介绍一下常见的变量混淆方式。

基本混淆方法

将值放到新的变量中,再通过 window 来取:

js 逆向系列04-常见混淆原理

也可以结合 base64 编码,即(btoa,atob)

js 逆向系列04-常见混淆原理

先通过 atob(ry4n3[0]),即 YWJj 的 base64decode,解码得到 abc,再用 window[abc]来获取变量 abc 的值——"test" 也可以利用 eval 方法,例如 eval("function xx(){return 12} xx()"),结合上 base64:

js 逆向系列04-常见混淆原理

如果是利用 eval 进行混淆,可以直接在 eval 处下断点,跟进虚拟机即可看到明文:

js 逆向系列04-常见混淆原理

js 默认支持 unicode 编码,因此可以支持生僻语言等等,AA 加密和 JJ 加密就是利用了这一点。

AA 加密

AA 加密和 JJ 加密都可以通过 sojson 网站进行。 

sojson:JS加密,JS 安全加密, AAencode 加密 —在线加密 (sojson.com)[1]

js 逆向系列04-常见混淆原理

以 console.log(1)为例,加密后的代码如图所示,执行后成功打印出 1.

JJ 加密

JJ 加密与 AA 加密类似,都是利用 js 支持 unicode 编码,并且都是通过 eval+Function 的方式进行,下面尝试对 JJ 加密进行调试。 

同样以 console.log(1)为例:

js 逆向系列04-常见混淆原理

首先这里可以直接运行出值。 最后一行代码为:

sojson.$(sojson.$(sojson.$$ +"""+ sojson.$$__ + sojson._$ +"\"+ sojson.__$ + sojson.$_$ + sojson.$$_ +"\"+ sojson.__$ + sojson.$$_ + sojson._$$ + sojson._$ +(![]+"")[sojson._$_]+ sojson.$$$_ +"."+(![]+"")[sojson._$_]+ sojson._$ +"\"+ sojson.__$ + sojson.$__ + sojson.$$$ +"("+ sojson.__$ +")"+""")())(sojson ={    ___:++sojson,    $$$$:(![]+"")[sojson]});

这里执行了一个方法,肯定是在该方法运行之后,才完成了字符串的拼接以及整体代码的运行。

js 逆向系列04-常见混淆原理

很明显这里是一个 Function,尝试改写 Function:

js 逆向系列04-常见混淆原理

Function = function(){debugger;}这里加上一个 debugger,类似于 hook 的形式,打上断点并运行,但是没有断住。 

看看上一行代码:

js 逆向系列04-常见混淆原理

js 逆向系列04-常见混淆原理

js 逆向系列04-常见混淆原理

sojson 是一个 object,其实也就是 OBJECT[0].constructor.constructor,执行后就是 Function:

js 逆向系列04-常见混淆原理

由于是直接从原型链取的,因此无法通过改写来 debug。

js 逆向系列04-常见混淆原理

可以直接改写 sojson. $ ,(注意,先在 28 行打断点,执行,断住时,改写为 sojson.$=function(){debugger;}),此时能够直接进到虚拟机里,即 sojson.$ = function(){debugger;} 通过 arguments 打印出此时的所有参数,可以看到 "return"co156163ole.lo147(1)"" 这段内容还是经过简单的加密处理的,直接通过控制台还原一下:

js 逆向系列04-常见混淆原理

最终结果即为 console.log(1)

jsfuck

javascript 是一种灵活的动态语言,其允许使用多种语法结构和运算符来实现具体逻辑,并且允许进行各种类型的数据转换,jsfuck 就是利用了这些特性,结合位运算操作实现的一种加密方式。 

还是以 console.log(1)为例,同样可以直接运行,因为他没有改变代码的语法和形式等等,只是进行了混淆操作:

js 逆向系列04-常见混淆原理

jsfuck 混淆之后的代码要进行调试较为麻烦,可以通过下面的代码来实现快速解密:

Function.prototype.__defineGetter__('constructor',function(){returnfunction(...args){console.log('code:',...args);returnFunction(...args);};});

这里定义了一个 getter 方法,该方法会在访问对象的 constructor 属性时被调用。在这个 getter 方法中,它重新定义了 constructor 属性,使得在访问 constructor 属性时,会执行一个自定义的函数。 

该函数会接收传入的参数即...args ,然后打印出参数 args ,最后返回一个新的 Function 对象,该对象与原始的 Function 构造函数的行为相同。 JSFuck 加密后的代码执行时,通常会创建一个 Function 对象,然后对他进行调用。通过重定义 constructor 属性,并在访问时输出参数,我们可以获取到加密后的代码内容,并且还可以将其作为参数传递给新的 Function 对象,从而执行原始代码。 

例如,对下面代码进行 jsfuck 混淆:

var test="123"console.log(test)

js 逆向系列04-常见混淆原理

可以看到很多 escape 和 location,最终跳到了原始的明文代码,并且输出了结果 123.

References

[1] JS加密,JS 安全加密, AAencode 加密 —在线加密 (sojson.com): https://www.sojson.com/aaencode.html

原文始发于微信公众号(Crush Sec):js 逆向系列04-常见混淆原理

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月22日11:46:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   js 逆向系列04-常见混淆原理https://cn-sec.com/archives/2514362.html

发表评论

匿名网友 填写信息