BUUCTF-RE-SimpleRev

一、查壳

64位文件

二、IDA分析

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  char v4; // [rsp+Fh] [rbp-1h]

  while ( 1 )
  {
    while ( 1 )
    {
      printf("Welcome to CTF game!\nPlease input d/D to start or input q/Q to quit this program: ", argv, envp);
      v4 = getchar();
      if ( v4 != 'd' && v4 != 'D' )
        break;
      Decry();
    }
    if ( v4 == 'q' || v4 == 'Q' )
      Exit();
    puts("Input fault format!");
    v3 = getchar();
    putchar(v3);
  }
}

Decry()为关键函数

 1 unsigned __int64 Decry()
 2 {
 3   char v1; // [rsp+Fh] [rbp-51h]
 4   int v2; // [rsp+10h] [rbp-50h]
 5   int v3; // [rsp+14h] [rbp-4Ch]
 6   int i; // [rsp+18h] [rbp-48h]
 7   int v5; // [rsp+1Ch] [rbp-44h]
 8   char src[8]; // [rsp+20h] [rbp-40h]
 9   __int64 v7; // [rsp+28h] [rbp-38h]
10   int v8; // [rsp+30h] [rbp-30h]
11   __int64 v9; // [rsp+40h] [rbp-20h]
12   __int64 v10; // [rsp+48h] [rbp-18h]
13   int v11; // [rsp+50h] [rbp-10h]
14   unsigned __int64 v12; // [rsp+58h] [rbp-8h]
15 
16   v12 = __readfsqword(0x28u);
17   *(_QWORD *)src = 'SLCDN';  //小端序标记
18   v7 = '\0';
19   v8 = 0;
20   v9 = 'wodah';  //是小端序标记的
21   v10 = '\0';
22   v11 = 0;
23   text = join(key3, (const char *)&v9);  //key3=kills v9=wodah  text=killshadow
24   strcpy(key, key1);  //key1=ADSFK
25   strcat(key, src);   //连接两个char类型  key=ADSFKNDCLS
26   v2 = 0;
27   v3 = 0;
28   getchar();
29   v5 = strlen(key); 
30   for ( i = 0; i < v5; ++i )
31   {
32     if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
33       key[i] = key[v3 % v5] + 32;
34     ++v3;
35   }
36   printf("Please input your flag:", src);
37   while ( 1 )
38   {
39     v1 = getchar();
40     if ( v1 == '\n' ) //输入为换行符,退出
41       break;
42     if ( v1 == ' ' )  //输入为空格,则v2+1
43     {
44       ++v2;
45     }
46     else
47     {
48       if ( v1 <= 96 || v1 > 122 )  //如果v1不为小写
49       {
50         if ( v1 > 64 && v1 <= 90 )  //如果v1为大写
51           str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;  //对str2[v2]进行处理
52       }
53       else   //如果v1为小写字母
54       {
55         str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
56       }
57       if ( !(v3 % v5) )  //如果不为大小写字母,则不进行处理
58         putchar(32);
59       ++v2;
60     }
61   }
62   if ( !strcmp(text, str2) )  //如果text和str2储存的相同,则成功
63     puts("Congratulation!\n");
64   else
65     puts("Try again!\n");
66   return __readfsqword(0x28u) ^ v12;
67 }

对第30-35行分析后  发现 30-35是把key从大写转到小写 key="adsfkndcls"

#include <iostream>
#include<stdio.h>
#include<string.h>
int main()
{
    char key[]= "ADSFKSLCDN";
    int v5;
    v5 = 10;
    int i,v3 = 0;
    for (i = 0; i < v5; ++i) {
        if (key[v3 % v5] > 64 && key[v3 % v5] <= 90)
            key[i] = key[v3 % v5] + 32;
        ++v3;
    }
    printf_s("%s\n",key);
}
View Code

解法有二

Ⅰ爆破

key="ADSFKNDCLS"
text="killshadow"
s=""
flag=""
loop="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

v2 = 0
v3 = 0
v5 = len(key)
for i in range(0,v5):
    if ( ord(key[i]) > 64 and ord(key[i]) <= 90 ):
        s += chr(ord(key[i]) + 32)
    else:
        s +=key[i]
print(s)
#变小写
for i in range(0,len(text)):
    for j in loop:
        if ord(text[i])==(ord(j)-39-ord(s[i])+97)%26+97:
            flag+=j

print(flag)

 

Ⅱ 逆推

#include <stdio.h>
#include <string.h>
int main(void)
{
    char text[] = "killshadow";
    char key[] = "adsfkndcls";
    int key_ = strlen(key), text_ = strlen(text), i, j;
    char str2[15] = { 0 };
    for (i = 0; i < text_; i++)
        for (j = 0;; j++)
        {
            str2[i] = text[i] - 97 + 26 * j + 39 - 97 + key[i];
            if (str2[i] > 64 && str2[i] < 91)
                break;
        }
    printf("flag{%s}", str2);
    return 0;
}

 

三、flag

flag{KLDQCUDFZO}

posted @ 2020-04-07 23:35  Nicky_啦啦啦是阿落啊  阅读(232)  评论(0编辑  收藏  举报