题目
首先来到给定的地址
题意很明确$miwen是加密之后的字符串,我们只需要逆向解密出miwen就能得到flag
我们先来代码审计
$_o=strrev($str);
strrev()函数是字符串的倒置
for($_0=0;$_0<strlen($_o);$_0++)
for循环,从零开始循环字符串的长度次
$_c=substr($_o,$_0,1);
$__=ord($_c)+1;
$_c=chr($__);
$_=$_.$_c;
这里是for循环的内部,也就是每次循环要做的事情,首先是一个substr()函数
第一个参数是目标字符串,第二个参数是起始位置,第三个参数是截取的长度
那就是说,每次截取的长度是1,起始位置从0到字符串末尾
第二个函数是ord将字符串的第一位转换成ascii码的形式,
$__变量存储它加一的值
第三个函数,chr()将ascii码转换成字符,然后又存到了$_c中
最后的变量每次加上当前的字符
这个循环的作用其实就是将字符串中的每个字符做了+1的操作
return str_rot13(strrev(base64_encode($_)));
最后还出现了三个函数
我们先来看第一步操作,是将当前的字符串做了base64加密的操作
第二步用到了strrev函数,给当前字符串做了反转
第三步用到了str_rot13函数,这个函数的作用是将字符串中的所有字母都向前移动十三位,例如A+1=B Z+1=A,是这样循环的形式
代码部分
这里不太会php和python,所以用了c++写了一个str_rot13()函数,base64用的bp(找机会自己写一个),str_rot13函数很巧妙它对字母做了+13的操作,我们知道字母总共有26,13正好是26的一半,所以经过两次加密的情况下就是+26,就又变成了原来的字符,所以加密算法即是解密算法
判断当前字符是字母之后,我们先将字符+13,然后判断当前字符是否大于最大的字母z或者Z,如果大于我们就对它进行取余的操作然后加上A就是结果
#include <bits/stdc++.h>
using namespace std;
int main (void)
{
string st="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
vector<char> str;
//相当于str_rot13()函数
for(int i=st.size()-1;i>=0;--i)
{
int c=st[i];
if(c>=int('A')&&c<=int('Z'))
{
c+=13;
if(c>int('Z'))
c=c%(int('Z')+1)+int('A');
str.push_back(char(c));
}
else if(c>=int('a')&&c<=int('z'))
{
c+=13;
if(c>int('z'))
c=c%(int('z')+1)+int('a');
str.push_back(char(c));
}
else
str.push_back(st[i]);
}
cout<<"encode_base64: ";
for(int i=0;i<str.size();i++) cout<<str[i];
cout<<endl;
//base64解密后~88:36e1bg8438e41757d:29cgeb6e48c`GUDTO|;hbmg
st="~88:36e1bg8438e41757d:29cgeb6e48c`GUDTO|;hbmg";
for(int i=st.size()-1;i>=0;--i)
{
char c=st[i];
cout<<char(c-1);
}
return 0;
}
运行结果
总结
加密算法还挺好玩