今年逆向题目比较多,还挺顺手的,其他题目还算不难,除了babyAnti这题就AK逆向了。这题用的flutter库,研究了好久也完全找不到思路,只好放弃。后来才知道根据题目的名字,预期解就是去掉反作弊的检查,用作弊方法完成的。
RE:confuse_re
代码中有大量的call $+5混淆,ida的F5不好使了,但是还是可以看汇编进入真正的函数,所以没有什么区别。
主函数:
很多字符串都采用异或进行加密
前面是简单的红橙蓝的输入判断:
输入bor进入密码环节,下面是核心判断代码:
密码被分成前16字节和后16字节两部分,第一部分先加密,然后第二部分在和加密结果进行异或并加1:
查看密钥生成和加密的部分,判断为AES加密
但是在AddroundKey函数中又用了0x23进行异或,因此采用脚本进行解密,exp如下:
import re
import binascii
class Aes:
sbox = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
s_box = {}
ns_box = { }
Rcon = {
1: ['0x01', '0x00', '0x00', '0x00'],
2: ['0x02', '0x00', '0x00', '0x00'],
3: ['0x04', '0x00', '0x00', '0x00'],
4: ['0x08', '0x00', '0x00', '0x00'],
5: ['0x10', '0x00', '0x00', '0x00'],
6: ['0x20', '0x00', '0x00', '0x00'],
7: ['0x40', '0x00', '0x00', '0x00'],
8: ['0x80', '0x00', '0x00', '0x00'],
9: ['0x1B', '0x00', '0x00', '0x00'],
10: ['0x36', '0x00', '0x00', '0x00']
}
Matrix = [
['0x02', '0x03', '0x01', '0x01'],
['0x01', '0x02', '0x03', '0x01'],
['0x01', '0x01', '0x02', '0x03'],
['0x03', '0x01', '0x01', '0x02']
]
ReMatrix = [
['0x0e', '0x0b', '0x0d', '0x09'],
['0x09', '0x0e', '0x0b', '0x0d'],
['0x0d', '0x09', '0x0e', '0x0b'],
['0x0b', '0x0d', '0x09', '0x0e']
]
plaintext = [[], [], [], []]
plaintext1 = [[], [], [], []]
subkey = [[], [], [], []]
def __init__(self, key):
self.s_box = dict(zip(["0x%02x"%i for i in range(256)], ["0x%02x"%i for i in self.sbox]))
self.ns_box = dict(zip(self.s_box.values(), self.s_box.keys()))
for i in range(4):
for j in range(0, 8, 2):
self.subkey[i].append("0x" + key[i * 8 + j:i * 8 + j + 2])
# print(self.subkey)
for i in range(4, 44):
if i % 4 != 0:
tmp = xor_32(self.subkey[i - 1], self.subkey[i - 4],0)
self.subkey.append(tmp)
else: # 4的倍数的时候执行
tmp1 = self.subkey[i - 1][1:]
tmp1.append(self.subkey[i - 1][0])
# print(tmp1)
for m in range(4):
tmp1[m] = self.s_box[tmp1[m]]
# tmp1 = self.s_box['cf']
tmp1 = xor_32(tmp1, self.Rcon[i / 4], 0)
self.subkey.append(xor_32(tmp1, self.subkey[i - 4],0))
# print(self.subkey)
def AddRoundKey(self, round):
for i in range(4):
self.plaintext[i] = xor_32(self.plaintext[i], self.subkey[round * 4 + i],0x23)
# print('AddRoundKey',self.plaintext)
def PlainSubBytes(self):
for i in range(4):
for j in range(4):
self.plaintext[i][j] = self.s_box[self.plaintext[i][j]]
# print('PlainSubBytes',self.plaintext)
def RePlainSubBytes(self):
for i in range(4):
for j in range(4):
self.plaintext[i][j] = self.ns_box[self.plaintext[i][j]]
def ShiftRows(self):
p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]
self.plaintext[0][1] = p2
self.plaintext[1][1] = p3
self.plaintext[2][1] = p4
self.plaintext[3][1] = p1
p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]
self.plaintext[0][2] = p3
self.plaintext[1][2] = p4
self.plaintext[2][2] = p1
self.plaintext[3][2] = p2
p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]
self.plaintext[0][3] = p4
self.plaintext[1][3] = p1
self.plaintext[2][3] = p2
self.plaintext[3][3] = p3
# print('ShiftRows',self.plaintext)
def ReShiftRows(self):
p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]
self.plaintext[3][1] = p3
self.plaintext[2][1] = p2
self.plaintext[0][1] = p4
self.plaintext[1][1] = p1
p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]
self.plaintext[0][2] = p3
self.plaintext[1][2] = p4
self.plaintext[2][2] = p1
self.plaintext[3][2] = p2
p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]
self.plaintext[0][3] = p2
self.plaintext[1][3] = p3
self.plaintext[2][3] = p4
self.plaintext[3][3] = p1
def MixColumns(self):
for i in range(4):
for j in range(4):
self.plaintext1[i].append(MatrixMulti(self.Matrix[j], self.plaintext[i]))
# print('MixColumns',self.plaintext1)
def ReMixColumns(self):
for i in range(4):
for j in range(4):
self.plaintext1[i].append(MatrixMulti(self.ReMatrix[j], self.plaintext[i]))
def AESEncryption(self, plaintext):
self.plaintext = [[], [], [], []]
for i in range(4):
for j in range(0, 8, 2):
self.plaintext[i].append("0x" + plaintext[i * 8 + j:i * 8 + j + 2])
self.AddRoundKey(0)
for i in range(9):
self.PlainSubBytes()
self.ShiftRows()
self.MixColumns()
self.plaintext = self.plaintext1
self.plaintext1 = [[], [], [], []]
self.AddRoundKey(i + 1)
self.PlainSubBytes()
self.ShiftRows()
self.AddRoundKey(10)
return Matrixtostr(self.plaintext)
def AESDecryption(self, cipher):
self.plaintext = [[], [], [], []]
for i in range(4):
for j in range(0, 8, 2):
self.plaintext[i].append('0x' + cipher[i * 8 + j:i * 8 + j + 2])
# print(self.ns_box)
self.AddRoundKey(10)
for i in range(9):
self.ReShiftRows()
self.RePlainSubBytes()
self.AddRoundKey(9-i)
self.ReMixColumns()
self.plaintext = self.plaintext1
self.plaintext1 = [[], [], [], []]
self.ReShiftRows()
self.RePlainSubBytes()
self.AddRoundKey(0)
return Matrixtostr(self.plaintext)
def Encryption(self, text):
group = PlaintextGroup(TextToByte(text), 32, 1)
# print(group)
cipher = ""
for i in range(len(group)):
cipher = cipher + self.AESEncryption(group[i])
return cipher
def Decryption(self, cipher):
group = PlaintextGroup(cipher, 32, 0)
# print(group)
text = ''
for i in range(len(group)):
text = text + self.AESDecryption(group[i])
text = ByteToText(text)
return text
def xor_32(start, end, key):
a = []
for i in range(0, 4):
xor_tmp = ""
b = hextobin(start[i])
c = hextobin(end[i])
d = bin(key)[2:].rjust(8,'0')
for j in range(8):
tmp = int(b[j], 10) ^ int(c[j], 10) ^ int(d[j],10)
xor_tmp += str(tmp )
a.append(bintohex(xor_tmp))
return a
def xor_8(begin, end):
xor_8_tmp = ""
for i in range(8):
xor_8_tmp += str(int(begin[i]) ^ int(end[i]))
return xor_8_tmp
def hextobin(word):
word = bin(int(word, 16))[2:]
for i in range(0, 8-len(word)):
word = '0'+word
return word
def bintohex(word):
word = hex(int(word, 2))
if len(word) == 4:
return word
elif len(word) < 4:
return word.replace('x', 'x0')
def MatrixMulti(s1, s2):
result = []
s3 = []
for i in range(4):
s3.append(hextobin(s2[i]))
for i in range(4):
result.append(MultiProcess(int(s1[i], 16), s3[i]))
for i in range(3):
result[0] = xor_8(result[0], result[i+1])
return bintohex(result[0])
def MultiProcess(a, b):
if a == 1:
return b
elif a == 2:
if b[0] == '0':
b = b[1:] + '0'
else:
b = b[1:] + '0'
b = xor_8(b, '00011011')
return b
elif a == 3:
tmp_b = b
if b[0] == '0':
b = b[1:] + '0'
else:
b = b[1:] + '0'
b = xor_8(b, '00011011')
return xor_8(b, tmp_b)
elif a == 9:
tmp_b = b
return xor_8(tmp_b, MultiProcess(2, MultiProcess(2, MultiProcess(2, b))))
elif a == 11:
tmp_b = b
return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, b)))
elif a == 13:
tmp_b = b
return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
elif a == 14:
return xor_8(MultiProcess(2, b), xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
def Matrixtostr(matrix):
result = ""
for i in range(4):
for j in range(4):
result += matrix[i][j][2:]
return result
def PlaintextGroup(plaintext, length, flag):
group = re.findall('.{'+str(length)+'}', plaintext)
group.append(plaintext[len(group)*length:])
if group[-1] == '' and flag:
group[-1] = '16161616161616161616161616161616'
elif len(group[-1]) < length and flag:
tmp = int((length-len(group[-1])) / 2)
if tmp < 10:
for i in range(tmp):
group[-1] = group[-1] + '0'+str(tmp)
else:
for i in range(tmp):
group[-1] = group[-1] + str(tmp)
elif not flag:
del group[-1]
return group
def TextToByte(words):
text = words.encode('utf-8').hex()
return text
def ByteToText(encode):
tmp = int(encode[-2:])
word = ''
for i in range(len(encode)-tmp*2):
word = word + encode[i]
# print(word)
word = bytes.decode(binascii.a2b_hex(word))
return word
def xorbytes(bytes1,bytes2):
length=min(len(bytes1),len(bytes2))
output=bytearray()
for i in range(length):
output.append(bytes1[i]^bytes2[i])
return bytes(output)
res='DCDCCC668DF33C15505EEF1646D9D7DF5027447765DCA73968CB7F7B88DD640F'.lower()
key = 'CA9D7FF8A4099004FAD40661E93B775A'.lower()
A1 = Aes(key)
plaintext=A1.AESDecryption(res[:32])
a=bytes.fromhex(plaintext)
b=A1.AESDecryption(res[32:])
b=bytearray(bytes.fromhex(b))
d=bytes.fromhex(res[:32])
for i in range(16):
b[i]-=1
b[i]^=d[i]
print((a+b).decode())
得到flag:
VNCTF{fa9ad36bd2de1586d944cf7b2935dd91}
RE:PZGalaxy
查看网页js源码,判断是RC4加密,写出计算日期的EXP:
password=bytes.fromhex('a6703adc92c397f31adf8d6412035907b6d4f7735f1d3a494c4358d1b94f998533e0697c')
from Crypto.Cipher import ARC4
for i in range(1,13):
for j in range(1,32):
arc4 = ARC4.new(('2023%02d%02d'%(i,j)).encode())
if b'flag' in arc4.decrypt(password):
print('2023%02d%02d'%(i,j))
得到日期:20230127
然后到web上提交得到flag
flag{HitYourSoulAndSeeYouInTheGalaxy}
RE:jijiji
资源里有个shell,会自动启动一个进程,并终止父进程
将shell的资源解密后保存成dump.exe,并可以以如下命令行方式运行:
dump.exe jijiji.exe 16000
核心代码如下:
就是一个魔改的XTEA加密
exp:
import struct
def decrypt(rounds, v, k):
v0 = v[0]
v1 = v[1]
delta = 0x88408067
x = delta * rounds
for i in range(rounds):
x -= delta
x = x & 0xFFFFFFFF
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (x + k[(x >> 11) & 3])
v1 = v1 & 0xFFFFFFFF
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (x + k[x & 3]) ^ x
v0 = v0 & 0xFFFFFFFF
return [v0,v1]
key = [98, 111, 109, 98]
rounds = 33
res=bytes.fromhex('78F7D4AD32F1D7A690328161A6404A2D115FB0002494D5B6C6BF1B23315B40CD')
#test=b'0123456789abcdef0123456789abcdef'
for i in range(len(res)//8):
data=res[i*8:i*8+8]
value=struct.unpack('<2I',data)
decrypted = decrypt(rounds, value, key)
print(struct.pack('<2I',*decrypted).decode(),end='')
得到flag:
2d326e43eb8fea8837737fc0f50f83f2
WEB:象棋王子
签到题
复制出脚本,直接在控制台运行就好了
flag{w3lc0m3_t0_VNCTF_2023—}
MISC:snake on web
咋看是一个web,但是是wasm的代码,直接逆向分析得到核心逻辑
调试的时候记录数据,然后用脚本恢复flag:
b=b'sfaceratrebumverodolorindolortakimataverou'
a=bytes.fromhex('84fdffff7b02000075020000790200006b020000bbfdffff79020000b7fdffffa0fdffff75020000c0fdffffb7fdffffbcfdffffc8fdffffa7fdffffbafdffffc2fdffffa4fdffffd3fdffffbdfdffff8efdffff85fdffffc2fdffffd0fdffff96fdffffbdfdffffc1fdffffc2fdffffccfdffffd1fdffffa7fdffffc3fdffff8dfdffffbefdffffabfdffffa3fdffff74020000d3fdffffc1fdffffbbfdffffbbfdffff7d02000075020000')
for i in range(len(a)//4-1):
data=a[i*4:i*4+4]
print(chr(((0x72^((data[0]^2)-5))+b[i])&0xff),end='')
得到:
flag{8e6ae178-7387-4db2-a788-039a27bd4185}
RE:dll_puzzle
按照题目提示进行调试执行
代码没有符号,需要调试才能看出如MessageBox这种系统函数,大量符号和变量也都在运行时会修改,比如SM4加密用到的Sbox和FK、Key等
注意代码的反调试功能,需要跳过,然后得到正确的解密参数后即可写出脚本(最终的解密居然就是没有魔改的SM4),后面判断结果时采用80个变量的方程组来进行,用Z3求解搞定,最终exp:
from sm4 import SM4Key
from z3 import *
s = Solver()
flag = [BitVec('flag%d' % i, 16) for i in range(80)]
for i in range(len(flag)):
s.add(And(flag[i]>=0x0,flag[i]<=0xff))
s.add(5 * (flag[1]) + 8 * (flag[0]) == 2669 )
s.add(6 * (flag[1]) + 4 * (flag[2]) == 1402 )
s.add(3 * (flag[3]) + 6 * (flag[2]) == 873 )
s.add(7 * (flag[4]) + 6 * (flag[3]) == 2627 )
s.add(8 * (flag[5]) + 4 * (flag[4]) == 2516 )
s.add(9 * (flag[6]) + 5 * (flag[5]) == 2781 )
s.add(3 * (flag[6]) + 4 * (flag[7]) == 1228 )
s.add(5 * (flag[8]) + 9 * (flag[7]) == 1821 )
s.add(7 * (flag[9]) + 5 * (flag[8]) == 554 )
s.add(6 * (flag[10]) + 9 * (flag[9]) == 825 )
s.add(5 * (flag[11]) + 6 * (flag[10]) == 1857 )
s.add(3 * (flag[11]) + 4 * (flag[12]) == 1627 )
s.add(7 * (flag[13]) + 5 * (flag[12]) == 2279 )
s.add(3 * (flag[14]) + 9 * (flag[13]) == 1974 )
s.add(6 * (flag[15]) + 6 * (flag[14]) == 2382 )
s.add(7 * (flag[15]) + 8 * (flag[16]) == 1903 )
s.add(8 * (flag[17]) + 8 * (flag[16]) == 1336 )
s.add(3 * (flag[18]) + 6 * (flag[17]) == 822 )
s.add(5 * (flag[19]) + 8 * (flag[18]) == 381 )
s.add(3 * (flag[20]) + 5 * (flag[19]) == 823 )
s.add(5 * (flag[21]) + 5 * (flag[20]) == 1680 )
s.add(6 * (flag[21]) + 8 * (flag[22]) == 2116 )
s.add(9 * (flag[23]) + 3 * (flag[22]) == 1059 )
s.add(3 * (flag[23]) + 8 * (flag[24]) == 1314 )
s.add(3 * (flag[25]) + 9 * (flag[24]) == 1641 )
s.add(5 * (flag[25]) + 8 * (flag[26]) == 2148 )
s.add(3 * (flag[27]) + 3 * (flag[26]) == 669 )
s.add(5 * (flag[28]) + 9 * (flag[27]) == 953 )
s.add(5 * (flag[29]) + 7 * (flag[28]) == 1896 )
s.add(3 * (flag[30]) + 3 * (flag[29]) == 1275 )
s.add(5 * (flag[31]) + 7 * (flag[30]) == 2874 )
s.add(9 * (flag[32]) + 6 * (flag[31]) == 1518 )
s.add(7 * (flag[33]) + 5 * (flag[32]) == 1312 )
s.add(6 * (flag[34]) + 5 * (flag[33]) == 2148 )
s.add(9 * (flag[34]) + 8 * (flag[35]) == 2979 )
s.add(3 * (flag[35]) + 4 * (flag[36]) == 476 )
s.add(6 * (flag[37]) + 3 * (flag[36]) == 1047 )
s.add(7 * (flag[38]) + 4 * (flag[37]) == 1488 )
s.add(6 * (flag[39]) + 6 * (flag[38]) == 1320 )
s.add(5 * (flag[40]) + 6 * (flag[39]) == 1784 )
s.add(3 * (flag[41]) + 8 * (flag[40]) == 1994 )
s.add(7 * (flag[42]) + 3 * (flag[41]) == 712 )
s.add(3 * (flag[43]) + 3 * (flag[42]) == 1002 )
s.add(5 * (flag[44]) + 7 * (flag[43]) == 2094 )
s.add(3 * (flag[45]) + 3 * (flag[44]) == 465 )
s.add(5 * (flag[46]) + 6 * (flag[45]) == 1479 )
s.add(3 * (flag[47]) + 6 * (flag[46]) == 1281 )
s.add(7 * (flag[48]) + 4 * (flag[47]) == 1064 )
s.add(3 * (flag[49]) + 4 * (flag[48]) == 985 )
s.add(3 * (flag[50]) + 4 * (flag[49]) == 922 )
s.add(7 * (flag[51]) + 8 * (flag[50]) == 1672 )
s.add(9 * (flag[51]) + 4 * (flag[52]) == 1740 )
s.add(6 * (flag[53]) + 7 * (flag[52]) == 1185 )
s.add(6 * (flag[54]) + 9 * (flag[53]) == 711 )
s.add(4 * (flag[55]) + 4 * (flag[54]) == 256 )
s.add(7 * (flag[56]) + 8 * (flag[55]) == 744 )
s.add(5 * (flag[57]) + 8 * (flag[56]) == 1674 )
s.add(6 * (flag[58]) + 3 * (flag[57]) == 834 )
s.add(3 * (flag[59]) + 4 * (flag[58]) == 348 )
s.add(9 * (flag[59]) + 4 * (flag[60]) == 952 )
s.add(3 * (flag[60]) + 4 * (flag[61]) == 1117 )
s.add(7 * (flag[62]) + 9 * (flag[61]) == 1853 )
s.add(6 * (flag[63]) + 9 * (flag[62]) == 399 )
s.add(3 * (flag[64]) + 6 * (flag[63]) == 1011 )
s.add(6 * (flag[65]) + 9 * (flag[64]) == 3171 )
s.add(8 * (flag[66]) + 8 * (flag[65]) == 1760 )
s.add(7 * (flag[67]) + 7 * (flag[66]) == 861 )
s.add(6 * (flag[68]) + 6 * (flag[67]) == 1710 )
s.add(7 * (flag[68]) + 8 * (flag[69]) == 1578 )
s.add(7 * (flag[70]) + 9 * (flag[69]) == 1280 )
s.add(3 * (flag[71]) + 6 * (flag[70]) == 1134 )
s.add(3 * (flag[72]) + 8 * (flag[71]) == 1003 )
s.add(9 * (flag[72]) + 8 * (flag[73]) == 1345 )
s.add(5 * (flag[74]) + 4 * (flag[73]) == 928 )
s.add(3 * (flag[74]) + 4 * (flag[75]) == 824 )
s.add(6 * (flag[76]) + 8 * (flag[75]) == 1840 )
s.add(9 * (flag[77]) + 7 * (flag[76]) == 1200 )
s.add(3 * (flag[77]) + 8 * (flag[78]) == 2032 )
s.add(5 * (flag[79]) + 5 * (flag[78]) == 1795 )
s.add(7 * (flag[79]) + 8 * (flag[0]) == 2584 )
if s.check() != sat:
print ("error!")
count=0
while s.check() == sat:
m = s.model()
count+=1
data=[m[flag[i]].as_long() for i in range(80)]
for j in range(256):
key_data = list(bytes.fromhex('206232332E74762F7946524337685900'))
for k in range(len(key_data)):
key_data[k]^=(j^0x2a)
flag=b''
sm4 = SM4Key(bytes(key_data))
flag = sm4.decrypt(bytes(data))
if checkflag(flag[:10]):
print(j,bytes.fromhex(flag.strip(b'\x00').decode()))
break
得到TheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything值和flag:
42 flag{3f27d7470d8967fd344ec7f1261e64b3}
填入license.ini验证通过:
这题其实在SM4解密的地方卡了好久,后来跟出题人沟通了下,才发现我用的SM4源码有问题,因为参数都是默认的,直接用Cyberchef也能解出来~