-
-
攻防世界simple_js
-
2023-8-6 16:13 2284
-
攻防世界simple_js
前言:
作为攻防世界唯一一道关于有关js的题目。大多WriteUP都是一笔带过,直接就是ascall编码转换成字符拼接。却没有一个WriteUP分析过源码并且修改源码通关的。
题目描述:
小宁发现了一个网页,但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} )
一进网页弹出了输入密码,输入密码错误返回FAUX PASSWORD HAHA,那我们应该怎么做呢,我的建议是爆破(开玩笑的)
打开控制面板看看有没有前端代码,题目起名有js那么题目肯定是与js有关的
哟西,文件里面果然有段js代码,接下来便对这段代码进行逆向分析!
初始js代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function dechiffre(pass_enc){ var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65" ; var tab = pass_enc.split( ',' ); var tab2 = pass .split( ',' );var i,j,k,l = 0 ,m,n,o,p = "";i = 0 ;j = tab.length; k = j + (l) + (n = 0 ); n = tab2.length; for (i = (o = 0 ); i < (k = j = n); i + + ){o = tab[i - l];p + = String.fromCharCode((o = tab2[i])); if (i = = 5 ) break ;} for (i = (o = 0 ); i < (k = j = n); i + + ){ o = tab[i - l]; if (i > 5 && i < k - 1 ) p + = String.fromCharCode((o = tab2[i])); } p + = String.fromCharCode(tab2[ 17 ]); pass = p; return pass ; } String[ "fromCharCode" ](dechiffre( "\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" )); h = window.prompt( 'Enter password' ); alert( dechiffre(h) ); |
我总共总结了几种方法可以得到flag。但万物不离其宗,都是为了把正确密码传进dechiffre函数里面执行。
初始代码太复杂了,我们可以通过逆向调试的手段去掉一些无关紧要的代码
正文
把初始代码扣进编译器,首先分析函数里面的pass_enc.split(','),可以初步判断传进去的pass_enc参数是有逗号隔开的,不然直接就爆错。由于dechiffre函数没有用到传进去的pass_enc参数所以代码没有报错。
分析dechiffre函数外面的代码:
1 2 3 4 | String[ "fromCharCode" ](dechiffre( "\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" )); h = window.prompt( 'Enter password' ); alert( dechiffre(h) ); |
传进dechiffre函数的参数总共有两个,第一个是"\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30",
第二个便是我们刚进入网页需要输入的密码,第二个直接pass掉了,难道这个世界上真的有人的密码是用逗号隔开的吗,如果有的话,那肯定是"逗逼"。
第一个参数他并没有逗号隔开的,不过明眼一看就是十六进制,转成十进制看看是什么!
复制到控制台运行,得到了用逗号隔开的密码。
改写代码,直接把第一个参数转为十进制传进dechiffre函数
改写后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function dechiffre(pass_enc){ var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65" ; var tab = pass_enc.split( ',' ); var tab2 = pass .split( ',' );var i,j,k,l = 0 ,m,n,o,p = "";i = 0 ;j = tab.length; k = j + (l) + (n = 0 ); n = tab2.length; for (i = (o = 0 ); i < (k = j = n); i + + ){o = tab[i - l];p + = String.fromCharCode((o = tab2[i])); if (i = = 5 ) break ;} for (i = (o = 0 ); i < (k = j = n); i + + ){ o = tab[i - l]; if (i > 5 && i < k - 1 ) p + = String.fromCharCode((o = tab2[i])); } p + = String.fromCharCode(tab2[ 17 ]); pass = p; return pass ; } pwd = dechiffre( "\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" ) console.log(pwd) |
在dechiffre函数的最后一段代码加入debugger丢到浏览器执行看看代码是如何执行的。
这样子的代码并不容易分析,因为有一些误导的代码。
下面是需要改写的代码
i = (o=0)—>i=0
i < (k = j = n)—>i<n
k = j + (l) + (n=0)—>k=j
改写之后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function dechiffre(pass_enc){ var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65" ; var tab = pass_enc.split( ',' ); var tab2 = pass .split( ',' ); var i,j,k,l = 0 ,m,n,o,p = ""; i = 0 ;j = tab.length; k = j n = tab2.length; for (i = 0 ; i < n; i + + ){ o = tab[i - l]; p + = String.fromCharCode((o = tab2[i])); if (i = = 5 ) break ; } for (i = 0 ; i < n; i + + ){ o = tab[i - l]; if (i > 5 && i < k - 1 ) p + = String.fromCharCode((o = tab2[i])); } p + = String.fromCharCode(tab2[ 17 ]); pass = p; return pass ; } pwd = dechiffre( "\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" ) console.log(pwd) |
第一种通关方法:
在未修改前的代码19行下个断点,刷新。p="FAUX PASSWORD HAH"
在未修改前的代码20行下个断点,单步调试。p="FAUX PASSWORD HAHA"
p += String.fromCharCode(tab2[17])的作用就是在所有ascall转字符拼接完了之后再拼接一个A。
而传进来的数组pass_enc并没有第十七个数值,所以是个未定义。拼接也是空。而他的本意就是拼接pass的第十七个字符也就是"65"字符A,所以修改后的代码完全可以把这一行删掉。
tab是传下来的数组pass_enc分割的,把拼接的tab2全部修改成tab。把tab2的长度n也修改成tab的长度j,并且把p += String.fromCharCode(tab2[17]);删掉。这样子我们就能把传进来的数组全部转换成字符并且拼接起来。
修改后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function dechiffre(pass_enc){ var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65" ; var tab = pass_enc.split( ',' ); var tab2 = pass .split( ',' ); var i,j,k,l = 0 ,m,n,o,p = ""; i = 0 ;j = tab.length; k = j; n = tab2.length; for (i = 0 ; i < j; i + + ){ o = tab[i - l]; p + = String.fromCharCode((o = tab[i])); if (i = = 5 ) break ; } for (i = 0 ; i < j; i + + ){ o = tab[i - l]; if (i > 5 && i < k - 1 ) p + = String.fromCharCode((o = tab[i])); } pass = p; return pass ; } pwd = dechiffre( "\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" ) console.log(pwd) |
结果:
第二种通关方法:
从代码可以看出两次for循环都是把tab2数组从ascall码转换成字符
而tab2数组是内置的var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65"
所以我们直接把tab2数组转换成传进来的参数
改写之后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function dechiffre(pass_enc){ var pass = "55,56,54,79,115,69,114,116,107,49,50" ; var tab = pass_enc.split( ',' ); var tab2 = pass .split( ',' ); var i,j,k,l = 0 ,m,n,o,p = ""; i = 0 ;j = tab.length; k = j; n = tab2.length; for (i = 0 ; i < n; i + + ){ o = tab[i - l]; p + = String.fromCharCode((o = tab2[i])); if (i = = 5 ) break ; } for (i = 0 ; i < n; i + + ){ o = tab[i - l]; if (i > 5 && i < k - 1 ) p + = String.fromCharCode((o = tab2[i])); } pass = p; return pass ; } pwd = dechiffre( "\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" ) console.log(pwd) |
执行结果:
结尾:
电脑麦克风坏了,后续视频录好了会发在b站上面。
b站主页:灵魂给了傀
此文章仅供技术交流使用,如有侵权联系我删除。
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。