强网杯-2022-GameMaster(.NET+C#+提取文件+z3爆破)

强网杯-2022-GameMaster

刚开始看这道题的时候,其实是有点懵的,还是自己做的题太少了T _ T.就此为了加深印象,复现这道题。

丢进Exeinfo PE中,可以发现是c#写的.net程序,我们用Dnspy打开(一个专门反编译c#,.net等的一个软件)。
在这里插入图片描述

我们直接找到此软件的主函数,分析其逻辑
在这里插入图片描述

这里我们可以发现,是读取了我们的附件所给的gamemesage里面的数据,读取到filestream,

在这里插入图片描述

分析下面的代码,可以知道,这部分实现的代码,就是根据我们的按键,施行对应的操作,其中Enter键和space键,对应的函数下都有deal和stand,hit键,如果简单的玩过一下这个游戏,我们很容易知道,这几个函数实现的功能就是进行输赢的判断和检测自己的金钱还有多少,游戏是否继续。

在这里插入图片描述

我们分析之后,发现这个esc这个键下的函数十分的可疑,我们跟进去看看。

在这里插入图片描述

整体来说,这个函数并没有做什么,但是这个函数中调用的另一个函数,goldFUNC,我们继续跟进。
在这里插入图片描述

发现这个函数里面全是flag判断啥的异常处理函数,这里应该就是我们关键的加密函数了,但是这些判断看起来一头雾水,我们继续分析。

在这里插入图片描述

我们翻到后面我们发现了一个非常不一样的异常处理函数,而且这里出现了Program.memory,这个就是程序的开头,将我们文件读取的数据存储的地方。我们继续向下分析,看还有没有同样的操作。
在这里插入图片描述

这里有一个AES-ECB的加密

在这里插入图片描述

我们发现了一个函数调用,我们进去看看。

在这里插入图片描述

这里也是AES-ECB加密,但是我们分析之后,我们可以发现它并没有对我们的文件的数据进行改变,因此我们不管它。

在这里插入图片描述

到这里我们就可以知道了,我们的gamemesage是被加密过的文件,首先异或了34,之后又进行了AES-ECB加密,我们写一个脚本进行解密即可

from Crypto.Cipher import AES

# 定义AES加密算法的密钥和块大小
key = b'Brainstorming!!!'
block_size = 16

# 创建AES加密算法对象
cipher = AES.new(key, AES.MODE_ECB)

# 打开待解密的文件
with open('gamemessage', 'rb') as f:
    ciphertext = f.read()

# 对读取的数据进行异或操作
ciphertext = bytes([byte ^ 34 for byte in ciphertext])

# 对密文进行解密
plaintext = cipher.decrypt(ciphertext)

# 将解密后的明文写入到新文件中
with open('data', 'wb') as f:
    f.write(plaintext)

将解密后的文件输出到data

我们放入winhex中分析,可以发现是.net的一个输出文件,但是并未有文件头,我们在这里面进行搜索,看看是否能找到一些看信息

在这里插入图片描述

我们可以找到一个MZ的头,我们将其前面的数据删除,然后将其加入dll的后缀,因为此文件是以dll文件的形式载入我们的程序的
在这里插入图片描述

我们将其放入dnspy中分析。

在这里插入图片描述

有两个关键函数,分析这两个函数是将先前的三段数据进行求解,下一个函数就是将解变成密钥后对我们的数据进行异或,我们先写个脚本爆破出x,y,z.

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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]

解出我们的x,y,z之后,在写解密脚本,解出我们的flag

l=[156324965, 868387187, 3131229747]
arr=[0]*12
for i in range(3):
    for j in range(4):
        arr[i*4+j]=(l[i]>>j*8)&0xff
enc=[60, 100, 36, 86, 51, 251, 167, 108, 116, 245,
				207, 223, 40, 103, 34, 62, 22, 251, 227]
for i in range(len(enc)):
    print(chr(enc[i]^arr[i%len(arr)]),end='')

即可得出flag: Y0u_@re_G3meM3s7er!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值