2025 强网杯S9 Reverse 复现
1502
字
8
分钟
2025 强网杯S9 Reverse 复现
- 1 CCB 2026 Half-Final Guangzhou
- 2 2025 强网杯S9 Reverse 复现 本文
- 3 LitCTF2025 Personal WriteUP
- 4 FCTF2025 Personal Writeup
孩子们,我又被 RE 肘击辣 😭
PolyEncryption
本题使用 Docker 部署,但是所给的文件不足以本地搭建……
题目只给了一个 dll,拖进 DIE,发现是 .NET,故使用 ILSpy 进行反编译
Warning
不要用 dnSpy,因为 dll 用了异步编程,所以编译的时候会编译成状态机的形式。用 dnspy 看的话只能反编译到状态机的代码,用 ilspy 才能完整反编译。
即使我使用 dnSpy 的最新构建版本,依然无法完整反编译…… C# 那篇已经更新信息了。
作为对比,对于 Main 方法,dnSpy 的反编译结果只有 12 行,而 ILSpy 则是足足 284 行!
// saw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null// Sawusing System;using System.Diagnostics;using System.Net;using System.Net.Sockets;using System.Reflection;using System.Security.Cryptography;using System.Text;using System.Threading;using System.Threading.Tasks;
private static async Task Main(string[] args){ if (args.Length != 1) { Console.WriteLine("Usage: dotnet saw.dll [input]"); Console.WriteLine(" where input is 16 hexa bytes (eg abe74e3a9c375b3428bf31d1f8fa49c1)"); Environment.Exit(1); } man.BlockSize = 128; man.Mode = CipherMode.CBC; man.Padding = PaddingMode.PKCS7; k = SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(typeof(Saw).Assembly.FullName)); s[1023] = 3207972492L; s[1024] = 1190065579L; s[1025] = 4165979424L; s[1026] = 2693353696L; s[1027] = 3628337899L; s[1028] = 1707638109L; s[1029] = 1003779598L; s[1030] = 2653425729L; s[1031] = 795752593L; s[1032] = 2469382657L; long[] array = new long[16]; Array.Copy(s, 1017, array, 0, 16); iv = Array.ConvertAll(array, (long x) => (byte)x); TcpListener tcpListener = new TcpListener(IPAddress.Loopback, 0); tcpListener.Start(); Process p = Process.Start(new ProcessStartInfo("python3", "-m saw " + ((IPEndPoint)tcpListener.LocalEndpoint).Port) { Environment = { { "PYTHONPATH", Assembly.GetEntryAssembly().Location } } }); client = tcpListener.AcceptTcpClient(); await Hack(); await Track(); int rr = 0; while (true) { Console.Error.Write("."); await Shreck(); if (rr == 0) { s[32] = Convert.ToInt64(args[0].Substring(0, 8), 16); s[33] = Convert.ToInt64(args[0].Substring(8, 8), 16); s[34] = Convert.ToInt64(args[0].Substring(16, 8), 16); s[35] = Convert.ToInt64(args[0].Substring(24, 8), 16); } else if (rr % 2 == 1) { if (rr != 1) { await Stop(await Crack(new byte[32] { 34, 38, 13, 204, 106, 91, 87, 35, 115, 198, 124, 92, 83, 151, 127, 227, 60, 108, 237, 212, 71, 88, 37, 39, 222, 28, 237, 242, 207, 61, 89, 65 })); } else { await Stop(await Crack(new byte[32] { 54, 26, 153, 43, 207, 163, 66, 102, 1, 251, 172, 137, 133, 103, 252, 200, 133, 6, 227, 185, 100, 190, 49, 220, 132, 230, 14, 201, 184, 28, 84, 127 })); sp += 3; } long[] array2 = s; array2[2] = await Stop(await Crack(new byte[16] { 132, 17, 89, 19, 158, 87, 26, 91, 138, 184, 20, 203, 22, 142, 33, 67 })); array2 = s; array2[3] = await Stop(await Crack(new byte[16] { 98, 124, 165, 114, 4, 73, 122, 239, 35, 224, 182, 58, 230, 239, 169, 171 })); if (rr == 1) { s[4] = 1038097261L; } else { s[4] ^= s[3]; } } else { sp -= 27; await Stop(await Crack(new byte[32] { 181, 158, 168, 62, 5, 218, 108, 22, 225, 44, 69, 4, 169, 112, 225, 186, 212, 234, 186, 217, 245, 102, 219, 46, 107, 236, 2, 37, 80, 8, 162, 183 })); await Stop(await Crack(new byte[32] { 71, 166, 143, 191, 134, 170, 65, 147, 11, 69, 123, 125, 140, 156, 32, 225, 68, 85, 198, 59, 6, 58, 62, 75, 142, 62, 22, 169, 7, 21, 26, 177 })); for (int ii = 0; ii < 4; ii++) { await Stop(await Crack(new byte[32] { 88, 244, 228, 34, 209, 136, 53, 33, 174, 103, 199, 211, 90, 244, 91, 46, 98, 141, 50, 45, 70, 160, 34, 209, 131, 19, 95, 66, 187, 185, 87, 236 })); await Stop(await Crack(new byte[32] { 59, 134, 219, 11, 168, 34, 42, 6, 142, 30, 47, 12, 175, 97, 187, 166, 191, 165, 206, 91, 56, 92, 35, 91, 63, 232, 2, 235, 246, 41, 249, 60 })); await Stop(await Crack(new byte[32] { 30, 47, 78, 72, 232, 144, 186, 158, 145, 46, 78, 42, 66, 78, 48, 177, 201, 84, 194, 246, 32, 77, 153, 26, 204, 139, 24, 149, 70, 89, 23, 50 })); await Stop(await Crack(new byte[32] { 88, 244, 228, 34, 209, 136, 53, 33, 174, 103, 199, 211, 90, 244, 91, 46, 98, 141, 50, 45, 70, 160, 34, 209, 131, 19, 95, 66, 187, 185, 87, 236 })); await Stop(await Crack(new byte[32] { 59, 134, 219, 11, 168, 34, 42, 6, 142, 30, 47, 12, 175, 97, 187, 166, 191, 165, 206, 91, 56, 92, 35, 91, 63, 232, 2, 235, 246, 41, 249, 60 })); await Stop(await Crack(new byte[32] { 30, 47, 78, 72, 232, 144, 186, 158, 145, 46, 78, 42, 66, 78, 48, 177, 201, 84, 194, 246, 32, 77, 153, 26, 204, 139, 24, 149, 70, 89, 23, 50 })); await Stop(await Crack(new byte[32] { 88, 244, 228, 34, 209, 136, 53, 33, 174, 103, 199, 211, 90, 244, 91, 46, 98, 141, 50, 45, 70, 160, 34, 209, 131, 19, 95, 66, 187, 185, 87, 236 })); await Stop(await Crack(new byte[32] { 59, 134, 219, 11, 168, 34, 42, 6, 142, 30, 47, 12, 175, 97, 187, 166, 191, 165, 206, 91, 56, 92, 35, 91, 63, 232, 2, 235, 246, 41, 249, 60 })); await Stop(await Crack(new byte[32] { 30, 47, 78, 72, 232, 144, 186, 158, 145, 46, 78, 42, 66, 78, 48, 177, 201, 84, 194, 246, 32, 77, 153, 26, 204, 139, 24, 149, 70, 89, 23, 50 })); await Stop(await Crack(new byte[32] { 47, 110, 238, 143, 41, 255, 113, 160, 229, 92, 84, 132, 31, 128, 72, 253, 98, 154, 102, 114, 68, 165, 121, 194, 102, 210, 191, 221, 49, 209, 210, 215 })); await Stop(await Crack(new byte[32] { 59, 134, 219, 11, 168, 34, 42, 6, 142, 30, 47, 12, 175, 97, 187, 166, 68, 235, 237, 14, 9, 156, 105, 253, 49, 93, 204, 138, 86, 162, 159, 183 })); await Stop(await Crack(new byte[32] { 59, 134, 219, 11, 168, 34, 42, 6, 142, 30, 47, 12, 175, 97, 187, 166, 191, 165, 206, 91, 56, 92, 35, 91, 63, 232, 2, 235, 246, 41, 249, 60 })); await Stop(await Crack(new byte[32] { 30, 47, 78, 72, 232, 144, 186, 158, 145, 46, 78, 42, 66, 78, 48, 177, 201, 84, 194, 246, 32, 77, 153, 26, 204, 139, 24, 149, 70, 89, 23, 50 })); } await Stop(await Crack(new byte[32] { 164, 53, 148, 8, 250, 208, 160, 70, 126, 59, 160, 104, 222, 18, 194, 130, 172, 224, 232, 3, 9, 43, 214, 128, 13, 213, 251, 91, 231, 216, 221, 212 })); long[] array2 = s; long num = s[1]; array2[32] = num ^ await Stop(await Crack(new byte[16] { 132, 17, 89, 19, 158, 87, 26, 91, 138, 184, 20, 203, 22, 142, 33, 67 })); array2 = s; num = s[2]; array2[33] = num ^ await Stop(await Crack(new byte[16] { 98, 124, 165, 114, 4, 73, 122, 239, 35, 224, 182, 58, 230, 239, 169, 171 })); array2 = s; num = s[3]; array2[34] = num ^ await Stop(await Crack(new byte[16] { 41, 105, 145, 250, 243, 41, 66, 60, 57, 250, 209, 67, 192, 42, 111, 95 })); array2 = s; num = s[4]; array2[35] = num ^ await Stop(await Crack(new byte[16] { 46, 125, 65, 197, 84, 64, 181, 17, 52, 236, 114, 213, 42, 180, 217, 142 })); } if (rr == 22) { await blient.GetStream().WriteAsync(new byte[15] { 0, 0, 0, 15, 0, 0, 0, 1, 0, 1, 10, 0, 0, 0, 0 }, default(CancellationToken)); p.Kill(); _ = new byte[16]; for (int num2 = 0; num2 < 4; num2++) { byte[] bytes = BitConverter.GetBytes((uint)s[32 + num2]); Array.Reverse(bytes); Console.Write(BitConverter.ToString(bytes).Replace("-", "")); } Environment.Exit(0); } await Breck(); await client.GetStream().WriteAsync(BitConverter.GetBytes(0), default(CancellationToken)); while (await Hack()) { } bool flag = true; while (flag) { flag = await Horror(); } rr++; }}很明显,要部署 Docker,环境里至少还需要一个 python 脚本,Where is it?
DIE 已经有提示:

