跳至主要內容

WKCTF_How to encrypt?

LPrincess大约 2 分钟ctfmiscai

How to encrypt

exp:

import torch  
import torch.nn as nn  
import numpy as np  
# 解决报错:OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.  
import os  
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"  
  
# 读取文件并解析密文数据  
ch = []  
with open('ciphertext.txt', 'r') as file:  
    for line in file:  
        try:  
            line_numbers = line.strip().split()  
            ch.append([float(num) for num in line_numbers])  
        except ValueError:  
            print(f"Ignored non-numeric line: {line}")  
print(len(ch))  
n = len(ch)-1  
  
# 定义加密网络  
class Net(nn.Module):  
    def __init__(self):  
        super(Net, self).__init__()  
        self.linear = nn.Linear(n, n*n)  
        self.conv = nn.Conv2d(1, 1, (2, 2), stride=1, padding=1)  
  
    def forward(self, x):  
        x = self.linear(x)  
        x = x.view(1, 1, n, n)  
        x = self.conv(x)  
        return x  
  
# 加载训练好的模型参数  
mynet=Net()  
mynet.load_state_dict(torch.load('model.pth'))  
conv_weight = mynet.conv.weight.data.tolist()[0][0]  
print(conv_weight)  
conv_bias = mynet.conv.bias.data.tolist()  
print(conv_bias)  
linear_weight = mynet.linear.weight.data.tolist()  
print(linear_weight[0])  
linear_bias = mynet.linear.bias.data.tolist()  
print(len(linear_bias))  
  
# 解密  
'''  
初始化 flag 数组,用于存储解密后的数据  
遍历 ch 中的每个元素,通过逆向操作计算出原始数据。具体操作包括减去卷积层的偏置和加权值,然后除以卷积核的权重。  
  
逆卷积操作  
对于卷积层,卷积核的大小为 2x2,并且在正向操作中,卷积公式为:  
output[i][j]=conv_weight[0][0]×input[i][j]+conv_weight[0][1]×input[i][j+1]+conv_weight[1][0]×input[i+1][j]+conv_weight[1][1]×input[i+1][j+1]+conv_bias  
  
将 flag 转换为适当的形状,并减去全连接层的偏置。  
使用全连接层权重的伪逆矩阵对 flag 进行矩阵运算,得到解密后的数据。  
将解密后的数据转换为字符并打印出来,形成解密后的文本。  
'''  
flag = [[0]*n for _ in range(n)]  
for i in range(n):  
    for j in range(n):  
        x = 0  
        y = 0  
        z = 0  
        if i>0:  
            y = flag[i-1][j]  
            if j>0:  
                x = flag[i-1][j-1]  
        if j>0:  
            z = flag[i][j-1]  
        # 减去卷积层的偏置 conv_bias[0] 和邻近元素的加权和,再除以卷积核 conv_weight[1][1]。  
        flag[i][j]=ch[i][j]-conv_bias[0]-(conv_weight[0][0]*x+conv_weight[0][1]*y+conv_weight[1][0]*z)  
        flag[i][j]/=conv_weight[1][1]  
  
# 转换和偏置调整  
'''  
将 flag 转换为一维数组。  
减去全连接层的偏置 linear_bias。  
将 flag 重新调整为 (n*n, 1) 的形状。  
'''  
flag = np.array(flag).reshape(n*n)  
flag = flag-linear_bias  
flag = flag.reshape(n*n,1)  
print(flag.shape)  
print(np.array(linear_weight).shape)  
print(np.linalg.pinv(linear_weight).shape)  
# 使用全连接层权重 linear_weight 的伪逆矩阵对 flag 进行矩阵运算,得到解密后的数据。  
flag = np.linalg.pinv(linear_weight).dot(flag)  
for i in flag:  
    print(chr(round(i[0])),end='')

得到flag:

flag{Mi_muhe_mosi!Mi_muhe_mita,mita_movo_lata!}
上次编辑于:
贡献者: L-mj0