zoukankan      html  css  js  c++  java
  • 社团的CTF逆向题WriteUp

    最近社团弄了CTF比赛,然后我就帮忙写了逆向的题目,这里写一下WriteUp,题目和源码在附件中给出

    一个简单的逆向:one_jmp_to_flag.exe

    这题算是签到题,直接OD智能搜索就完事了,flag{Welcome_to_GeekFZCTF}

    一个简单的对比:check.exe

    这一道也算是送分题,可以用IDA直接分析可以看出来,这里就是读取输入的字符串,然后逐个进行对比,这里可以直接用IDA转化为char型就可以看出。flag{sAdf_fDfkl_Fdf}

     

     猜猜那个是flag:whichisflag.exe

     首先加载进IDA,先看一下基本逻辑,输入的flag首先要小于25,然后进行判断进行判断,如果flag[5]=Y,且flag[8] = flag[11],flag[16] = flag[18],上面的都实现了就执行which_is_flag这个函数,我们跟进去看一下。 

     可以看到这是通过flag[5]进行switch跳转,然后我们之前有个判断条件flag[5]=Y,所以这里的跳转就是到89处

     但是我们可以看到,这个flag的长度是大于25的,然后仔细观察一下flag里的内容,可以看出是base64编码过的,我们找个网站进行解码就可以,这里的flag是用python随机出来的,代码也在附件里。flag{YkEj_djkf3_jEj_eUn}

     

     简单的反调试:fts.exe

     其实这道题目就只是用OD调试时会遇到一点反调试,如果用IDA直接分析逻辑就可以了,这里首先用IDA分析先。

    可以看到一个可疑的循环并printf出来字符 ,我们看到逻辑就是用flag_2这个数组的数据与0x11进行异或,我们手动计算一下得出字符串(这里注意的是0x76707D77是小端序,我们要从77开始异或):flag{

     然后我们可以继续往下面找关键循环,函数CheckDebug、fts_Rdtsc、the_end里都有循环输出,然后都解密出来就是:congratulations_for_you}

     

    所以flag就是:flag{congratulations_for_you}

    然后用OD动态调试一下,一开始就是先进行进程的检索,判断是否存在IDA或者OD,然后我们可以通过je直接跳过进行判断的地方。

     跳过第一个反调试的地方后就得看一下我们的main函数入口在哪里(为什么不先找main函数,因为你不跳过第一个反调试即使找到main函数入口也没用,尝试一下就发现跳过了第一个反调试就很容易去到main函数了),我们这里先智能搜索一下可以看到一些字符串,你可以每个都进去看一下,然后发现main函数就在走过八十一难哪里(用IDA可以直接找到)

     

     找到main函数后下断点,然后F9跳过去就可以单步跟踪了,我们可以发现会自己打印出了第一个解密循环

     

     下面继续跟会发现有用到FindWindow函数去查找有没有IDA和OD,然后我们只要不让下面两个je进行跳转就可以,就会再打印出一段flag出来

     跟进去函数里面,可以发现用了ZwQueryInformationProcess进行检测调试端口的,我们不让它跳转就会打印出字符串来

     

     再进入下一个函数中,在里面可以看到rdtsc命令,这个用于把时间保存的指令,这里是基于时间的反调试,我们可以直接在下面的popad下断点然后F9直接跳过,然后就找到了解密循环。

     

     最后进入函数,我们可以看到有一个get函数并且下面的跳转是关键,可以先随机输入一些东西,然后可以看到下面的跳转跳过了我们的printf函数,所以我们让它不跳转,然后就跑出最后的flag出来。

     

     简单的算法:suafa.exe

    这是一个算法,然后这里要道个歉是出题不够严谨,在跑flag的时候会出现多解的情况。正向的核心算法是输入的字符串减去key之后对4求余,然后在key1到key4之间选择字符,最后与我们给定的字符进行对比

     1     char key1[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     2     char key2[65] = "+/abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     3     char key3[65] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
     4     char key4[65] = "0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     5 
     6     char key[27] = "QASWZXDECVFRBNGTHYJUMKIOLP";
     7     int len = strlen(flag);
     8     for(int i=0; i<len; i++)
     9     {
    10         if(int(flag[i]) <= 126 && int(flag[i]) >= 33)
    11         {
    12             if(flag[i]-key[i] > 0)
    13             {
    14                 int the_key = (flag[i]-key[i]) % 4;
    15                 switch (the_key)
    16                 {
    17                     case 0:
    18                         flag[i] = key1[flag[i]-key[i]];
    19                         continue;
    20                     case 1:
    21                         flag[i] = key2[flag[i]-key[i]];
    22                         continue;
    23                     case 2:
    24                         flag[i] = key3[flag[i]-key[i]];
    25                         continue;
    26                     case 3:
    27                         flag[i] = key4[flag[i]-key[i]];
    28                         continue;
    29                     default:
    30                         continue;
    31                 }                
    32             }
    33             else
    34             {
    35                 printf("flag is wrong");
    36                 ExitProcess(0);
    37             }
    38         }
    39     }

     然后在逆向的时候我们用IDA打开基本都能编译出来,然后有一点小问题就是v5 = v4 - v1[key-flag]这里,反编译后与原来的代码int the_key = (flag[i]-key[i])有点差别,不过如果看汇编的代码可以更好的理解

     其中sub eax, flag就是我们的v4 - v1[key-flag],而v4=flag[i],所以理论上flag = v1[key-flag],而我们汇编中flag的值为byte ptr [ebx+edx],这里的ebx可以从前面查看就是key,而edx就相当于索引。不懂得可以自己仔细看一下。

     

    然后分析完就可以写个脚本自己跑出来:flag{this_is_a_easy_suanfa}

     1 #include "stdio.h"
     2 #include "Windows.h"
     3 
     4 int main()
     5 {
     6     char key1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     7     char key2[] = "+/abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     8     char key3[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
     9     char key4[] = "0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    10 
    11     char key[] = "QASWZXDECVFRBNGTHYJUMKIOLP";
    12 
    13     char flag_1[] = "tfoQ5ckkwhX51HYpxAjkMQYTAp5";
    14 
    15     int yushu = 0;
    16 
    17     for(int m=0; m<=26; m++)
    18     {
    19         for(int n=33; n<=126; n++)
    20         {
    21             yushu = n - int(key[m]);
    22             yushu %= 4;
    23             switch (yushu)
    24             {
    25                 case 0:
    26                     if(key1[n - int(key[m])] == flag_1[m])
    27                     {
    28                         printf("%c", n);
    29                     }
    30                     continue;
    31                 case 1:
    32                     if(key2[n - int(key[m])] == flag_1[m])
    33                     {
    34                         printf("%c", n);
    35                     }
    36                     continue;
    37                 case 2:
    38                     if(key3[n - int(key[m])] == flag_1[m])
    39                     {
    40                         printf("%c", n);
    41                     }
    42                     continue;
    43                 case 3:
    44                     if(key4[n - int(key[m])] == flag_1[m])
    45                     {
    46                         printf("%c", n);
    47                     }
    48                     continue;
    49                 default:
    50                     continue;
    51             }            
    52         }
    53         printf("
    ");
    54     }
    55 }

    因为存在多解,所以跑出来得结果是这样子的

     附件:题目、题目源码和脚本:https://github.com/QKSword/CTF-GeekFZ

  • 相关阅读:
    魅蓝Note有几种颜色 魅蓝Note哪个颜色好看
    Android在跳转市场进行评分问题总结
    轻松学会多线程(四)——synchronized同步keyword知多少
    对于stackoverflow的中文翻译的相关问题
    HBase总结(二十)HBase经常使用shell命令具体说明
    Tiny语言执行环境TM机源码
    【IOS工具类】获得设备唯一标识(兼容IOS5,6,7)
    VMwave下Ubuntu扩展磁盘空间
    wordpress搭建后地址栏页面显示IP地址的问题
    成都Java培训机构太多,该如何选择呢?
  • 原文地址:https://www.cnblogs.com/QKSword/p/9095242.html
Copyright © 2011-2022 走看看