强网杯2022 wp re复现学习
Re
Gamemaster
dnsspy打开解密。
goldFunc函数中看到解密方式为手动输入字符串。共3段。分别为 9位key+任1字符+4位key
AQLMP65790MF3K
Z5M0G6P160EEPW
D253Y5J0Y06VD6
第一段 将 gamemessage ^ 34
第二段 aes 解密
三段 Balance值是不确定的。理论上要拿到3段AchivePoint用于后面解密。
然后debug可以调出一段解密的文件,不知道啥格式不会打开。看到flag字样。
可以用dnsspy dump或者用Python解密
mb = open('gamemessage', 'rb').read()
mb = bytearray([x ^ 34 for x in mb])
from Crypto.Cipher import AES
key = bytearray([66, 114, 97, 105, 110, 115, 116, 111, 114, 109, 105, 110, 103, 33, 33, 33])
cryptor = AES.new(key, AES.MODE_ECB)
data = cryptor.decrypt(mb)
open('output', 'wb').write(data)
。。看到PE头。 This program cannot be run in DOS
。把前面删掉还是exe。再用dnspy打开这个文件。显示出加密解密方法。。
z3求解一下 achievecode1,2,3
# Create to bit-vectors of size 32
from z3 import *
x, y, z = BitVecs('x y z', 64)
s = Solver()
KeyStream = [0] * 40
key1 = [101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173, 189, 198, 166, 140, 183, 42, 247, 223, 24, 106,
20, 145, 37, 24, 7, 22, 191, 110, 179, 227, 5, 62, 9, 13, 17, 65, 22, 37, 5]
num = -1
for i in range(320):
x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1)
y = (((y >> 30 ^ y >> 27) & 1) | y << 1)
z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1)
flag = i % 8 == 0
if flag:
if i!=0:
s.add(KeyStream[num] == key1[num])
num += 1
KeyStream[num] = (KeyStream[num] << 1) | (((z >> 32 & 1 & (x >> 30 & 1)) ^ (((z >> 32 & 1) ^ 1) & (y >> 31 & 1))))
print(s.check())
print(s.model())
# [y = 868387187, x = 156324965, z = 3131229747]
然后直接改一下cs源代码输出flag
using System;
using System.Linq;
using System.Text;
// using System.Windows.Forms;
namespace T1Class
{
// Token: 0x02000002 RID: 2
public class T1
{
// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
private static void Check1(ulong x, ulong y, ulong z, byte[] KeyStream)
{
int num = -1;
for (int i = 0; i < 320; i++)
{
x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1UL) | x << 1);
y = (((y >> 30 ^ y >> 27) & 1UL) | y << 1);
z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1UL) | z << 1);
bool flag = i % 8 == 0;
if (flag)
{
num++;
}
KeyStream[num] = (byte) ((long) ((long) KeyStream[num] << 1) |
(long) ((ulong) ((uint) ((z >> 32 & 1UL & (x >> 30 & 1UL)) ^
(((z >> 32 & 1UL) ^ 1UL) & (y >> 31 & 1UL))))));
}
}
// Token: 0x06000002 RID: 2 RVA: 0x00002110 File Offset: 0x00000310
private static void ParseKey(ulong[] L, byte[] Key)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
Key[i * 4 + j] = (byte) (L[i] >> j * 8 & 255UL);
}
}
}
// Token: 0x06000003 RID: 3 RVA: 0x0000215C File Offset: 0x0000035C
public T1()
{
try
{
// string environmentVariable = Environment.GetEnvironmentVariable("AchivePoint1");
// string environmentVariable2 = Environment.GetEnvironmentVariable("AchivePoint2");
// string environmentVariable3 = Environment.GetEnvironmentVariable("AchivePoint3");
// bool flag = environmentVariable == null || environmentVariable2 == null || environmentVariable3 == null;
bool flag = false;
if (!flag)
{
// ulong num = ulong.Parse(environmentVariable); // 20
// ulong num2 = ulong.Parse(environmentVariable2); // 195
// ulong num3 = ulong.Parse(environmentVariable3); // 168
ulong[] array = new ulong[3];
byte[] array2 = new byte[40];
byte[] array3 = new byte[40];
byte[] array4 = new byte[12];
byte[] key1 = new byte[]
{
101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173, 189, 198, 166, 140, 183, 42, 247, 223, 24, 106,
20, 145, 37, 24, 7, 22, 191, 110, 179, 227, 5, 62, 9, 13, 17, 65, 22, 37, 5
};
byte[] key2 = new byte[]
{60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227};
array[0] = 156324965;
array[1] = 868387187;
array[2] = 3131229747;
T1.Check1(array[0], array[1], array[2], array2);
bool flag2 = key1.SequenceEqual(array2);
if (flag2)
{
T1.ParseKey(array, array4);
for (int i = 0; i < key2.Length; i++)
{
key2[i] ^= array4[i % array4.Length];
}
Console.WriteLine(Encoding.Default.GetString(key2)); // Y0u_@re_G3meM3s7er!
// MessageBox.Show("flag{" + Encoding.Default.GetString(key2) + "}", "Congratulations!",
// MessageBoxButtons.OK);
}
}
}
catch (Exception)
{
}
}
static void Main(string[] args)
{
T1 t = new T1();
}
}
}