buu-reverse findit CSRe

buu-reverse-findit

关键代码

怎么提取jar可看:http://poilzero.sipc115.club/index.php/archives/72/

提取jar文件用jd-gui打开可以很容易找到这段关键代码

          public void onClick(View param1View) {
            char[] arrayOfChar1 = new char[17]; //0-16
            char[] arrayOfChar2 = new char[38]; //
            int i = 0;
            while (true) {
              String str;
              if (i >= 17) {
                if (String.valueOf(arrayOfChar1).equals(edit.getText().toString())) {
                  for (i = 0;; i++) {
                    if (i >= 38) { //i:0-37字符
                      str = String.valueOf(arrayOfChar2);
                      text.setText(str);
                      return;
                    } 
                    if ((b[i] >= 'A' && b[i] <= 'Z') || (b[i] >= 'a' && b[i] <= 'z')) {
                      arrayOfChar2[i] = (char)(b[i] + 16);
                      if ((arrayOfChar2[i] > 'Z' && arrayOfChar2[i] < 'a') || arrayOfChar2[i] >= 'z')
                        arrayOfChar2[i] = (char)(arrayOfChar2[i] - 26); 
                    } else {
                      arrayOfChar2[i] = b[i];
                    } 
                  } 
                  break;
                } 
              } else {
                if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) {
                  str[i] = (char)(a[i] + 18);
                } else if ((a[i] >= 'A' && a[i] <= 'Z') || (a[i] >= 'a' && a[i] <= 'z')) {
                  str[i] = (char)(a[i] - 8);
                } else {
                  str[i] = a[i];
                } 
                i++;
                continue;
              } 
              text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~");
              return;
            } 
          }
        });

使用androidkiller吧压缩包改.apk后缀后打开查到这两个字符串的定义(类汇编)

    :array_0
    .array-data 2
        0x54s
        0x68s
        0x69s
        0x73s
        0x49s
        0x73s
        0x54s
        0x68s
        0x65s
        0x46s
        0x6cs
        0x61s
        0x67s
        0x48s
        0x6fs
        0x6ds
        0x65s
    .end array-data

    .line 23
    nop

    :array_1
    .array-data 2
        0x70s
        0x76s
        0x6bs
        0x71s
        0x7bs
        0x6ds
        0x31s
        0x36s
        0x34s
        0x36s
        0x37s
        0x35s
        0x32s
        0x36s
        0x32s
        0x30s
        0x33s
        0x33s
        0x6cs
        0x34s
        0x6ds
        0x34s
        0x39s
        0x6cs
        0x6es
        0x70s
        0x37s
        0x70s
        0x39s
        0x6ds
        0x6es
        0x6bs
        0x32s
        0x38s
        0x6bs
        0x37s
        0x35s
        0x7ds
    .end array-data
.end method

转换成字符

base=[0x54,0x68,0x69,0x73,0x49,0x73,0x54,0x68,0x65,0x46,0x6c,0x61,0x67,0x48,0x6f,0x6d,0x65]
code=""
for i in  range(len(base)):
    code+=chr(base[i])
print(code)

base=[0x70,0x76,0x6b,0x71,0x7b,0x6d,0x31,0x36,0x34,0x36,0x37,0x35,0x32,0x36,0x32,0x30,0x33,0x33,0x6c,0x34,0x6d,0x34,0x39,0x6c,0x6e,0x70,0x37,0x70,0x39,0x6d,0x6e,0x6b,0x32 ,0x38,0x6b,0x37,0x35,0x7d]
code=""
for i in  range(len(base)):
    code+=chr(base[i])
print(code)

输出

ThisIsTheFlagHome
pvkq{m164675262033l4m49lnp7p9mnk28k75}

逆向过程

怀疑是维吉尼亚密码(需要密钥),或者凯撒密码,因为没有找到对应的其他字符串作为密钥

使用ThisIsTheFlagHome作为密钥尝试解密得到wocy{e164675262033t4t49ejk7e9mhd28w75}

