XCTF-攻防世界CTF平台-Crypto类——4flag_in_your_hand1
Posted 大灬白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XCTF-攻防世界CTF平台-Crypto类——4flag_in_your_hand1相关的知识,希望对你有一定的参考价值。
下载文件之后,发现是一道前端的题目:有一个index.html文件和一个script-min.js文件:
运行html文件:
要求输入一个Token,然后点Get flag!按钮:
代码逻辑就是输入一个字符串,然后经过计算对比得到正确的flag
我们先查看源代码:
<html>
<head>
<title>Flag in your Hand</title>
<style type="text/css">
body {
padding-left: 30%;
}
#flag {
font-family: Garamond, serif;
font-size: 36px;
}
#flagtitle {
font-family: Garamond, serif;
font-size: 24px;
}
.rightflag {
color: green;
}
.wrongflag {
color: red;
}
</style>
<script src="script-min.js"></script>
<script type="text/javascript">
var ic = false;
var fg = "";
function getFlag() {
var token = document.getElementById("secToken").value;
ic = checkToken(token);
fg = bm(token);
showFlag()
}
function showFlag() {
var t = document.getElementById("flagTitle");
var f = document.getElementById("flag");
//!!判断ic是否为空,为空则t.innerText赋为第一个值
t.innerText = !!ic ? "You got the flag below!!" : "Wrong!";
t.className = !!ic ? "rightflag" : "wrongflag";
f.innerText = fg;
}
</script>
</head>
<body>
<h1>Flag in your Hand</h1>
<p>Type in some token to get the flag.</p>
<p>Tips: Flag is in your hand.</p>
<div>
<p>
<span>Token:</span>
<span><input type="text" id="secToken"/></span>
</p>
<p>
<input type="button" value="Get flag!" onclick="getFlag()" />
</p>
</div>
<div>
<p id="flagTitle"></p>
<p id="flag"></p>
</div>
</body>
</html>
输入框的id=“secToken”,值保存在token变量中,先调用checkToken(token)函数检查token
查看checkToken()函数:
它在script-min.js只有这一处声明,是个假的TOKEN返回给ic变量,下面showFlag()函数也是根据ic变量的值判断输出flag的
之后的fg = bm(token);就是根据输入的字符串计算得到一个最终的结果,之后在前端最下面显示出来
注意这里的ic变量的值和fg变量的值是没有关系的,但是最终输出flag的时候他们都要求是正确的值
先求flag字符串的内容的过程:fg变量
查看bm(token)函数:
它层层嵌套,调用了3个函数str2rstr_utf8(s)、rstr()、rb()来处理输入的字符串
先看str2rstr_utf8(s)函数:
这个函数只是将我们输入的字符串转换成utf-8编码格式
直接在控制台输入str2rstr_utf8(s)函数的代码之后
str2rstr_utf8(“123”);调用函数对字符"123"处理之后输入的结果是"123"
也可以直接在chrome浏览器里面新增js代码来调用原有的str2rstr_utf8(s)函数
在chrome浏览器的Sources->Snippets中
选择New snippet就能新建一个js文件
输入str2rstr_utf8(“abcd”);调用str2rstr_utf8(s)函数
之后点击Ctrl+Enter就能运行js代码:
之后就是rstr()函数:
依次调用了rstr2binl(s)、binl()、binl2rstr()函数
同样调用三个函数查看输出:
发现他们对输入字符串做了复杂的处理,
查看rstr2binl(s)函数源代码:
function rstr2binl(input) {
var output = Array(input.length >> 2);
for (var i = 0; i < output.length; i++)
output[i] = 0;
for (var i = 0; i < input.length * 8; i += 8)
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
return output;
}
从代码我们可以看到根据输入的字符串,决定了输出的字符串,所以现在我们无法直接逆向这部分的代码。
接下来只能从ic变量去找突破口了,因为当我们输入的字符串是正确的字符串的时候,ic变量的值会被赋为true
可以看到ic变量的初始值被设为了false,但最后输出正确的flag的时候,要求它的值是true,所以我们去看ic变量的值在哪被更改了:
只有在ck(s)函数中有4次更改,也就是要输出正确的flag,ic的值就要在这被修改成true。
实际上ck(s)函数是被binl(x, len)调用的:
也就是上面的计算flag的值的过程中,调用了ck(s)函数去验证输入的字符串s,如果符合要求,就把ic的值设为true,然后在输出计算得到的flag。
我们接着分析ck(s)函数:
function ck(s) {
try {
ic
} catch (e) {
return;
}
var a = [118, 104, 102, 120, 117, 108, 119, 124, 48,123,101,120];
if (s.length == a.length) {
for (i = 0; i < s.length; i++) {
if (a[i] - s.charCodeAt(i) != 3)
return ic = false;
}
return ic = true;
}
return ic = false;
}
就是把输入的字符串的字符的ASCII码和a[]数组中的数逐个比较,一旦出现不是相差3的字符就返回
return ic = false;
所有的字符和数字都相差3时就返回
return ic = true;
我们根据代码逻辑,写出逆向求输入字符串的代码:
var a = [118, 104, 102, 120, 117, 108, 119, 124, 48,123,101,120];
var s="";
for (i = 0; i < a.length; i++) {
s += String.fromCharCode(a[i] - 3);
}
console.log(“结果是:%s”,s);
运行结果:
得到输入的字符串就是security-xbu
将字符串输入到Token输入框中
得到flag:RenIbyd8Fgg5hawvQm7TDQ
以上是关于XCTF-攻防世界CTF平台-Crypto类——4flag_in_your_hand1的主要内容,如果未能解决你的问题,请参考以下文章
XCTF-攻防世界CTF平台-Web类——14supersqli
XCTF-攻防世界CTF平台-Reverse逆向类——31hackme
XCTF-攻防世界CTF平台-Web类——7NewsCenter