[NSSRound#16 Basic]CompileMe!!! WP

[NSSCTF Round#16 Basic] CPR-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_52640415/article/details/135575169参考了石氏是时试大佬的WP,学到很多东西!

附件把我吓坏了,一个极大的C#文件,VS打开直接崩溃了

显然不能直接编译

用记事本看看代码

[NSSRound#16 Basic]CompileMe!!! WP_第1张图片

前面是函数的主体,可以看出是一个魔改TEA解密的函数,变量名做了混淆

四个数的key { 0x57656c636f6d6520, 0x746f204e53534354, 0x4620526f756e6423, 0x3136204261736963 }

密文(但是取值时会被再次加密){ 0xc60b34b2bff9d34a, 0xf50af3aa8fd96c6b, 0x680ed11f0c05c4f1, 0x6e83b0a4aaf7c1a3, 0xd69b3d568695c3c5, 0xa88f4ff50a351da2, 0x5cfa195968e1bb5b, 0xc4168018d92196d9 }

经典 delta=0x9E3779B9

注意var ____ = Enumerable.Range(0, 32).Select(______ => ___ * (32 - (uint)______)).ToArray();这里做了一个逆序

其它参数基本照抄形成魔改TEA

接下来是大量的val计算,对每个密文再次加密

[NSSRound#16 Basic]CompileMe!!! WP_第2张图片

由于编译过于复杂,应当用python处理巨量信息,筛选出return后面的部分

lines = open('Program.cs','rb').readlines()  #以二进制读取所有行

a = b'def cal(val):\n'
for line in lines:
    if line.startswith(b'            return val'):
        a += b'    val = '+line[18:]
#把我们需要的运算部分提取出来写到新的文件里去
a += b'    return val'
#结尾加上return防止报错“TypeError: unsupported operand type(s) for &: 'NoneType' and 'int'”
print(a)
open('recrypt.py','wb').write(a)

在Program.cs所在目录下启动cmd,用python draw.py提取

[NSSRound#16 Basic]CompileMe!!! WP_第3张图片

由此得到再加密的函数(注意结尾要有return防止报错“TypeError: unsupported operand type(s) for &: 'NoneType' and 'int'”)

[NSSRound#16 Basic]CompileMe!!! WP_第4张图片

由此构建解密脚本

from ctypes import *
from pwn import p64   #转换为64位无符号整型
from recrypt import cal  #引用提取出来的加密函数
 
def decrypt(v,key):
    v0 = c_uint64(v[0])  #也是转化为64位无符号整型
    v1 = c_uint64(v[1]) 
    delta = 0x9E3779B9
    sum1 = c_uint64((delta) * 32)
    for i in range(32):       
        v1.value -= (((v0.value << 4) ^ (v0.value >> 5)) + v0.value) ^ (sum1.value + key[(sum1.value >> 11) & 3])
        sum1.value -= delta       
        v0.value -= (((v1.value << 4) ^ (v1.value >> 5)) + v1.value) ^ (sum1.value + key[sum1.value & 3])
    
    return p64(cal(v0.value)&0xffffffffffffffff)[::-1]+p64(cal(v1.value)&0xffffffffffffffff)[::-1]
    #输出的整数转化为字符串 反转后连在一起 
enc = [0xc60b34b2bff9d34a, 0xf50af3aa8fd96c6b, 0x680ed11f0c05c4f1, 0x6e83b0a4aaf7c1a3, 0xd69b3d568695c3c5, 0xa88f4ff50a351da2, 0x5cfa195968e1bb5b, 0xc4168018d92196d9]
key = [0x57656c636f6d6520, 0x746f204e53534354, 0x4620526f756e6423, 0x3136204261736963]
 
flag = b''
for i in range(0,8,2):
    flag += decrypt(enc[i:i+2],key)
 
print(flag)

你可能感兴趣的:(python,c#)