攻防世界--simple_js

image.png

 

题目描述:小宁发现了一个网页,但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} )

打开网址,就一个密码输入框,啥都没有,尝试随便输入一个密码,报错。

image.pngimage.png

ctrl+U 查看源代码

<html>
<head>
   <title>JS</title>
   <script type="text/javascript">
   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) );
</script>
</head>
</html>

最后一题真的太不会了,好吧,js不太懂,得学习一下网上的大佬了。。注:推荐先看一下,最下方的函数说明,再看代码分析

代码分析

一.代码定义了一个dechiffre函数,因为还没有调用,就先不理他了。
先将十六进制转换成字符串,使用网址:https://www.bejson.com/convert/ox2str/  
或者直接将十六进制参数放入python的print()中。即
s="\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"
print (s)
转换结果:55,56,54,79,115,69,114,116,107,49,50


二.执行了String["fromCharCode"](dechiffre("55,56,54,79,115,69,114,116,107,49,50"));


2.1 调用了dechiffre,执行了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”作为参数带入dechiffre函数中执行。即:
dechiffre(pass_enc)
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")


2.2 接着定义了pass变量一大串,先放着


2.3 因为pass_enc="55,56,54,79,115,69,114,116,107,49,50"
将pass_enc字符串分割成字符串数组,复制给tab参数所以:
tab=[55,56,54,79,115,69,114,116,107,49,50] 注:tab此时事字符串数组!!!


2.4 随后 tab2等于 pass分割成的数组
tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]


2.5 变量赋值代码分析:var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;
一开始i,j,m,n,o没有赋值,为undefined,而其他参数l=0,p="",后来 i 被赋值=0,j 被赋值=11


2.6  k = j + (l) + (n=0); 因为n=0,所以k=11+0+0=11, 注这里的(l)是英文字母l,不是数字1


2.7 n = tab2.length; n等于tab2的长度18 所以n=18


2.8 第一个循环,精简一些代码:
for(i =0; i < (k = j = n); i++ ) //i =(o=0) 不就是 i=0嘛 ,真是服了,这段代码一大堆烟雾弹,后面那个更大
{o = tab[i-l];p += String.fromCharCode((o = tab2[i]));
                         if(i == 5)break;}
解释:前面的o=tab[i-1]是无用的,因为后面会被o=tab2[i]的值重新覆盖 烟雾弹+1
第一次循环:o=tab[0];p=p+String.fromCharCode((o = tab2[0])
tab2[0]=70,o=70 p=""+String.fromCharCode(70) ==>p=F
ps:fromCharCode:将 Unicode 编码转为一个字符:
第二次...  p=A
第三次...  p=U
第四次...  p=X
第五次...  p=
所以,这个for循环,最后的p为(尽管没有输出出来,这里我们知道就好)FAUX P


2.9 第二个循环,精简一些代码:
for(i = 0; i < 18; i++ ){ //i =(o=0)不就是 i=0嘛 ,和上面的一样,烟雾弹+1
o = tab[i-l];
   if(i > 5 && i < 17)
       p += String.fromCharCode((o = tab2[i]));
}

解释:这里的for循环和上面的差不多,注意这里的p值由于第一次for循环执行后现在已经是FAUX P了
加上第一次for循环的p值,最后的p为FAUX PASSWORD HAH


2.10 p += String.fromCharCode(tab2[17]);
因为tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]
所以:p=FAUX PASSWORD HAH + A
因此,最后的p为FAUX PASSWORD HAHA

2.11 pass = p;return pass;
即 pass = FAUX PASSWORD HAHA;return FAUX PASSWORD HAHA;
最后函数输出为FAUX PASSWORD HAHA

额。。这个函数就这样执行完了,tab数组也没有使用到!!一开始带入进来的参数pass_enc也没有用,,最后这个tab和其带入的参数就像个烟雾弹,迷惑人的。

在运行函数过程中也用到了分割后的tab数组(即带入的参数),但是经过for循环的一通乱绕,人家直接使用tab2数组相关代码的值,根本没有使用到tab数组的值,
所以由于代码逻辑问题,传入dechiffre函数的参数pass_enc是没有意义的,只是个烟雾弹。


三、dechiffre函数执行后,继续执行其他的代码
h = window.prompt('Enter password');
   alert( dechiffre(h) );
h=你输入弹框的内容
之后alert弹出dechiffre(h)的值,由前面所有的代码分析可知,代码中的p值与tab无关,因为不论你输入什么最终都会被tab2的值替代。

所以不论pass_enc输入什么参数,输出的值都是会显示FAUX PASSWORD HAHA。

四、结论

最后结论是,不论输入什么参数,都只会返回FAUX PASSWORD HAHA,所以flag可能会与输入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
由上面分析已知,这一串参数转换为tab字符串数组为:[55,56,54,79,115,69,114,116,107,49,50] 注:tab此时是字符串数组!!!
所以得抛弃前面的代码,重新编写代码来运行它,好吧其实是大佬写的,我不会!!!
 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
   var n=String.fromCharCode(55,56,54,79,115,69,114,116,107,49,50);
   document.write(n);
</script>
</body>
</html>

最后结果是:786OsErtk12

根据题目的提示的Flag的格式,所以flag为:Cyberpeace(786OsErtk12)

函数说明

(1)split() 方法用于把一个字符串分割成字符串数组
语法:string.split(separator,limit)
参数                 描述
separator        可选。字符串或正则表达式,从该参数指定的地方分割 string Object。比如此题以逗号分割成字符串数组
limit            可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
举例:str="a,b,c,d,e,f,g";
var 1st = str.split(",",3);   对str以逗号进行分割,分割后的字符串数组内的值最多只能有3个,结果就是1st = [a,b,c]

(2)for 循环的语法如下:
for (语句 1; 语句 2; 语句 3) {
    要执行的代码块
}
语句 1 在循环(代码块)开始之前执行。
语句 2 定义运行循环(代码块)的条件。
语句 3 会在循环(代码块)每次被执行后执行。

(3)fromCharCode() 可接受一个指定的 Unicode 值,然后返回一个字符串。
语法:String.fromCharCode(n1, n2, ..., nX)
参数                 描述
n1, n2, ..., nX     必需。一个或多个 Unicode 值,即要创建的字符串中的字符的 Unicode 编码。

(4)prompt()方法用于显示可提示用户进行输入的对话框。
这个方法返回用户输入的字符串
语法:prompt(msg,defaultText)
参数                描述
msg                可选。要在对话框中显示的纯文本(而不是 HTML 格式的文本)就是弹框显示文本。
defaultText        可选。默认的输入文本,你输入什么弹框一开始出现里面的输入框就会默认显示你这个文本。

(5)var i,j,k,l=0,m,n,o,p = "";
这个表示声明变量i,j,k,l,m,n,o,p,只有l和p两个变量被赋值了,其它的变量都是不带值的,不带有值的变量,它的值将是undefined,后续代码中可以给它赋值。

(6)length
length 属性可设置或返回数组中元素的数目。

参考链接:XCTF_Web_新手练习区:simple_js(源代码详解)_1stPeak的博客-CSDN博客

第七题:simple_js(源代码详解)_greedy-hat的博客-CSDN博客

声明:

本文仅限于大家技术交流和学习,严谨读者利用本博客的所有知识点进行非法操作。如果你利用文章中介绍的技术对他人造成损失,后果由您自行承担,感谢您的配合,

作者创作不容易,请大家点赞支持一下。谢谢各位读者大老爷。

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值