小菜鸟一枚 发表于 2020-10-2 16:14

学破解第128天,《攻防世界reverse练习区debug》学习

本帖最后由 小菜鸟一枚 于 2020-10-2 16:27 编辑

## 学破解第128天,《攻防世界reverse练习区debug》学习
前言:
  从小学到大专(计算机网络技术专业),玩过去的,所以学习成绩惨不忍睹,什么证书也没考,直到找不到工作才后悔,不知道怎么办才好。

  2017年12月16日,通过19元注册码注册论坛账号,开始做伸手党,潜水一年多,上来就是找软件。(拿论坛高大上的软件出去装X)

  2018年8月某一天,报名了华中科技大学网络教育本科(计算机科学与技术专业)2018级秋季。(开始提升学历)

  2019年6月17日,不愿再做小菜鸟一枚,开始零基础学习破解。(感谢小糊涂虫大哥在我刚开始学习脱壳时,录制视频解答我的问题)

  2020年7月7日,感谢H大对我的鼓励,拥有了第一篇获得优秀的文章。(接下来希望学习逆向,逆天改命)

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:[https://www.52pojie.cn/thread-1278021-1-1.html](https://www.52pojie.cn/thread-1278021-1-1.html)
立帖为证!--------记录学习的点点滴滴

### 0x1下载软件观察行为
  1.去攻防世界找到这个debug题目,下载文件,看到是一个exe程序。


  2.PEID查壳:Microsoft Visual C# v7.0 / Basic .NET,说明这是一个.NET程序,IDA用不了。

  3.丢到OD里面程序直接跑飞了,断不下来,去text段也搜不到字符串,OD也报废了。

  4.这可怎么办,小菜鸟一枚只会OD和IDA搜搜字符串呀,不懂.NET程序,硬着头皮用dnspy反编译吧,反编译结果如下:
```
// C:\Documents and Settings\Administrator\桌面\3d43134e9941483e970e936e88c245f2.exe
// ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

// Entry point: ᜅ.ᜀ

using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
















```

  5.去百度一下:assembly是集合,汇编,编译的意思,上面大概说的是它的编译环境吧,展开列表看看


  6.看上图,就是一些函数,看不出什么东西,直接把程序跑起来看看,发现就是输入一个flag,然后错误提示是wrong,这些就是我简单侦查到的信息。

### 0x2动静结合调试分析
  1.还是继续dnspy分析,几个函数不知道看哪个,看软件右上角有个start选项,点击跑起来看看:


  2.看到程序停在了02000003这个位置,虽然没看到main函数,但是应该这里就是程序开始执行的地方了吧。
```
using System;
using System.Security.Cryptography;
using System.Text;

// Token: 0x02000003 RID: 3
internal class ᜅ
{
      // Token: 0x06000006 RID: 6 RVA: 0x00002144 File Offset: 0x00000344
      private static string ᜀ(string A_0)
      {
                byte[] bytes = Encoding.ASCII.GetBytes(A_0);
                return "flag{" + BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(bytes)).Replace("-", "") + "}";
      }

      // Token: 0x06000008 RID: 8 RVA: 0x000021F0 File Offset: 0x000003F0
      private static void ᜀ(string[] A_0)
      {
                string b = null;
                string value = string.Format("{0}", DateTime.Now.Hour + 1);
                string a_ = "CreateByTenshine";
                ᜅ.ᜀ(a_, Convert.ToInt32(value), ref b);
                string a = Console.ReadLine();
                if (a == b)
                {
                        Console.WriteLine("u got it!");
                        Console.ReadKey(true);
                }
                else
                {
                        Console.Write("wrong");
                }
                Console.ReadKey(true);
      }

      // Token: 0x06000005 RID: 5 RVA: 0x0000212B File Offset: 0x0000032B
      private static int ᜀ(int A_0, int A_1)
      {
                return (new int[]
                {
                        2,
                        3,
                        5,
                        7,
                        11,
                        13,
                        17,
                        19,
                        23,
                        29,
                        31,
                        37,
                        41,
                        43,
                        47,
                        53,
                        59,
                        61,
                        67,
                        71,
                        73,
                        79,
                        83,
                        89,
                        97,
                        101,
                        103,
                        107,
                        109,
                        113
                }) ^ A_0;
      }

      // Token: 0x06000007 RID: 7 RVA: 0x0000218C File Offset: 0x0000038C
      private static void ᜀ(string A_0, int A_1, ref string A_2)
      {
                int num = 0;
                if (0 < A_0.Length)
                {
                        do
                        {
                              char c = A_0;
                              int num2 = 1;
                              do
                              {
                                        c = Convert.ToChar(ᜅ.ᜀ(Convert.ToInt32(c), num2));
                                        num2++;
                              }
                              while (num2 < 15);
                              A_2 += c;
                              num++;
                        }
                        while (num < A_0.Length);
                }
                A_2 = ᜅ.ᜀ(A_2);
      }
}
```
这段代码看上去被混淆了,函数名,还有一些地方没反编译出来。


  3.小菜鸟一枚一眼就看到了if a==b和后面Console.Write("wrong");,那么是不是只要在这里下断点flag就会出来呢?试试


  4.从上面的图就可以看出字符串a是我输入的52pojie,字符串b应该就是flag了。

  5.输入flag{967DDDFBCD32C1F53527C221D9E40A0B}提交,验证通过了,这道题真的是意外的顺利。

### 0x3算法剖析
  1.既要分析算法,就得看懂代码,从头开始,一步步调试吧,虽然我不懂.NET,但是可以看结果猜代码的作用。

  2.string b =NULL,结合前面的分析,知道这里面一会存的就是flag,string.Format("{0}", DateTime.Now.Hour + 1);与时间相关,但是我看不懂,单步看一下value的值:就是当前系统时间。然后string a_ = "CreateByTenshine";给a_赋值了,接着Convert.ToInt32函数我也看不懂,百度获得以下知识:
> 将字符串转换成数字
> 方法:Convert.ToInt32(string value,int fromBase)
> 将字符串bai转换成数字
> 方法:Convert.ToInt32(string value,int fromBase)
> fromBase为进制(2,8,10,16)
> 如:将2进制(string)转换成10进制(int)
> string strBase2="0101";
> int intBase10=Convert.ToInt32(strBase2,2);
> 结果:5

  3.不是很明白,那就继续走一步就是了,然而这一单步flag就已经出来了,所以重新来吧,到上面这一句跟进去,没看懂,应该是进入了API函数里面去了,跳出来,再次进去,看到
```
      A_0      "CreateByTenshine"      string
      private static void ᜀ(string A_0, int A_1, ref string A_2)
      {
                int num = 0;
                if (0 < A_0.Length)
                {
                        do
                        {
                              char c = A_0;//取第一个元素C
                              int num2 = 1;
                              do
                              {
                                        c = Convert.ToChar(ᜅ.ᜀ(Convert.ToInt32(c), num2));//看不懂,将c不断变换
                                        num2++;
                              }
                              while (num2 < 15);
                              A_2 += c;
                              num++;
                        }
                        while (num < A_0.Length);
                }
                A_2 = ᜅ.ᜀ(A_2);//                A_2      "[j}yl}ZaL}vkpqv}"      string
      }
}
```
经过这段代码,字符串b被变换成了[j}yl}ZaL}vkpqv}

  4.然后继续进去就来到了拼接正确flag的地方,先将字符串b进行md5加密,可以随便丢到一个在线的md5加密网站试试,得到967DDDFBCD32C1F53527C221D9E40A0B然后拼上flag{},正确的flag就出来了。
