霍雅
tgctf reverse逆向前四题复现
比赛的时候只做出前三题
然后crypto剩下两题没做,都是板子就不写了
base64
打开主函数
分析发现有base64的特征
分析函数,其实只有一个加密函数
点进加密函数,可以看到base64的表
但是这个base64没有等于号
应该是有魔改
直接让ai嗦
# 魔改Base64解码脚本
CUSTOM_TABLE = "GLp/+Wn7uqX8FQ2JDR1c0M6U53sjBwyxglmrCVdSThAfEOvPHaYZNzo4ktK9iebI"
# 构建逆向字符表(字符 -> 索引)
reverse_table = {char: idx for idx, char in enumerate(CUSTOM_TABLE)}
def modified_base64_decode(s: str) -> bytes:
# 移除补位符`=`,并记录补位数量
stripped = s.rstrip('=')
pad_count = len(s) - len(stripped)
# 将字符转换为原始6位值(考虑偏移24)
decoded = []
for char in stripped:
if char not in reverse_table:
raise ValueError(f"Invalid character: {char}")
original_idx = (reverse_table[char] - 24) % 64 # 逆向偏移计算
decoded.append(original_idx)
# 合并6位组为字节流
byte_stream = []
for i in range(0, len(decoded), 4):
chunk = decoded[i:i + 4]
if len(chunk) < 4:
chunk += [0] * (4 - len(chunk)) # 填充缺失的块
# 将4个6位值合并为3字节
byte1 = (chunk[0] << 2) | (chunk[1] >> 4)
byte2 = ((chunk[1] & 0x0F) << 4) | (chunk[2] >> 2)
byte3 = ((chunk[2] & 0x03) << 6) | chunk[3]
byte_stream.extend([byte1, byte2, byte3])
# 根据补位数量移除末尾无效字节
if pad_count:
byte_stream = byte_stream[:-pad_count]
return bytes(byte_stream)
# 测试用例
if __name__ == "__main__":
# 示例编码数据(假设原始数据为"Hello")
encoded_str = "AwLdOEVEhIWtajB2CbCWCbTRVsFFC8hirfiXC9gWH9HQayCJVbB8CIF=" # 需替换为实际编码结果
decoded_data = modified_base64_decode(encoded_str)
print(f"Decoded: {decoded_data.decode('utf-8', errors='replace')}")
水果忍者
标题考察的是对Unity的基础知识
一般而言都是打开Fruit Ninja_Data\Managed\Assembly-CSharp.dll
直接把他拖进去dnspy
找到start函数,一般这个是入口,和main类似
查看函数可以发现调用了NewGame()这个函数
根进去看看
往下翻一翻,就能看到KEY ENC和IV
一般这种特征都是分组加密的CBC模式,而rsa中题目一般是AES
直接试,就出来了
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import binascii
# 输入数据
encrypted_hex = "cecadff28e93aa5d6f65128ae33e734d3f47b4b8a050d326c534a732d51b96e2a6a80dca0d5a704a216c2e0c3cc6aaaf"
encryption_key = "HZNUHZNUHZNUHZNU"
iv = "0202005503081501"
try:
# 将十六进制字符串转换为字节
encrypted_data = bytes.fromhex(encrypted_hex)
# 转换密钥和IV为字节(UTF-8编码)
key = encryption_key.encode('utf-8')
iv_bytes = iv.encode('utf-8')
# 创建AES-CBC解密器
cipher = AES.new(key, AES.MODE_CBC, iv=iv_bytes)
# 解密并去除PKCS#7填充
decrypted_data = cipher.decrypt(encrypted_data)
decrypted_data = unpad(decrypted_data, AES.block_size)
# 输出明文(假设是UTF-8可打印字符串)
print("Decrypted Text:", decrypted_data.decode('utf-8'))
except (ValueError, binascii.Error) as e:
print(f"Error: {e}")
print("Possible reasons: invalid hex, key/IV mismatch, or padding error.")
蛇年的本命语言
使用pyinstxtractor.py对output.exe进行解包
然后用在线网站反编译output.pyc
可以看到代码很丑,这种代码基本上是发分析不了的
所以我们要把变量名弄好看一些
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8
from collections import Counter
print('Welcome to HZNUCTF!!!')
print('Plz input the flag:')
input = input()
Counter_input = Counter(input)
count_str = ''.join((str(Counter_input[char]) for char in input))
print('ans1: ', end='')
print(count_str )
if count_str != '111111116257645365477364777645752361':
print('wrong_wrong!!!')
exit(1)
encoded = ''
for char in input:
if Counter_input[char] > 0:
encoded += char + str(Counter_input[char ])
Counter_input[char ] = 0
ascii_values = [ord(c) for c in encoded_str]
conditions = [
7 * ascii_values[0] == 504,
9 * ascii_values[0] - 5 * ascii_values[1] == 403,
(2 * ascii_values[0] - 5 * ascii_values[1]) + 10 * ascii_values[2] == 799,
3 * ascii_values[0] + 8 * ascii_values[1] + 15 * ascii_values[2] + 20 * ascii_values[3] == 2938,
(5 * ascii_values[0] + 15 * ascii_values[1] + 20 * ascii_values[2] - 19 * ascii_values[3]) + 1 * ascii_values[4] == 2042,
(7 * ascii_values[0] + 1 * ascii_values[1] + 9 * ascii_values[2] - 11 * ascii_values[3]) + 2 * ascii_values[4] + 5 * ascii_values[5] == 1225,
11 * ascii_values[0] + 22 * ascii_values[1] + 33 * ascii_values[2] + 44 * ascii_values[3] + 55 * ascii_values[4] + 66 * ascii_values[5] - 77 * ascii_values[6] == 7975,
((21 * ascii_values[0] + 23 * ascii_values[1] + 3 * ascii_values[2] + 24 * ascii_values[3] - 55 * ascii_values[4]) + 6 * ascii_values[5] - 7 * ascii_values[6]) + 15 * ascii_values[7] == 229,
(2 * ascii_values[0] + 26 * ascii_values[1] + 13 * ascii_values[2] + 0 * ascii_values[3] - 65 * ascii_values[4]) + 15 * ascii_values[5] + 29 * ascii_values[6] + 1 * ascii_values[7] + 20 * ascii_values[8] == 2107,
(10 * ascii_values[0] + 7 * ascii_values[1] + -9 * ascii_values[2] + 6 * ascii_values[3] + 7 * ascii_values[4] + 1 * ascii_values[5] + 22 * ascii_values[6] + 21 * ascii_values[7] - 22 * ascii_values[8]) + 30 * ascii_values[9] == 4037,
(15 * ascii_values[0] + 59 * ascii_values[1] + 56 * ascii_values[2] + 66 * ascii_values[3] + 7 * ascii_values[4] + 1 * ascii_values[5] - 122 * ascii_values[6]) + 21 * ascii_values[7] + 32 * ascii_values[8] + 3 * ascii_values[9] - 10 * ascii_values[10] == 4950,
(((13 * ascii_values[0] + 66 * ascii_values[1] + 29 * ascii_values[2] + 39 * ascii_values[3] - 33 * ascii_values[4]) + 13 * ascii_values[5] - 2 * ascii_values[6]) + 42 * ascii_values[7] + 62 * ascii_values[8] + 1 * ascii_values[9] - 10 * ascii_values[10]) + 11 * ascii_values[11] == 12544,
(((23 * ascii_values[0] + 6 * ascii_values[1] + 29 * ascii_values[2] + 3 * ascii_values[3] - 3 * ascii_values[4]) + 63 * ascii_values[5] - 25 * ascii_values[6]) + 2 * ascii_values[7] + 32 * ascii_values[8] + 1 * ascii_values[9] - 10 * ascii_values[10]) + 11 * ascii_values[11] - 12 * ascii_values[12] == 6585,
((((223 * ascii_values[0] + 6 * ascii_values[1] - 29 * ascii_values[2] - 53 * ascii_values[3] - 3 * ascii_values[4]) + 3 * ascii_values[5] - 65 * ascii_values[6]) + 0 * ascii_values[7] + 36 * ascii_values[8] + 1 * ascii_values[9] - 15 * ascii_values[10]) + 16 * ascii_values[11] - 18 * ascii_values[12]) + 13 * ascii_values[13] == 6893,
((((29 * ascii_values[0] + 13 * ascii_values[1] - 9 * ascii_values[2] - 93 * ascii_values[3]) + 33 * ascii_values[4] + 6 * ascii_values[5] + 65 * ascii_values[6] + 1 * ascii_values[7] - 36 * ascii_values[8]) + 0 * ascii_values[9] - 16 * ascii_values[10]) + 96 * ascii_values[11] - 68 * ascii_values[12]) + 33 * ascii_values[13] - 14 * ascii_values[14] == 1883,
(((69 * ascii_values[0] + 77 * ascii_values[1] - 93 * ascii_values[2] - 12 * ascii_values[3]) + 0 * ascii_values[4] + 0 * ascii_values[5] + 1 * ascii_values[6] + 16 * ascii_values[7] + 36 * ascii_values[8] + 6 * ascii_values[9] + 19 * ascii_values[10] + 66 * ascii_values[11] - 8 * ascii_values[12]) + 38 * ascii_values[13] - 16 * ascii_values[14]) + 15 * ascii_values[15] == 8257,
((((23 * ascii_values[0] + 2 * ascii_values[1] - 3 * ascii_values[2] - 11 * ascii_values[3]) + 12 * ascii_values[4] + 24 * ascii_values[5] + 1 * ascii_values[6] + 6 * ascii_values[7] + 14 * ascii_values[8] - 0 * ascii_values[9]) + 1 * ascii_values[10] + 68 * ascii_values[11] - 18 * ascii_values[12]) + 68 * ascii_values[13] - 26 * ascii_values[14]) + 15 * ascii_values[15] - 16 * ascii_values[16] == 5847,
(((((24 * ascii_values[0] + 0 * ascii_values[1] - 1 * ascii_values[2] - 15 * ascii_values[3]) + 13 * ascii_values[4] + 4 * ascii_values[5] + 16 * ascii_values[6] + 67 * ascii_values[7] + 146 * ascii_values[8] - 50 * ascii_values[9]) + 16 * ascii_values[10] + 6 * ascii_values[11] - 1 * ascii_values[12]) + 69 * ascii_values[13] - 27 * ascii_values[14]) + 45 * ascii_values[15] - 6 * ascii_values[16]) + 17 * ascii_values[17] == 18257,
((((25 * ascii_values[0] + 26 * ascii_values[1] - 89 * ascii_values[2]) + 16 * ascii_values[3] + 19 * ascii_values[4] + 44 * ascii_values[5] + 36 * ascii_values[6] + 66 * ascii_values[7] - 150 * ascii_values[8] - 250 * ascii_values[9]) + 166 * ascii_values[10] + 126 * ascii_values[11] - 11 * ascii_values[12]) + 690 * ascii_values[13] - 207 * ascii_values[14]) + 46 * ascii_values[15] + 6 * ascii_values[16] + 7 * ascii_values[17] - 18 * ascii_values[18] == 12591,
(((((5 * ascii_values[0] + 26 * ascii_values[1] + 8 * ascii_values[2] + 160 * ascii_values[3] + 9 * ascii_values[4] - 4 * ascii_values[5]) + 36 * ascii_values[6] + 6 * ascii_values[7] - 15 * ascii_values[8] - 20 * ascii_values[9]) + 66 * ascii_values[10] + 16 * ascii_values[11] - 1 * ascii_values[12]) + 690 * ascii_values[13] - 20 * ascii_values[14]) + 46 * ascii_values[15] + 6 * ascii_values[16] + 7 * ascii_values[17] - 18 * ascii_values[18]) + 19 * ascii_values[19] == 52041,
((((((29 * ascii_values[0] - 26 * ascii_values[1]) + 0 * ascii_values[2] + 60 * ascii_values[3] + 90 * ascii_values[4] - 4 * ascii_values[5]) + 6 * ascii_values[6] + 6 * ascii_values[7] - 16 * ascii_values[8] - 21 * ascii_values[9]) + 69 * ascii_values[10] + 6 * ascii_values[11] - 12 * ascii_values[12]) + 69 * ascii_values[13] - 20 * ascii_values[14] - 46 * ascii_values[15]) + 65 * ascii_values[16] + 0 * ascii_values[17] - 1 * ascii_values[18]) + 39 * ascii_values[19] - 20 * ascii_values[20] == 20253,
(((((((45 * ascii_values[0] - 56 * ascii_values[1]) + 10 * ascii_values[2] + 650 * ascii_values[3] - 900 * ascii_values[4]) + 44 * ascii_values[5] + 66 * ascii_values[6] - 6 * ascii_values[7] - 6 * ascii_values[8] - 21 * ascii_values[9]) + 9 * ascii_values[10] - 6 * ascii_values[11] - 12 * ascii_values[12]) + 69 * ascii_values[13] - 2 * ascii_values[14] - 406 * ascii_values[15]) + 651 * ascii_values[16] + 2 * ascii_values[17] - 10 * ascii_values[18]) + 69 * ascii_values[19] - 0 * ascii_values[20]) + 21 * ascii_values[21] == 18768,
(((((555 * ascii_values[0] - 6666 * ascii_values[1]) + 70 * ascii_values[2] + 510 * ascii_values[3] - 90 * ascii_values[4]) + 499 * ascii_values[5] + 66 * ascii_values[6] - 66 * ascii_values[7] - 610 * ascii_values[8] - 221 * ascii_values[9]) + 9 * ascii_values[10] - 23 * ascii_values[11] - 102 * ascii_values[12]) + 6 * ascii_values[13] + 2050 * ascii_values[14] - 406 * ascii_values[15]) + 665 * ascii_values[16] + 333 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 777 * ascii_values[20] + 201 * ascii_values[21] - 22 * ascii_values[22] == 111844,
(((((((1 * ascii_values[0] - 22 * ascii_values[1]) + 333 * ascii_values[2] + 4444 * ascii_values[3] - 5555 * ascii_values[4]) + 6666 * ascii_values[5] - 666 * ascii_values[6]) + 676 * ascii_values[7] - 660 * ascii_values[8] - 22 * ascii_values[9]) + 9 * ascii_values[10] - 73 * ascii_values[11] - 107 * ascii_values[12]) + 6 * ascii_values[13] + 250 * ascii_values[14] - 6 * ascii_values[15]) + 65 * ascii_values[16] + 39 * ascii_values[17] + 10 * ascii_values[18] + 69 * ascii_values[19] + 777 * ascii_values[20] + 201 * ascii_values[21] - 2 * ascii_values[22]) + 23 * ascii_values[23] == 159029,
(((520 * ascii_values[0] - 222 * ascii_values[1]) + 333 * ascii_values[2] + 4 * ascii_values[3] - 56655 * ascii_values[4]) + 6666 * ascii_values[5] + 666 * ascii_values[6] + 66 * ascii_values[7] - 60 * ascii_values[8] - 220 * ascii_values[9]) + 99 * ascii_values[10] + 73 * ascii_values[11] + 1007 * ascii_values[12] + 7777 * ascii_values[13] + 2500 * ascii_values[14] + 6666 * ascii_values[15] + 605 * ascii_values[16] + 390 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 99999 * ascii_values[20] + 210 * ascii_values[21] + 232 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24] == 2762025,
((((1323 * ascii_values[0] - 22 * ascii_values[1]) + 333 * ascii_values[2] + 4 * ascii_values[3] - 55 * ascii_values[4]) + 666 * ascii_values[5] + 666 * ascii_values[6] + 66 * ascii_values[7] - 660 * ascii_values[8] - 220 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 100 * ascii_values[12] + 777 * ascii_values[13] + 2500 * ascii_values[14] + 6666 * ascii_values[15] + 605 * ascii_values[16] + 390 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 9999 * ascii_values[20] + 210 * ascii_values[21] + 232 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24]) + 25 * ascii_values[25] == 1551621,
(((((777 * ascii_values[0] - 22 * ascii_values[1]) + 6969 * ascii_values[2] + 4 * ascii_values[3] - 55 * ascii_values[4]) + 666 * ascii_values[5] - 6 * ascii_values[6]) + 96 * ascii_values[7] - 60 * ascii_values[8] - 220 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 100 * ascii_values[12] + 777 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + 65 * ascii_values[16] + 90 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 999 * ascii_values[20] + 21 * ascii_values[21] + 232 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24]) + 25 * ascii_values[25] - 26 * ascii_values[26] == 948348,
((((((97 * ascii_values[0] - 22 * ascii_values[1]) + 6969 * ascii_values[2] + 4 * ascii_values[3] - 56 * ascii_values[4]) + 96 * ascii_values[5] - 6 * ascii_values[6]) + 96 * ascii_values[7] - 60 * ascii_values[8] - 20 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 10 * ascii_values[12] + 707 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + -9 * ascii_values[16] + 90 * ascii_values[17] + -2 * ascii_values[18] + 609 * ascii_values[19] + 0 * ascii_values[20] + 21 * ascii_values[21] + 2 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24]) + 25 * ascii_values[25] - 26 * ascii_values[26]) + 27 * ascii_values[27] == 777044,
(((((177 * ascii_values[0] - 22 * ascii_values[1]) + 699 * ascii_values[2] + 64 * ascii_values[3] - 56 * ascii_values[4] - 96 * ascii_values[5] - 66 * ascii_values[6]) + 96 * ascii_values[7] - 60 * ascii_values[8] - 20 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 10 * ascii_values[12] + 707 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + -9 * ascii_values[16] + 0 * ascii_values[17] + -2 * ascii_values[18] + 69 * ascii_values[19] + 0 * ascii_values[20] + 21 * ascii_values[21] + 222 * ascii_values[22] + 23 * ascii_values[23] - 224 * ascii_values[24]) + 25 * ascii_values[25] - 26 * ascii_values[26]) + 27 * ascii_values[27] - 28 * ascii_values[28] == 185016,
((((((77 * ascii_values[0] - 2 * ascii_values[1]) + 6 * ascii_values[2] + 6 * ascii_values[3] - 96 * ascii_values[4] - 9 * ascii_values[5] - 6 * ascii_values[6]) + 96 * ascii_values[7] - 0 * ascii_values[8] - 20 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 10 * ascii_values[12] + 707 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + -9 * ascii_values[16] + 0 * ascii_values[17] + -2 * ascii_values[18] + 9 * ascii_values[19] + 0 * ascii_values[20] + 21 * ascii_values[21] + 222 * ascii_values[22] + 23 * ascii_values[23] - 224 * ascii_values[24]) + 26 * ascii_values[25] - -58 * ascii_values[26]) + 27 * ascii_values[27] - 2 * ascii_values[28]) + 29 * ascii_values[29] == 130106]
if all(ii1iIi1i11i):
print('Congratulation!!!')
else:
print('wrong_wrong!!!')
分析代码可以发现,前一部分是统计每个字母字母出现的次数,计算得到一组数等于111111116257645365477364777645752361
后一段代码是一组方程
方程直接用z3求解
得到H1Z1N1U1C1T1F1{1a6d275f7-463}1
交flag发现不是
但是flag头已经出来了,猜测这可能是前一段代码的约数条件
让ai分析一下,得到完整exp
from z3 import *
from collections import Counter
# 初始化求解器和ASCII值变量数组(共30个变量)
solver = Solver()
ascii_values = [Int(f'a{i}') for i in range(30)]
# 添加所有方程约束
conditions = [
7 * ascii_values[0] == 504,
9 * ascii_values[0] - 5 * ascii_values[1] == 403,
(2 * ascii_values[0] - 5 * ascii_values[1]) + 10 * ascii_values[2] == 799,
3 * ascii_values[0] + 8 * ascii_values[1] + 15 * ascii_values[2] + 20 * ascii_values[3] == 2938,
(5 * ascii_values[0] + 15 * ascii_values[1] + 20 * ascii_values[2] - 19 * ascii_values[3]) + 1 * ascii_values[4] == 2042,
(7 * ascii_values[0] + 1 * ascii_values[1] + 9 * ascii_values[2] - 11 * ascii_values[3]) + 2 * ascii_values[4] + 5 * ascii_values[5] == 1225,
11 * ascii_values[0] + 22 * ascii_values[1] + 33 * ascii_values[2] + 44 * ascii_values[3] + 55 * ascii_values[4] + 66 * ascii_values[5] - 77 * ascii_values[6] == 7975,
((21 * ascii_values[0] + 23 * ascii_values[1] + 3 * ascii_values[2] + 24 * ascii_values[3] - 55 * ascii_values[4]) + 6 * ascii_values[5] - 7 * ascii_values[6]) + 15 * ascii_values[7] == 229,
(2 * ascii_values[0] + 26 * ascii_values[1] + 13 * ascii_values[2] + 0 * ascii_values[3] - 65 * ascii_values[4]) + 15 * ascii_values[5] + 29 * ascii_values[6] + 1 * ascii_values[7] + 20 * ascii_values[8] == 2107,
(10 * ascii_values[0] + 7 * ascii_values[1] + -9 * ascii_values[2] + 6 * ascii_values[3] + 7 * ascii_values[4] + 1 * ascii_values[5] + 22 * ascii_values[6] + 21 * ascii_values[7] - 22 * ascii_values[8]) + 30 * ascii_values[9] == 4037,
(15 * ascii_values[0] + 59 * ascii_values[1] + 56 * ascii_values[2] + 66 * ascii_values[3] + 7 * ascii_values[4] + 1 * ascii_values[5] - 122 * ascii_values[6]) + 21 * ascii_values[7] + 32 * ascii_values[8] + 3 * ascii_values[9] - 10 * ascii_values[10] == 4950,
(((13 * ascii_values[0] + 66 * ascii_values[1] + 29 * ascii_values[2] + 39 * ascii_values[3] - 33 * ascii_values[4]) + 13 * ascii_values[5] - 2 * ascii_values[6]) + 42 * ascii_values[7] + 62 * ascii_values[8] + 1 * ascii_values[9] - 10 * ascii_values[10]) + 11 * ascii_values[11] == 12544,
(((23 * ascii_values[0] + 6 * ascii_values[1] + 29 * ascii_values[2] + 3 * ascii_values[3] - 3 * ascii_values[4]) + 63 * ascii_values[5] - 25 * ascii_values[6]) + 2 * ascii_values[7] + 32 * ascii_values[8] + 1 * ascii_values[9] - 10 * ascii_values[10]) + 11 * ascii_values[11] - 12 * ascii_values[12] == 6585,
((((223 * ascii_values[0] + 6 * ascii_values[1] - 29 * ascii_values[2] - 53 * ascii_values[3] - 3 * ascii_values[4]) + 3 * ascii_values[5] - 65 * ascii_values[6]) + 0 * ascii_values[7] + 36 * ascii_values[8] + 1 * ascii_values[9] - 15 * ascii_values[10]) + 16 * ascii_values[11] - 18 * ascii_values[12]) + 13 * ascii_values[13] == 6893,
((((29 * ascii_values[0] + 13 * ascii_values[1] - 9 * ascii_values[2] - 93 * ascii_values[3]) + 33 * ascii_values[4] + 6 * ascii_values[5] + 65 * ascii_values[6] + 1 * ascii_values[7] - 36 * ascii_values[8]) + 0 * ascii_values[9] - 16 * ascii_values[10]) + 96 * ascii_values[11] - 68 * ascii_values[12]) + 33 * ascii_values[13] - 14 * ascii_values[14] == 1883,
(((69 * ascii_values[0] + 77 * ascii_values[1] - 93 * ascii_values[2] - 12 * ascii_values[3]) + 0 * ascii_values[4] + 0 * ascii_values[5] + 1 * ascii_values[6] + 16 * ascii_values[7] + 36 * ascii_values[8] + 6 * ascii_values[9] + 19 * ascii_values[10] + 66 * ascii_values[11] - 8 * ascii_values[12]) + 38 * ascii_values[13] - 16 * ascii_values[14]) + 15 * ascii_values[15] == 8257,
((((23 * ascii_values[0] + 2 * ascii_values[1] - 3 * ascii_values[2] - 11 * ascii_values[3]) + 12 * ascii_values[4] + 24 * ascii_values[5] + 1 * ascii_values[6] + 6 * ascii_values[7] + 14 * ascii_values[8] - 0 * ascii_values[9]) + 1 * ascii_values[10] + 68 * ascii_values[11] - 18 * ascii_values[12]) + 68 * ascii_values[13] - 26 * ascii_values[14]) + 15 * ascii_values[15] - 16 * ascii_values[16] == 5847,
(((((24 * ascii_values[0] + 0 * ascii_values[1] - 1 * ascii_values[2] - 15 * ascii_values[3]) + 13 * ascii_values[4] + 4 * ascii_values[5] + 16 * ascii_values[6] + 67 * ascii_values[7] + 146 * ascii_values[8] - 50 * ascii_values[9]) + 16 * ascii_values[10] + 6 * ascii_values[11] - 1 * ascii_values[12]) + 69 * ascii_values[13] - 27 * ascii_values[14]) + 45 * ascii_values[15] - 6 * ascii_values[16]) + 17 * ascii_values[17] == 18257,
((((25 * ascii_values[0] + 26 * ascii_values[1] - 89 * ascii_values[2]) + 16 * ascii_values[3] + 19 * ascii_values[4] + 44 * ascii_values[5] + 36 * ascii_values[6] + 66 * ascii_values[7] - 150 * ascii_values[8] - 250 * ascii_values[9]) + 166 * ascii_values[10] + 126 * ascii_values[11] - 11 * ascii_values[12]) + 690 * ascii_values[13] - 207 * ascii_values[14]) + 46 * ascii_values[15] + 6 * ascii_values[16] + 7 * ascii_values[17] - 18 * ascii_values[18] == 12591,
(((((5 * ascii_values[0] + 26 * ascii_values[1] + 8 * ascii_values[2] + 160 * ascii_values[3] + 9 * ascii_values[4] - 4 * ascii_values[5]) + 36 * ascii_values[6] + 6 * ascii_values[7] - 15 * ascii_values[8] - 20 * ascii_values[9]) + 66 * ascii_values[10] + 16 * ascii_values[11] - 1 * ascii_values[12]) + 690 * ascii_values[13] - 20 * ascii_values[14]) + 46 * ascii_values[15] + 6 * ascii_values[16] + 7 * ascii_values[17] - 18 * ascii_values[18]) + 19 * ascii_values[19] == 52041,
((((((29 * ascii_values[0] - 26 * ascii_values[1]) + 0 * ascii_values[2] + 60 * ascii_values[3] + 90 * ascii_values[4] - 4 * ascii_values[5]) + 6 * ascii_values[6] + 6 * ascii_values[7] - 16 * ascii_values[8] - 21 * ascii_values[9]) + 69 * ascii_values[10] + 6 * ascii_values[11] - 12 * ascii_values[12]) + 69 * ascii_values[13] - 20 * ascii_values[14] - 46 * ascii_values[15]) + 65 * ascii_values[16] + 0 * ascii_values[17] - 1 * ascii_values[18]) + 39 * ascii_values[19] - 20 * ascii_values[20] == 20253,
(((((((45 * ascii_values[0] - 56 * ascii_values[1]) + 10 * ascii_values[2] + 650 * ascii_values[3] - 900 * ascii_values[4]) + 44 * ascii_values[5] + 66 * ascii_values[6] - 6 * ascii_values[7] - 6 * ascii_values[8] - 21 * ascii_values[9]) + 9 * ascii_values[10] - 6 * ascii_values[11] - 12 * ascii_values[12]) + 69 * ascii_values[13] - 2 * ascii_values[14] - 406 * ascii_values[15]) + 651 * ascii_values[16] + 2 * ascii_values[17] - 10 * ascii_values[18]) + 69 * ascii_values[19] - 0 * ascii_values[20]) + 21 * ascii_values[21] == 18768,
(((((555 * ascii_values[0] - 6666 * ascii_values[1]) + 70 * ascii_values[2] + 510 * ascii_values[3] - 90 * ascii_values[4]) + 499 * ascii_values[5] + 66 * ascii_values[6] - 66 * ascii_values[7] - 610 * ascii_values[8] - 221 * ascii_values[9]) + 9 * ascii_values[10] - 23 * ascii_values[11] - 102 * ascii_values[12]) + 6 * ascii_values[13] + 2050 * ascii_values[14] - 406 * ascii_values[15]) + 665 * ascii_values[16] + 333 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 777 * ascii_values[20] + 201 * ascii_values[21] - 22 * ascii_values[22] == 111844,
(((((((1 * ascii_values[0] - 22 * ascii_values[1]) + 333 * ascii_values[2] + 4444 * ascii_values[3] - 5555 * ascii_values[4]) + 6666 * ascii_values[5] - 666 * ascii_values[6]) + 676 * ascii_values[7] - 660 * ascii_values[8] - 22 * ascii_values[9]) + 9 * ascii_values[10] - 73 * ascii_values[11] - 107 * ascii_values[12]) + 6 * ascii_values[13] + 250 * ascii_values[14] - 6 * ascii_values[15]) + 65 * ascii_values[16] + 39 * ascii_values[17] + 10 * ascii_values[18] + 69 * ascii_values[19] + 777 * ascii_values[20] + 201 * ascii_values[21] - 2 * ascii_values[22]) + 23 * ascii_values[23] == 159029,
(((520 * ascii_values[0] - 222 * ascii_values[1]) + 333 * ascii_values[2] + 4 * ascii_values[3] - 56655 * ascii_values[4]) + 6666 * ascii_values[5] + 666 * ascii_values[6] + 66 * ascii_values[7] - 60 * ascii_values[8] - 220 * ascii_values[9]) + 99 * ascii_values[10] + 73 * ascii_values[11] + 1007 * ascii_values[12] + 7777 * ascii_values[13] + 2500 * ascii_values[14] + 6666 * ascii_values[15] + 605 * ascii_values[16] + 390 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 99999 * ascii_values[20] + 210 * ascii_values[21] + 232 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24] == 2762025,
((((1323 * ascii_values[0] - 22 * ascii_values[1]) + 333 * ascii_values[2] + 4 * ascii_values[3] - 55 * ascii_values[4]) + 666 * ascii_values[5] + 666 * ascii_values[6] + 66 * ascii_values[7] - 660 * ascii_values[8] - 220 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 100 * ascii_values[12] + 777 * ascii_values[13] + 2500 * ascii_values[14] + 6666 * ascii_values[15] + 605 * ascii_values[16] + 390 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 9999 * ascii_values[20] + 210 * ascii_values[21] + 232 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24]) + 25 * ascii_values[25] == 1551621,
(((((777 * ascii_values[0] - 22 * ascii_values[1]) + 6969 * ascii_values[2] + 4 * ascii_values[3] - 55 * ascii_values[4]) + 666 * ascii_values[5] - 6 * ascii_values[6]) + 96 * ascii_values[7] - 60 * ascii_values[8] - 220 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 100 * ascii_values[12] + 777 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + 65 * ascii_values[16] + 90 * ascii_values[17] + 100 * ascii_values[18] + 609 * ascii_values[19] + 999 * ascii_values[20] + 21 * ascii_values[21] + 232 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24]) + 25 * ascii_values[25] - 26 * ascii_values[26] == 948348,
((((((97 * ascii_values[0] - 22 * ascii_values[1]) + 6969 * ascii_values[2] + 4 * ascii_values[3] - 56 * ascii_values[4]) + 96 * ascii_values[5] - 6 * ascii_values[6]) + 96 * ascii_values[7] - 60 * ascii_values[8] - 20 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 10 * ascii_values[12] + 707 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + -9 * ascii_values[16] + 90 * ascii_values[17] + -2 * ascii_values[18] + 609 * ascii_values[19] + 0 * ascii_values[20] + 21 * ascii_values[21] + 2 * ascii_values[22] + 23 * ascii_values[23] - 24 * ascii_values[24]) + 25 * ascii_values[25] - 26 * ascii_values[26]) + 27 * ascii_values[27] == 777044,
(((((177 * ascii_values[0] - 22 * ascii_values[1]) + 699 * ascii_values[2] + 64 * ascii_values[3] - 56 * ascii_values[4] - 96 * ascii_values[5] - 66 * ascii_values[6]) + 96 * ascii_values[7] - 60 * ascii_values[8] - 20 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 10 * ascii_values[12] + 707 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + -9 * ascii_values[16] + 0 * ascii_values[17] + -2 * ascii_values[18] + 69 * ascii_values[19] + 0 * ascii_values[20] + 21 * ascii_values[21] + 222 * ascii_values[22] + 23 * ascii_values[23] - 224 * ascii_values[24]) + 25 * ascii_values[25] - 26 * ascii_values[26]) + 27 * ascii_values[27] - 28 * ascii_values[28] == 185016,
((((((77 * ascii_values[0] - 2 * ascii_values[1]) + 6 * ascii_values[2] + 6 * ascii_values[3] - 96 * ascii_values[4] - 9 * ascii_values[5] - 6 * ascii_values[6]) + 96 * ascii_values[7] - 0 * ascii_values[8] - 20 * ascii_values[9]) + 99 * ascii_values[10] + 3 * ascii_values[11] + 10 * ascii_values[12] + 707 * ascii_values[13] + 250 * ascii_values[14] + 666 * ascii_values[15] + -9 * ascii_values[16] + 0 * ascii_values[17] + -2 * ascii_values[18] + 9 * ascii_values[19] + 0 * ascii_values[20] + 21 * ascii_values[21] + 222 * ascii_values[22] + 23 * ascii_values[23] - 224 * ascii_values[24]) + 26 * ascii_values[25] - -58 * ascii_values[26]) + 27 * ascii_values[27] - 2 * ascii_values[28]) + 29 * ascii_values[29] == 130106]
for c in conditions:
solver.add(c)
# 限定每个 ascii 值为可打印字符范围(32 到 126)
for v in ascii_values:
solver.add(v >= 32, v <= 126)
# 求解并输出结果
if solver.check() == sat:
model = solver.model()
solution = [model[v].as_long() for v in ascii_values]
flag = ''.join(chr(v) for v in solution)
print("Solution ascii values:", solution)
print("Flag:", flag)
else:
print("No solution found.")
from collections import Counter
# 固定信息:各字符的总出现次数(从 z3 得到的编码字符串)
freq = {
'H': 1, 'Z': 1, 'N': 1, 'U': 1, 'C': 1, 'T': 1, 'F': 1, '{': 1,
'a': 6, 'd': 2, '7': 5, 'f': 7, '-': 4, '6': 3, '}': 1
}
# flag 长度
flag_len = sum(freq.values()) # 36
# 根据 count_str 要求,每个位置的数字决定了该位置应属于哪个字符(频率)
# 位置与对应数字(数字为字符在 flag 中的总出现次数)如下:
pos_digit = {
0: '1', 1: '1', 2: '1', 3: '1', 4: '1', 5: '1', 6: '1', 7: '1',
8: '6',
9: '2',
10: '5',
11: '7',
12: '6',
13: '4',
14: '5',
15: '3',
16: '6',
17: '5',
18: '4',
19: '7',
20: '7',
21: '3',
22: '6',
23: '4',
24: '7',
25: '7',
26: '7',
27: '6',
28: '4',
29: '5',
30: '7',
31: '5',
32: '2',
33: '3',
34: '6',
35: '1'
}
# 数字与应对应的字符(每个数字只可能来自特定字符):
digit_to_char = {
'1': None, # 出现1的字符有多个:H, Z, N, U, C, T, F, {, },且要求第一次出现顺序为 [H, Z, N, U, C, T, F, {, }]
'6': 'a',
'2': 'd',
'5': '7',
'7': 'f',
'4': '-',
'3': '6'
}
# 根据第一次出现顺序,频率1 字符固定排列为:
freq1_order = ['H', 'Z', 'N', 'U', 'C', 'T', 'F', '{', '}']
# 从 pos_digit 得知,所有位置标记为 '1' 的位置必须填入频率1的字符,且第一出现顺序必须为 freq1_order
# 观察 pos_digit:位置 0~7和位置35为 '1'
# 因此,我们要求:
# flag[0] = 'H', flag[1] = 'Z', ..., flag[7] = '{', flag[35] = '}'
# 其余位置可以直接确定:
flag_list = [''] * flag_len
# 填入固定的频率1字符:
flag_list[0] = 'H'
flag_list[1] = 'Z'
flag_list[2] = 'N'
flag_list[3] = 'U'
flag_list[4] = 'C'
flag_list[5] = 'T'
flag_list[6] = 'F'
flag_list[7] = '{'
flag_list[35] = '}'
# 对于其它位置,根据 pos_digit 与 digit_to_char 可直接赋值:
for pos in range(flag_len):
if pos in [0,1,2,3,4,5,6,7,35]:
continue
d = pos_digit[pos]
flag_list[pos] = digit_to_char[d]
flag_candidate = ''.join(flag_list)
print("爆破得到的 flag 为:")
print(flag_candidate)
# 验证 count_str:
cnt = Counter(flag_candidate)
count_str = ''.join(str(cnt[c]) for c in flag_candidate)
print("计算得到的 count_str 为:")
print(count_str)
expected = "111111116257645365477364777645752361"
print("期望的 count_str 为:")
print(expected)
if count_str == expected:
print("flag 符合要求!")
else:
print("flag 不符合要求!")
xtea
ida打开进去会发现很乱
直接shift+F12找字符串,然后找到主函数入口
题目提示tea,直接去找看看能不能找到tea加密函数
找到了类似的东西
但是很明显少了东西
没有模数
而且轮数也被魔改成32轮
查看模数是A1
a1是传进来的
是一个V10数组
通过对代码分析和动态调试
v10是用户传进来的
缓冲区里没有东西,回去分析代码
发现有个sub_7FF792BD10B9(key);调用了key
进去发现调用了一个rand()函数这个是一个随机函数
回去看代码,看种子的生成逻辑
发现是一个固定种子,根据计算机的随机数
随机数种子固定,生成的随机数就是固定的
回去看上面的代码,一共生成了4次
说明key就是由这个伪随机数生成的
直接用Python模拟一个c的随机数生成器
class CppRand:
def __init__(self, seed):
self.seed = seed # 初始化种子
def rand(self):
# LCG 算法生成下一个种子
self.seed = (self.seed * 214013 + 2531011) % (1 << 31)
# 返回高15位值(模拟 C/C++ 的 rand())
return (self.seed >> 16) & 0x7FFF
# 使用种子 2024 初始化
rng = CppRand(2024)
# 生成4个与 C/C++ 完全相同的随机数
random_numbers = [rng.rand() for _ in range(4)]
print(random_numbers)
得到[6648, 4542, 2449, 13336]
目前我们除了魔数不知道,其他都是已知的
第一种方式就是我们直接爆破
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4],uint32_t delta) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0,a,b,c ;
for (i = 0; i < num_rounds; i++) {
a = (v1 << 4) ^ (v1 >> 5);
//printf("%x\n", a);
b = a+v1;
c = sum + key[sum & 3];
v0 += ( b^ c);
sum -= delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
v[0] = v0; v[1] = v1;
}
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4],uint32_t delta) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = delta * num_rounds ;
sum = 0;
for (int j = 0; j < 32; j++) sum -= delta;
for (i = 0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
sum += delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
v[0] = v0; v[1] = v1;
}
int main() {
uint32_t v[8] = { 0x8CCB2324, 0x09A7741A, 0xFB3C678D, 0xF6083A79, 0xF1CC241B, 0x39FA59F2, 0xF2ABE1CC, 0x17189F72 };
uint32_t k[4] = { 0x000019F8, 0x000011BE, 0x00000991, 0x00003418 };
srand(2024);
uint32_t v2[4] = {0};
char flag[] = "HZNUCTF{";
//for (int i = 0; i < 4; i++) {
// k[i] = rand();
//}
uint32_t delta = 0;
for (uint32_t j = 0; j < 0xffffffff; j++) {
v2[0] = 0x485a4e55;
v2[1] = 0x4354467b;
encipher(32, v2, k,j);
if (v2[0] == v[0]) {
delta = j;
printf("%d\n", j);
}
}
printf("\n");
unsigned int r = 32;
for (int i = 6; i >=0; i--) {
decipher(r, &v[i], k, delta);
}
for (int i = 0; i < 32; i++) {
printf("%c", *((char*)v + i));
}
return 0;
}
但是这花费的时间比较久,因为这题还有个阴间的地方就是大小端序问题
会导致你直接爆破的明文没有完整flag头
所以不能通过得到flag头去退出
但是其实爆破时间也不长
大概十分钟是可以爆破出来的
还有一种方法就是直接上板子
这也是我经常干的事
上来管他有没有魔改,先上板子
板子解不出来再去分析魔改
#include <stdio.h>
#include <stdint.h>
int main() {
uint32_t data[] = {
0x8CCB2324, 0x9A7741A, 0x0FB3C678D, 0x0F6083A79,
0x0F1CC241B, 0x39FA59F2, 0x0F2ABE1CC, 0x17189F72
};
uint32_t k[] = {6648, 4542, 2449, 13336};
int delta = 0x9E3779B9;
// TEA-like 解密过程
for (int i = 6; i >= 0; i--) {
int sum = (0 - (32 * delta)) & 0xFFFFFFFF;
for (int j = 0; j < 32; j++) {
data[i + 1] -= (k[(sum >> 11) & 3] + sum) ^ (data[i] + ((data[i] >> 5) ^ (16 * data[i])));
sum += delta;
data[i] -= (k[sum & 3] + sum) ^ (data[i + 1] + ((data[i + 1] >> 5) ^ (16 * data[i + 1])));
}
}
// printf("Decrypted data (hex):\n");
char *str = (char *)data;
printf("Decrypted ASCII:\n%s\n", str);
printf("\n");
return 0;
}
确实还有一种方法,题目提示了misc,给了个压缩包给了个md,但是这个压缩包没有任何意义
md里给了个压缩包密码:2654435769
把这个数转成16进制,其实就是标准的魔数