【2022 Geek Challenge】个人出题记录
【2022 Geek Challenge】个人出题记录
都是些远没有现在CTF签到难的题目(,毕竟是新生赛,不过也是自己第一次给正规赛事命题,就记录一下。
Hello Binary
本来签到该上IDA题目的,不过后来放了几个教程题上去,就整了个怪活。
题目链接:https://pan.baidu.com/s/1M9wfl4KHvhHqtjJckgnUAA?pwd=bin0
flag藏在了PE头部,覆盖掉了原本的This program cannot be run in DOS mode的部分,不影响程序正常功能。
拿记事本,010editor,IDA等打开都可以直接看到flag。
IDA由于是加载后的视图,不太方便找,可以以二进制模式打开。
其实可以试下DOS模式下会不会直接把flag吐出来,摆了
SYC{E#t4r_th4_dOo2_o&_>h4_Rev4rseWorLd}
CrazyThursday
题目链接:https://pan.baidu.com/s/1FYv6Hkhxnl05B5czkuyLkw?pwd=GAME
加密就是标准的RC4,根据其对称性利用lazyida在程序内部paste(详情见https://www.bilibili.com/video/BV1WQ4y1X7TY/,或者拿脚本跑都很简单,程序去了符号。
本题在data段里面放了一个加密过的DLL,在程序运行时会对DLL解密。
这里利用了一个第三方库mmloader,其作用是在内存中加载DLL,而非从文件系统中加载。根据符号找到MiniCry的加密函数对输入进行验证(相当于用DLL实现了SMC)。有学弟说感觉有很多无用代码,其实都是这一过程的实现。
下图为关键函数。
这里就分出了两种做法
- 动态调试,找到函数指针,令IDA将其识别为函数
- dump内存中解密后的DLL,静态分析。或者dump DLL再手动解密
SYC{wwww@RC_RC_RC_RC@wwww:)H}
For_Girl…s?
本来想把数据写到C++的DLL里面,后来降难度了,纯C#还是很好做的。
题目链接:https://pan.baidu.com/s/1GFA2nPUZ7jjdAyeUFs6QpA?pwd=GAME
本题是个C#写的Winform程序,使用dnSpy来逆向会非常方便。
C#逆向涉及到的一些面向对象语法和GUI程序的基本逻辑不再赘述。
很容易可以看出本题的加密是XTEA,但是实际解密时会发现解密失败。
本题的主要考点在于利用Timer的时间回调修改了密文,因为程序在15s内退出,所以解题时只需要写个循环对密文异或15次,每次异或后解密即可。
这里因为出题时的疏忽没有考虑到异或之间的重复作用,导致第一次异或和第九次异或加密数据都会完全解密。(拖到DDL临时搓的加密...玉玉了)
解题脚本如下,从dnSPYcv出来直接改的。
using System.Collections.Generic; using System.Text; namespace ConsoleApp1 { internal class Program { public static List<uint> LuckyNum = new List<uint> { 76U, 110U, 71U, 115U }; public static List<uint> GirlsHeart = new List<uint> { 1536903838U, 521453914U, 3046417386U, 1214738056U }; private static List<uint> DeCrypt(List<uint> v, List<uint> k) { uint v0 = v[0]; uint v1 = v[1]; uint delta = 2654435769U; uint sum = delta * 32; for (int i = 0; i < 32; i++) { v1 -= ((v0 << 4 ^ v0 >> 5) + v0 ^ sum + LuckyNum[Convert.ToInt32(sum >> 11 & 3U)]); sum -= delta; v0 -= ((v1 << 4 ^ v1 >> 5) + v1 ^ sum + LuckyNum[Convert.ToInt32(sum & 3U)]); } return new List<uint>() { v0,v1 }; } static void Main(string[] args) { for (int i = 0; i < 15; i++) { uint num = Convert.ToUInt32(i); for (int k = 0; k < GirlsHeart.Count(); k++) { GirlsHeart[k] ^= (num << 8 | num << 4 | num << 2 | num); } var decrypt = DeCrypt(GirlsHeart, LuckyNum); decrypt.AddRange(DeCrypt(GirlsHeart.Skip(2).Take(2).ToList<uint>(), LuckyNum)); List<byte> flaglist = new List<byte>(); foreach (var item in decrypt) { for (int j = 0; j < 4; j++) { flaglist.Add((byte)((item >> (8 * j)) & 0xFF)); } } foreach (var item in LuckyNum) { flaglist.Add((byte)item); } ASCIIEncoding encoding = new ASCIIEncoding(); string flag = encoding.GetString(flaglist.ToArray()); Console.WriteLine(flag); } } } }
SYC{y%U_@2e_@11_m7_wLnGs}