此处 DIE 识别不完全正确。识别为 JAR 的实际依然是 ZIP。
DIE 内置的提取器,选择 Binary 模式,“扫描”并“转储全部”:

改 jar 后缀为 zip,解压体积最大的那个 zip(polyencrypt.dll.9200_2b8c.zip),得到完整文件:
d---- 2025/10/25 22:09 META-INF-a--- 2024/5/6 4:18 338 Curse.class-a--- 2024/5/6 4:18 2048 Curse.dll-a--- 2024/5/6 4:18 736 Hack.class-a--- 2024/5/11 16:53 48524 polyencrypt.dll-a--- 2024/5/11 16:53 242 polyencrypt.runtimeconfig.json-a--- 2024/5/6 4:18 1337 remote_pdb_LICENSE.txt-a--- 2024/5/6 4:18 3985 remote_pdb.py-a--- 2025/10/10 22:55 69 run.sh-a--- 2024/5/6 4:18 8823 Saw.class-a--- 2024/5/6 4:18 5025 saw.py文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
2025 强网杯S9 Reverse 复现
https://blog.watermelonabc.top/p/6375919/
相关文章
智能推荐
1
CCB 2026 Half-Final Guangzhou
Writeup
蒟蒻的第一次 CCB 线下赛 ;)
2
LitCTF2025 Personal WriteUP
Writeup
LitCTF 2025 本人负责部分的 WriteUP
3
FCTF2025 Personal Writeup
Writeup
第一篇正式 Writeup,来自 FZU 校赛
4
出题人的“恶意”
学习笔记
CTF是一场游戏,设计者们想达成的便是让游玩者不自觉地进入错误的道路
5
视频也可以含恶意代码吗
Writeup
何等 Pixel Art 的代码
随机文章
随机推荐