第七题:simple_js(源代码详解)

在这里插入图片描述

目标:

掌握有关js的知识

Writeup

<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>

执行流程:

一、

首先定义了一个dechiffre函数,咱先不管,因为还没有调用

二、

执行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"));

  • 调用了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")
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] 注:tab此时是字符串数组!!!
  • 接着我们看到了pass变量,暂时先放着
  • pass_enc字符串分割成字符串数组,赋值给tab参数,所以:
    tab=[55,56,54,79,115,69,114,116,107,49,50] 注:tab此时是字符串数组!!!
  • 随后也对pass分割
tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]
  • 变量赋值代码分析:var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;
    一开始i,j,k,m,n,o没有赋值,为undefined,其它参数l=0,p="",后来i被赋值为0,j被赋值为11

  • 第九行此时n被赋值为0,所以k=11+0+0,最后等于11
    注:这里的(l)其中是英文字母l,一开始看成1了…

  • 第十一行中,n=18

  • 第一个for循环,精简一下代码:

for(i = 0; i < (18); i++ )
{
	o = tab[i-l];
	p += String.fromCharCode((o = tab2[i]));
    if(i == 5)break;
}

解释:前面的o=tab[i-1]是无用的,因为后面会被o=tab2[i]的值重新覆盖
第一次循环:

{
	o=tab[-1];
	p=p+String.fromCharCode((o = tab2[0])
}

第二次…
第三次…
第四次…
第五次…
所以,这个for循环,最后的p为FAUX P(尽管没有输出出来,这里我们知道就好)

可以自己运行一下

  • 第二个for循环,精简一下代码:
for(i = 0; i < 18; i++ ){
	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

  • 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 HAHA + A
    因此,最后的p为FAUX PASSWORD HAHA

  • pass = p; return pass;
    pass = FAUX PASSWORD HAHAA;return FAUX PASSWORD HAHA;

最后dechiffre函数输出为FAUX PASSWORD HAHA

嗯哼???这个函数就执行完了???我的tab数组怎么没有用到???,我一开始带进来的参数呢?去哪了?
别想了,输出值虽然用到了带进来的参数(就是分割后的tab数组),但是for循环那里人家直接使用tab2数组相关代码的值直接覆盖了你的值。

因此:将还没执行结束的

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"))

这个代码执行完,现在就变成了
String[“fromCharCode”] (“FAUX PASSWORD HAHA”);

三、

dechiffre函数执行完成后,继续执行其它的代码

h = window.prompt('Enter password');
alert(dechiffre(h));

h=你输入弹框内的内容
之后alert弹出dechiffre(h)的值

由前面所有的代码可知,代码里p的值与tab无关,因为最终都会被tab2的值替代,所以我们无论输入什么,也就是pass_enc=h,无论这个h等于什么,不管tab能否被分割成字符串数组、是否存在,我只要tab2在就行了,你tab在不在无所谓。
通俗点讲,有关tab的参数与值都可以视为没有,因此,pass_enc参数是什么也就没有意义了
无论你在弹框中输入什么,弹出内容还是一样。

四、

最后,结论就是,无论我们在弹框中输入什么值,都只会返回FAUX PASSWORD HAHA
我就猜想,会不会与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"));
中的
\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有关呢?

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] 注: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值,执行正确!!!

注:

(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,后续代码中可以给它赋值。

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值