https://buuoj.cn/challenges#[BJDCTF2020]BJD%20hamburger%20competition

Unity 3D 逆向

https://blog.csdn.net/Lenard404/article/details/123854785

找到 Assembly-CSharp.dll 用 ILSpy 打开

保存代码,用 VS 打开,找到 ButtonSpawnFruit.cs 文件

using System.Security.Cryptography;
using System.Text;
using UnityEngine;
 
public class ButtonSpawnFruit : MonoBehaviour
{
	public GameObject toSpawn;
 
	public int spawnCount = 1;
 
	public AudioSource[] audioSources;
 
	public string result = "";
 
	public static string Md5(string str)
	{
		byte[] bytes = Encoding.UTF8.GetBytes(str);
		byte[] array = MD5.Create().ComputeHash(bytes);
		StringBuilder stringBuilder = new StringBuilder();
		byte[] array2 = array;
		foreach (byte b in array2)
		{
			stringBuilder.Append(b.ToString("X2"));
		}
		return stringBuilder.ToString().Substring(0, 20);
	}
 
	public static string Sha1(string str)
	{
		byte[] bytes = Encoding.UTF8.GetBytes(str);
		byte[] array = SHA1.Create().ComputeHash(bytes);
		StringBuilder stringBuilder = new StringBuilder();
		byte[] array2 = array;
		foreach (byte b in array2)
		{
			stringBuilder.Append(b.ToString("X2"));
		}
		return stringBuilder.ToString();
	}
 
	public void Spawn()
	{
		FruitSpawner component = GameObject.FindWithTag("GameController").GetComponent<FruitSpawner>();
		if (!component)
		{
			return;
		}
		if (audioSources.Length != 0)
		{
			audioSources[Random.Range(0, audioSources.Length)].Play();
		}
		component.Spawn(toSpawn);
		string text = toSpawn.name;
		if (text == "汉堡底" && Init.spawnCount == 0)
		{
			Init.secret += 997;
		}
		else
		{
			switch (text)
			{
			case "鸭屁股":
				Init.secret -= 127;
				break;
			case "胡罗贝":
				Init.secret *= 3;
				break;
			case "臭豆腐":
				Init.secret ^= 18;
				break;
			case "俘虏":
				Init.secret += 29;
				break;
			case "白拆":
				Init.secret -= 47;
				break;
			case "美汁汁":
				Init.secret *= 5;
				break;
			case "柠檬":
				Init.secret ^= 87;
				break;
			case "汉堡顶":
				if (Init.spawnCount == 5)
				{
					Init.secret ^= 127;
					string str = Init.secret.ToString();
					if (Sha1(str) == "DD01903921EA24941C26A48F2CEC24E0BB0E8CC7")
					{
						result = "BJDCTF{" + Md5(str) + "}";
						Debug.Log(result);
					}
				}
				break;
			}
		}
		Init.spawnCount++;
		Debug.Log(Init.secret);
		Debug.Log(Init.spawnCount);
	}
}
 

查表 SHA 加密

得到 1001

MD5加密 但是结果并不对

看看具体的加密函数

public static string Md5(string str)
{
	byte[] bytes = Encoding.UTF8.GetBytes(str);
	byte[] array = MD5.Create().ComputeHash(bytes);
	StringBuilder stringBuilder = new StringBuilder();
	byte[] array2 = array;
	foreach (byte b in array2)
	{
		stringBuilder.Append(b.ToString("X2"));
	}
	return stringBuilder.ToString().Substring(0, 20);
}
  • ToString("X2") byte 转化为大写的两位 16 进制
  • Substring(0, 20) 截取前面 20 位
import hashlib  
  
flag = hashlib.md5("1001".encode()).hexdigest().upper()  
  
print(flag[:20])
B8C37E33DEFDE51CF91E