[BJDCTF2020]BJD hamburger competition]

识别Unity游戏

Android平台的apk包可以直接解压,看是否有./assets/bin/Data/Managed目录,也可以查看lib文件夹下面包含的一些so,如果有libmono,libunity等模块,基本可以确定是unity游戏了。

Android平台中C#编写的主逻辑模块代码静态编辑之后存储于Assembly-CSharp.dll文件中。因为unity的跨平台,Android平台是unity编译的游戏,那么其对应的IOS平台上也是unity编译出来的。如果希望直接从IOS上面去看是否是unity游戏,可以提取游戏中的主模块查看是否有unity之类的函数即可。

这道题找对文件分析就行,dnSpy打开Assembly-CSharp.dll文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  1 using System;
2 using System.Security.Cryptography;
3 using System.Text;
4 using UnityEngine;
5
6 // Token: 0x02000004 RID: 4
7 public class ButtonSpawnFruit : MonoBehaviour
8 {
9 // Token: 0x0600000A RID: 10 RVA: 0x00002110 File Offset: 0x00000310
10 public static string Md5(string str)
11 {
12 byte[] bytes = Encoding.UTF8.GetBytes(str);
13 byte[] array = MD5.Create().ComputeHash(bytes);
14 StringBuilder stringBuilder = new StringBuilder();
15 foreach (byte b in array)
16 {
17 stringBuilder.Append(b.ToString("X2"));
18 }
19 return stringBuilder.ToString().Substring(0, 20);
20 }
21
22 // Token: 0x0600000B RID: 11 RVA: 0x00002170 File Offset: 0x00000370
23 public static string Sha1(string str)
24 {
25 byte[] bytes = Encoding.UTF8.GetBytes(str);
26 byte[] array = SHA1.Create().ComputeHash(bytes);
27 StringBuilder stringBuilder = new StringBuilder();
28 foreach (byte b in array)
29 {
30 stringBuilder.Append(b.ToString("X2"));
31 }
32 return stringBuilder.ToString();
33 }
34
35 // Token: 0x0600000C RID: 12 RVA: 0x000021C8 File Offset: 0x000003C8
36 public void Spawn()
37 {
38 FruitSpawner component = GameObject.FindWithTag("GameController").GetComponent<FruitSpawner>();
39 if (component)
40 {
41 if (this.audioSources.Length != 0)
42 {
43 this.audioSources[Random.Range(0, this.audioSources.Length)].Play();
44 }
45 component.Spawn(this.toSpawn);
46 string name = this.toSpawn.name;
47 if (name == "汉堡底" && Init.spawnCount == 0)
48 {
49 Init.secret += 997;
50 }
51 else if (name == "鸭屁股")
52 {
53 Init.secret -= 127;
54 }
55 else if (name == "胡罗贝")
56 {
57 Init.secret *= 3;
58 }
59 else if (name == "臭豆腐")
60 {
61 Init.secret ^= 18;
62 }
63 else if (name == "俘虏")
64 {
65 Init.secret += 29;
66 }
67 else if (name == "白拆")
68 {
69 Init.secret -= 47;
70 }
71 else if (name == "美汁汁")
72 {
73 Init.secret *= 5;
74 }
75 else if (name == "柠檬")
76 {
77 Init.secret ^= 87;
78 }
79 else if (name == "汉堡顶" && Init.spawnCount == 5)
80 {
81 Init.secret ^= 127;
82 string str = Init.secret.ToString();
83 if (ButtonSpawnFruit.Sha1(str) == "DD01903921EA24941C26A48F2CEC24E0BB0E8CC7")
84 {
85 this.result = "BJDCTF{" + ButtonSpawnFruit.Md5(str) + "}";
86 Debug.Log(this.result);
87 }
88 }
89 Init.spawnCount++;
90 Debug.Log(Init.secret);
91 Debug.Log(Init.spawnCount);
92 }
93 }
94
95 // Token: 0x04000005 RID: 5
96 public GameObject toSpawn;
97
98 // Token: 0x04000006 RID: 6
99 public int spawnCount = 1;
100
101 // Token: 0x04000007 RID: 7
102 public AudioSource[] audioSources;
103
104 // Token: 0x04000008 RID: 8
105 public string result = "";
106 }

经过SHa1加密得到DD01903921EA24941C26A48F2CEC24E0BB0E8CC7,经过解密就可以知道str=1001

再用MD5加密就可以得到b8c37e33defde51cf91e1e03e51657da

19行代码只取了20位,最后就可以得出flag

[WUSTCTF2020]Cr0ssfun

找到主函数

fun9

要想跳出循环就要判断check这个函数,点进去看看

fun8

都是简单的判断,直接可以得出

[FlareOn6]Overlong

ida打开,主函数

long3

第六行的函数,unk_402008的28位给Text,后面再用MessageBoxA输出text,运行试试

long5

输出中没有看到flag,看看unk_402008的数据

long4

发现不止28个,有175个数据,就是AF

用OD打开

long1

将压入栈的1C改为AF即可