Posted onInctfViews: Disqus: Word count in article: 490Reading time ≈2 mins.
We created a service which can read and print the flag for you. To
use the application, you first need to enter a valid product key. Can
you reverse the algorithm and generate a valid key?
Reversing
The binary reads a product key, validates it, and prints the flag
only if validation succeeds.
int __fastcall main(int argc, char **argv, char **envp) { int is_valid; char input_key[136];
setbuf(stdout, 0); memset(input_key, 0, 129); puts("Enter a valid product key to gain access to the flag:"); fgets(input_key, 128, stdin); input_key[strcspn(input_key, "\n")] = 0;
from z3 import * from z3 import BitVec, BitVecVal, If, Solver, ZeroExt, sat
s = Solver()
# 1. 定义 32 个 8-bit 的符号变量(代表字符) flag = [BitVec(f"flag[{i}]", 8) for i inrange(32)]
# 2. 施加字符集约束 ('@' to 'Z') for i inrange(32): # Integer Promotion converts c to a 32-bit integer = 8 bits(char) + 24 bits s.add(flag[i] >= 65, flag[i] <= 90)
# 3. 核心转换逻辑 (transform_char) deftransform(c): # z3 的 If 语法:If(条件, 真值, 假值) return If(c <= 77, ZeroExt(24, c) + 181, ZeroExt(24, c) + 177)
# 4. 累加校验和计算 # 使用 32-bit 位向量防止整数溢出,就像 C 语言里的 int 一样 # Integer Promotion converts c to a 32-bit integer = 8 bits(char) + 24 bits checksum = BitVecVal(247, 32) for i inrange(1, 32): checksum += transform(flag[i]) - i + 247
if s.check() == sat: model = s.model() # 提取计算出的字符并拼接 flag = "".join(chr(model[flag[i]].as_long()) for i inrange(32)) print(f"[+] Valid Product Key: {flag}")
Solver output:
1
BUYRSCLZHPATAQZSLJMJMKOOBFRAOVUX
Remote verification
1
nc 892dc593a381aaea.247ctf.com 50478
1 2 3 4
Enter a valid product key to gain access to the flag: BUYRSCLZHPATAQZSLJMJMKOOBFRAOVUX Valid product key! 247CTF{********************************}