moectf2023-天网

C#逆向接触的不多 一些C#的用法也不熟悉 正好跟着ZM师傅的WP复现一遍学一学
题目附件+最终工程 : https://wwk.lanzouj.com/iMUBa1rp2icb

因为这题我们要自己编写加载 所以最好把C#提取出来 用ILSPY把核心模块re1提取出来 vs2022打开

在这里插入图片描述
在这里插入图片描述

这样就很方便 也能很容易查看交叉引用
输入fakeflag后得到这种输出
在这里插入图片描述

本来是一个while true 但是会因为随机到除数为零而导致异常
只是这里的异常没有处理?
而Flaghelper那儿有AppDomain.CurrentDomain.UnhandledException += delegate
搜了搜发现C#的委托可以用来实现事件和回调方法

注意到这里:
在这里插入图片描述

就是在遍历右边列出的一大堆 FlagMachine_xxxx 而chosen刚好取出的也是4位
下面的SetFlag Vmeflag
在这里插入图片描述

然后这个setflag是套着的 一个套一个 还会输出BrainPower
发现其共有接口是 IFlagMachine 但是每个实现都对flag异或了不同的值
最终在 FakeFlagMachineVmeflag进行最后的校验
IsRealFlag

一个大check 但是这些都是写好了的 我们只需要关注参数怎么来的
在这里插入图片描述

关键点就是parameter 追溯到前面的ResetState 发现是8byte
往前跟踪一下看看这个参数怎么传进来的
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果能动调就很显然 但是前面有一大段函数进行了反调试check 只能静态分析
不难猜到其实Meow~!?!那四个8byte的字符串就是传进来的parameter

分析一下现在得到的信息:
输入一个长度为72的flag
取四个字符串中的一个作为parameter
在一大堆FlagMachine_xxxx中找到与flag前4个字符匹配的进行调用 每个函数xor的值不一样
最后进入IsRealFlag check

那么就爆破可能情况吧 : parameters+FlagMachine_xxxx
用python提取出函数名的xxxx 修改C#进行爆破

提取文件名:

import os

filepath = r"D:\浏览器下载\moectf2023天网\re1\KoitoCoco.MoeCtf"
namelist = os.listdir(filepath)
names = []
for c in namelist:
    try:
        if(c[-8]=='_'):
            names.append(c[-7:-3])
    except:
        pass

with open(r"D:\浏览器下载\moectf2023天网\re1\dic.txt","r+") as f:
    for name in names:
        f.write(name)
        f.write('\n')

print("[+] Done!")

由于我们是ILSPY反编译 不可能完全还原 如果调用全部的话肯定编译错误
所以我们只在几个关键.cs修改 不必加载整个程序 利用 C#顶级语句
可以不用是用Main

修改Program.cs

using System;
using System.IO;
using System.Linq;
using System.text;
using KoitoCoco.MoeCtf;


string[] s = File.ReadAllLines("./dic.txt");
string[] paras = { "Meow~!?!", "meoW?!~~", "me0w~?!!", "mEow????" };

foreach (var para in paras)
{
    Console.Write(para + ": ");
    foreach(var ss in s)
    {
        string text = "moectf" + ss;
        string chosen = text.Substring(7, 4);
        // 下面这段照抄原程序遍历的代码
        if (Activator.CreateInstance((from item in AppDomain.CurrentDomain.GetAssemblies()
                                      from type in item.GetTypes()
                                      where type.Name.EndsWith(chosen)
                                      select type).FirstOrDefault((Type i) => i.Name.Contains("FlagMachine"), typeof(FlagMachine))) is IFlagMachine flagMachine)
        {


            flagMachine.SetFlag(Encoding.UTF8.GetBytes(s4));
            flagMachine.VmeFlag(text);
        }
    }
    Console.Write(para + " Finished!\n");
}

然后修改IsRealFlag 只check前11位 然后满足条件就输出parameters和11位的flag

	public static bool IsRealFlag(byte[] flag, byte[] paramaters)
	{
		ResetState(paramaters);
		int[] array = new int[72]
		{
			143, 75, 130, 35, 251, 51, 51, 49, 92, 145,
			151, 13, 30, 200, 47, 14, 231, 100, 49, 169,
			56, 25, 94, 176, 116, 11, 128, 10, 186, 63,
			185, 45, 216, 55, 190, 72, 130, 200, 139, 252,
			58, 250, 37, 151, 179, 220, 200, 35, 111, 41,
			100, 87, 203, 54, 7, 81, 59, 153, 165, 71,
			255, 195, 220, 144, 112, 243, 227, 251, 228, 232,
			246, 251
		};
		int[] array2 = new int[11]; // 我们现在爆破check前11位 moectf{xxxx
		for (int k = 0; k < 11; k++)
		{
			array2[k] ^= GetNextSpellcard();
		}
		for (int l = 0; l < 11; l++)
		{
			array[l] ^= flag[l] ^ array2[l];
		}
		bool ok = true;
		for(int i = 0; i < 11; i++)
		{
			if (array[i]!=0)
				ok = false;
		}
		if (ok == true)
		{
			Console.Write("Find!\n");
			Console.WriteLine(Encoding.UTF8.GetBytes(flag));
			foreach(var par in paramaters)
			{
				Console.Write(par);
                Console.Write(", ");
            }
			Console.WriteLine();
        }
	}


写好直接是跑不起来一点…
捣鼓半天终于跑起来了 几个点注意:

然后删掉那些没啥用的b/c/i/j .cs 然后根据报错慢慢调整 就能make来跑起来了
在这里插入图片描述

啊哈哈哈…
Let the bass kick Ooooooo…
在这里插入图片描述

那就把唱BrainPower的删掉吧…
ButAnotherYetAnother两个函数里的Jooo…删掉
然后就开始爆破~
慢慢等 毕竟要跑 4x9906
由于是复现 我直接把para顺序调一调

在这里插入图片描述

!!!
得到了parameters 那么直接再次修改Program.cs调用输出即可
我们直接在KoitoMagicalShop.cs加一个函数 直接xor输出

KoitoMagicalShop.Get_Ans:

 public static bool Get_Ans(byte[] paramaters)
 {
     ResetState(paramaters);
     int[] array = new int[72]{
     143, 75, 130, 35, 251, 51, 51, 49, 92, 145,
         151, 13, 30, 200, 47, 14, 231, 100, 49, 169,
         56, 25, 94, 176, 116, 11, 128, 10, 186, 63,
         185, 45, 216, 55, 190, 72, 130, 200, 139, 252,
         58, 250, 37, 151, 179, 220, 200, 35, 111, 41,
         100, 87, 203, 54, 7, 81, 59, 153, 165, 71,
         255, 195, 220, 144, 112, 243, 227, 251, 228, 232,
         246, 251
 };
     int[] array2 = new int[72];
     for (int k = 0; k < 72; k++)
     {
         array2[k] ^= GetNextSpellcard();
     }
     for (int l = 0; l < 72; l++)
     {
Console.Write((array[l] ^ array2[l]));
Console.Write(' ');
     }
     var b = true;
     return b;
 }

Program.sc

byte[] paras = { 231, 239, 247, 240, 136, 161, 120, 14 };
KoitoMagicalShop.Get_Ans(paras);

在这里插入图片描述

转成chr
moectf{nUynafeaaz_gOoD_jo6!_you_have_fed_The_CaT_in_The_neT!_xSMrlYDuuM}



总结: 很好的题 加深了一点对C#的理解 也学会了如何用ILSPY+VS来修改&重编译C#工程

  • 45
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值