查壳(养成习惯了,不管有没有用都要来那么一下):
![](https://img2023.cnblogs.com/blog/3074711/202305/3074711-20230505070920012-266092211.png)
发现没啥,进IDA瞅瞅:
![](https://img2023.cnblogs.com/blog/3074711/202305/3074711-20230505071020801-348259562.png)
给了一堆字串,且没有主函数,那么我们退出IDA,运行一下:
![](https://img2023.cnblogs.com/blog/3074711/202305/3074711-20230505071119606-1856359135.png)
checkflag,那么必定有方法去检查这玩意:继续找F12:
![](https://img2023.cnblogs.com/blog/3074711/202305/3074711-20230505071215502-1707583011.png)
<!DOCTYPE Html />
<html>
<head>
<title>FLARE On 2017</title>
</head>
<body>
<input type="text" name="flag" id="flag" value="Enter the flag" />
<input type="button" id="prompt" value="Click to check the flag" />
<script type="text/javascript">
document.getElementById("prompt").onclick = function () {
var flag = document.getElementById("flag").value;
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert(rotFlag);
}
}
</script>
</body>
</html>
找到了那么个方法:有我们不认识的函数(查呗):
document.getElementById:大概的意思是从文件中获取字串,放在这里就是当我们点击check的时候,获取我们输入的字符串。
var flag = document.getElementById("flag").value:将获得的字串给flag
flag.replace:对flag进行某种变化
两个参数:/[a-zA-Z]/g 和 一个方法返回的值 function(c)
/[a-zA-Z]/g :一种正则表达式:指代所有的字母,包括大小写。
到这里我们大概懂在做啥了:对我们输入的flag的所有字母进行变化,变化后如果与“PyvragFvqrYbtvafNerRnfl@syner-ba.pbz”相同,那么我们输入的flag就是正确的。
那么我们就需要了解字母是怎么替换的:function(c)
这里我们可以拆开来看,首先我们先看最终返回的值是啥 c : c - 26,也就是说在某种条件成立的情况下要么返回 它自身+13,要么返回 (它自身+13)-26 后的值
往前推进能看到条件,(c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13):首先是判断从输入的flag中拿出的字符是否为大小写。 如果该字符为小写,则拿‘z’字符和该字符+13的值进行比较(这里注意,这里重新给c赋值了,所以后边才会有+13的操作),来决定返回的是 它自身+13,还是返回 它自身+13-26 后的值,反之则是拿‘Z’来比较。
这里有个点要注意如果用的不是python来写脚本的话要注意越界的问题,不然始终都是错误的。
上脚本(很明显,凯撒的套路)咯,定点爆破:
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
string Des = "PyvragFvqrYbtvafNerRnfl@syner-ba.pbz";
string flag = "";
for (int i = 0; i < Des.size(); i++) {
if((Des[i] >= 'a' && Des[i] <= 'z') ||(Des[i] >= 'A' && Des[i] <= 'Z')){
//写凯撒的加密方法
for (int j = 'a'; j <= 'z'; j++) {
int c = (int)j;
char a = (c <= 'Z' ? 90 : 122) >= (c += 13) ? char(c) : char(c - 26);
if(a == Des[i])flag += j;
}
for (int j = 'A'; j <= 'Z'; j++) {
int c = (int)j;
char a = (c <= 'Z' ? 90 : 122) >= (c += 13) ? char(c) : char(c - 26);
if(a == Des[i])flag += j;
}
}else{
flag += Des[i];
}
}
cout << "flag{" << flag << "}" << endl;
return 0;
}
对于这类,感觉还是爆破比较来的快,不然费脑子(个人脑缺失)
得到flag{ClientSideLoginsAreEasy@flare-on.com}收工。