BUUCTF/SimpleRev

今天做这道题做的很爽,于是想拿出来写一写我的思路

首先用IDA打开,查看main函数

 首先就是程序会判断你是否会进入这个游戏,容易看出Decry()函数是重要的,点击进入

各种初始变量的申明先留着,直接查看后面的部分

图中的join函数,点进去发现其实就是把两个字符串合成一个

所以上面做的事情是合成了初始的key和flag(!!注意这里是小端存储!!)

接着看下一part

这里也很容易理解,其实就是把key字符串全部从大写变为小写

到这里

text=killshadow

key=adsfkndcls

到下面就是叫你输入flag了

printf("Please input your flag:");
  while ( 1 )
  {
    v1 = getchar();
    if ( v1 == 10 )
      break;
    if ( v1 == 32 )
    {
      ++v2;
    }
    else
    {
      if ( v1 <= 96 || v1 > 122 )
      {
        if ( v1 > 64 && v1 <= 90 )
        {
          str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
          ++v3;
        }
      }
      else
      {
        str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
        ++v3;
      }
      if ( !(v3 % v5) )
        putchar(32);
      ++v2;
    }
  }
  if ( !strcmp(text, str2) )
    puts("Congratulation!\n");
  else
    puts("Try again!\n");
  return __readfsqword(0x28u) ^ v11;

 一整个while循环,先把你输入的字符进行一系列处理后 ,再弄到str2上,最后如果str2与text相同,则输入正确

再观察核心代码

发现除了ascii码为32的字符外,无论你输入什么字符,都会进行

 str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;

这个操作

但这是取余操作,没办法有效逆推,只能爆破

我这里假设输入的全部都是大写字母,如果有某个大写字母符合上述条件,则生成flag的一个字符

下面附上脚本~~

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int main(){
    string key = "adsfkndcls";
    string text = "killshadow";
    char res[10];
    for(int i=0;i<10;i++){
        for(int j=65;j<=90;j++){
            if(text[i]==(j-39-key[i]+97)%26+97){
                res[i]=j;
                break;
            }
        }
    }
    cout<<res<<endl;
    system("pause");
    return 0;
}

 最后得到flag{KLDQCUDFZO}

猜你喜欢

转载自blog.csdn.net/weixin_51681694/article/details/125628768