zoukankan      html  css  js  c++  java
  • [逆向][Writeup]EIS2016 chkflag .NET程序逆向

    这是一道比较简单的逆向题,难点之处在于chkflag.exe是.NET编译生成的,如果用IDA进行逆向难度很大,因此本题主要考察.NET逆向工具的使用。题目中使用的二进制文件可以从我的github上下载:https://github.com/gsharpsh00ter/reverse

    0x01 工具准备

    在对.NET程序进行反编译时,常用的一个工具为.NET Reflector,但是目前该工具是收费的。本例中我们使用另一款开源的.NET反编译工具dnSpy。dnSpy是一款开源的基于ILSpy发展而来的.NET程序的编辑、反编译和调试神器,可对.NET程序进行反编译和动态调试,界面友好,功能强大。

    dnSpy下载地址:

    https://github.com/0xd4d/dnSpy/releases

    下载后解压直接运行即可,但是需要先安装.NET框架。安装后进行逆向分析和调试的界面如下:

    0x02 逆向

    将chkflag.exe拖入dnspy,查看入口函数,如下:

     1 // chkflag.Module1
     2 // Token: 0x06000001 RID: 1 RVA: 0x00002048 File Offset: 0x00000248
     3 [STAThread]
     4 public static void Main()
     5 {
     6     ReadOnlyCollection<string> commandLineArgs = MyProject.Application.CommandLineArgs;
     7     ulong num = 91713730301111000uL;
     8     string @string = Resources.ResourceManager.GetString("f");
     9     string string2 = Resources.ResourceManager.GetString("i");
    10     string description = MyProject.Application.Info.Description;
    11     //命令行必需有8个参数
    12     if (commandLineArgs.Count != 8)
    13     {
    14         Console.WriteLine(string2);
    15         return;
    16     }
    17     string[] array = Resources.ResourceManager.GetString("p").Split(new char[]
    18     {
    19         ' '
    20     });
    21     checked
    22     {
    23         int num2 = commandLineArgs.Count - 1;
    24         //命令行的每一个参数需要符合array中规定的格式
    25         for (int i = 0; i <= num2; i++)
    26         {
    27             if (!LikeOperator.LikeString(commandLineArgs[i], array[i], CompareMethod.Binary))
    28             {
    29                 Console.WriteLine(@string);
    30                 return;
    31             }
    32         }
    33         //将所有的命令行参数拼接成一个字符串
    34         string text = string.Join("", commandLineArgs);
    35         string text2 = "";
    36         string text3 = "";
    37         int num3 = text.Length - 1;
    38         //对拼接的字符串进行处理,如果某字符为数字,则拼接到text3,反之拼接到text2
    39         for (int j = 0; j <= num3; j++)
    40         {
    41             char c = text[j];
    42             if (char.IsDigit(c))
    43             {
    44                 text3 += Conversions.ToString(c);
    45             }
    46             else
    47             {
    48                 text2 += Conversions.ToString(c);
    49             }
    50         }
    51         //如果拼接后的text3逆序之后转化为整数为num(91713730301111000uL),并且text2逆序之后为description,则将在命令行打印flag
    52         if (ulong.Parse(Strings.StrReverse(text3)) == num && Strings.StrReverse(text2).Equals(description))
    53         {
    54             Console.WriteLine("EIS{" + string.Join("_", commandLineArgs) + "}");
    55             return;
    56         }
    57         Console.WriteLine(@string);
    58     }
    59 }

    0x03 分析

    处理逻辑比较简单。首先,程序会检查命令行参数的个数,参数必须有8个,否则会打印“参数错误”而退出。

     

    然后,程序会检查每一个参数是否符合指定的格式,参数格式在array中指定,通过动态调试,可以得到array的内容如下:

     

    即:["?#?","?##","?#??#?##?","?#","?#?#?#?","#?#","?#??#","?#?#"],其中’?’表示字母,’#’表示数字,比如”?#?”表示第一个参数应该是“字母+数字+字母”的形式。

    之后程序将命令行所有的参数进行拼接,成为一个字符串。

    拼接完命令行参数后,会继续对拼接的字符串进行处理,如果某字符为数字,则拼接到text3,反之拼接到text2

    最后,对text2和text3进行判断。如果text3逆序之后转化为整数为num,并且text2逆序之后为description,则将在命令行打印flag。

    Num的值在反编译得到的代码中可以看到,为91713730301111000UL。

    Description可以通过动态调试得到,为“aFhgRhrVcRttcffDTTn”

     

    通过上述逻辑,用如下python代码进行逆向计算,即可得到我们向chkflag传递的命令行参数:

     1 #!/usr/bin/python2
     2 
     3 patterns     = ["?#?","?##","?#??#?##?","?#","?#?#?#?","#?#","?#??#","?#?#"]
     4 num            = "91713730301111000"
     5 desc        = "aFhgRhrVcRttcffDTTn"
     6 args        = []
     7 numidx         = 0
     8 descidx     = 0
     9 for pattern in patterns:
    10     arg = ""
    11     for k in xrange(0, len(pattern)):
    12         if pattern[k] == '?':
    13             arg += desc[::-1][descidx]
    14             descidx += 1
    15         else:
    16             arg += num[::-1][numidx]
    17             numidx += 1
    18     args.append(arg)
    19 print args

    打印出的命令行参数为:

    ['n0T', 'T00', 'D1ff1c11t', 't0', 'R3c0V3r', '7h3', 'R1gh7', 'F1a9']

    在命令行运行chkflag,并传递上述参数,可得flag:

    最终flag为:

    EIS{n0T_T00_D1ff1c11t_t0_R3c0V3r_7h3_R1gh7_F1a9}

  • 相关阅读:
    luogu P1064|| 01背包||金明的预算
    NOIp蒟蒻的爆零记——HA-0132
    模板输入计划
    1112测试教你做人
    NOIP注意事项
    强连通分量的一二三 | | JZOJ【P1232】 | | 我也不知道我写的什么
    图的割点 | | jzoj【P1230】 | | gdoi | |备用交换机
    【游戏作品】Sunset Game 制作组出品游戏一览
    【说明】我们计划从博客园迁移到知乎啦
    【总结】操作系统的重点
  • 原文地址:https://www.cnblogs.com/gsharpsh00ter/p/6404396.html
Copyright © 2011-2022 走看看