多次解密也不对,看来是凯撒密码了。

计算偏移

print(abs(0x70-ord('f')))
print(abs(0x76-ord('l')))

输出

10

10

使用10的偏移值解得flag{c164675262033b4c49bdf7f9cda28a75}

buu-reverse-[V&N2020 公开赛]CSRe

基本逻辑

程序直接运行报错了,打开IDA查看发现函数名是乱码的,怀疑加壳了

使用exeinfope查看

Snipaste_2021-02-26_15-23-52.png

查到壳了,使用提示的解壳de4dot

.NET obf/license protector - for ver. < 5.0 - Unpack with : de4dot v3.1 2011-2014 de4dot@gmail.com - http://github.com/0xd4d/de4dot

由于虚拟机中没有对应工具,从网上下载

https://github.com/de4dot/de4dot

然后能够得到未加壳的本体

关键代码

前面已经得知是.net文件了,因此直接用dnspy打开不用IDA了

入口点

// C:\Users\15426\Desktop\reverse\buu\0_256_[V&N2020 公开赛]CSRe\CS-cleaned.exe
// CS_exe, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

// 入口点: Class3.Main
// 时间戳: 5C80ED62 (2019/3/7 18:07:30)

找到主函数

// Token: 0x0600000F RID: 15 RVA: 0x00002374 File Offset: 0x00000574
private static void Main(string[] args)
{
    if (!Class1.smethod_1())
    {
        return;
    }
    bool flag = true;
    Class3 @class = new Class3();
    string str = Console.ReadLine();
    if (Class3.smethod_0("3" + str + "9") != "B498BFA2498E21325D1178417BEA459EB2CD28F8")
    {
        flag = false;
    }
    string text = Console.ReadLine();
    string string_ = Class3.smethod_0("re" + text);
    string text2 = @class.method_0(string_, "63143B6F8007B98C53CA2149822777B3566F9241");
    for (int i = 0; i < text2.Length; i++)
    {
        if (text2[i] != '0')
        {
            flag = false;
        }
    }
    if (flag)
    {
        Console.WriteLine("flag{" + str + text + "}");
    }
}

第一部分调用到的相关函数,其实就是sha1(静态函数)

// Token: 0x0600000E RID: 14 RVA: 0x0000231C File Offset: 0x0000051C
public static string smethod_0(string string_0)
{
    byte[] bytes = Encoding.UTF8.GetBytes(string_0);
    byte[] array = SHA1.Create().ComputeHash(bytes);
    StringBuilder stringBuilder = new StringBuilder();
    foreach (byte b in array)
    {
        stringBuilder.Append(b.ToString("X2"));
    }
    return stringBuilder.ToString();
}

结合理解,第一部分就是验证sha1("3" + str + "9")==B498BFA2498E21325D1178417BEA459EB2CD28F8

第二部分调用到的相关函数(成员方法)

// Token: 0x0600000D RID: 13 RVA: 0x000022C8 File Offset: 0x000004C8
public string method_0(string string_0, string string_1)
{
    string text = string.Empty;
    char[] array = string_0.ToCharArray();
    char[] array2 = string_1.ToCharArray();
    int num = (array.Length < array2.Length) ? array.Length : array2.Length; //取小的长度
    for (int i = 0; i < num; i++)
    {
        text += (int)(array[i] ^ array2[i]);
    }
    return text;
}

结合理解,也就是第二部分异或后结果是,而众所周知,只有相等的数异或才会等于零。

因此本质上第二部分就是验证sha1('re'+text)==63143B6F8007B98C53CA2149822777B3566F9241

逆向过程

分别逆sha1得到

  • 314159=》1415
  • return=》turn

因此flag为:flag{1415turn}

Last modification:February 27, 2021
如果觉得我的文章对你有用,请随意赞赏。咖啡(12RMB)进度+100%,一块巧克力(1RMB)进度+6%。
(赞赏请备注你的名称哦!后台记录中来自理工小菜狗)