```
private static string ᜀ(string A_0)
      {
                byte[] bytes = Encoding.ASCII.GetBytes(A_0);
                return "flag{" + BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(bytes)).Replace("-", "") + "}";
      }
```

  5.C#的函数看不懂,只能大概分析到这里了。

### 0x4总结
  1.看了钱老师的华科视频,逆向分析是基础,解决问题是关键,软件逆向分析的水平 <= 软件开发的水平,深以为然,我这不懂C#很难还原它的算法。

  2.这道题目应该考的就是调试程序,程序运行起来很容易看到出flag的点。

  3.慢慢加油,每天进步一点点。

### 0x5参考资料


  **PS:善于总结,善于发现,找到分析问题的思路和解决问题的办法。虽然我现在还是零基础的小菜鸟一枚,也许学习逆向逆天改命我会失败,但也有着成功的可能,只要还有希望,就决不放弃!**

XXBK 发表于 2020-10-2 16:45

我还在你的第一个阶段,在论坛找资源,自己改着玩。碰到违反版规的就去提醒,遇到“狡辩”的就举报。混了几个月,也没实实在在的学到有用的知识。上课学的是Java,Linux,web,mysql这些,主要还是自己学,只靠课上知识是不够的。我们有企业的老师,真的很牛,项目总监真不是吹的,逻辑很强!关注一下你,多学一些知识!:lol

一线生机 发表于 2020-10-9 20:41

帖主,零基础学习,刚开始要怎么做,先看视频么,30了你看我还有机会么,想学这个。刚刚注册了看到你的帖子。

famdo818 发表于 2020-10-2 16:35

感谢分享,论坛有你真好

坑久必神 发表于 2020-10-2 16:52

不错不错,能坚持到今天说明你一直在成功的路上。坚持吧。嗯,我去看看基础教程。? ? ? ? ?

幻蓝2222 发表于 2020-10-2 17:32

楼主讲的很详细,学习了,谢谢!

Gaho2002 发表于 2020-10-2 17:39

这些是什么语言啊

lt199210 发表于 2020-10-2 19:43

不错,感谢分享

雨卷倾城3236 发表于 2020-10-2 21:49

学到了,非常好。

二怪同学 发表于 2020-10-2 23:18

godclever 发表于 2020-10-3 00:42

每一分努力都不会被辜负,加油
页: [1] 2 3 4
查看完整版本: 学破解第128天,《攻防世界reverse练习区debug》学习