强网杯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();
        }
    }
}
posted @ 2022-07-31 17:58  wgf4242  阅读(262)  评论(0编辑  收藏  举报