Logo WP

2024-04-28

babyre#

【CISCN 2023 初赛】babyRE

文件

xml文件里有个网站:Snap! re4baby22 (berkeley.edu)

类似Scratch的可视化编程,导入xml

Article Image

输入flag之后报错,“需要开启JavaScript”

点左上角齿轮,Enable Js,就运行正常了

每个元素都点一下,找找加密脚本

Article Image

复制一下模块,改成 say secret for 600 secs ,右键显示的数组 export,就可以拿到 secret

enc = [102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]

r = [enc[0]]
for i in range(1, len(enc)):
    r.append(enc[i] ^ r[i - 1])
print(''.join([chr(c) for c in r]))

用z3也可以,需要注意的是,z3只有BitVec能进行位运算,Int位运算会报错

Babybc#

文件

提交的flag为NSSCTF{md5(your_input)}

通过搜索后缀名,是 LLVM Bitcode 格式

安装 llvm

sudo apt install llvm
lli baby.bc # 运行
llvm-dis baby.bc -o baby.ll # 反汇编
llc baby.ll # 生成 baby.s
as baby.s -o baby # 生成 baby

其实一条命令就完事

Windows安装 LLVM Snapshot Builds

clang baby.bc -o baby

就可以把baby扔进IDA里分析了,不过不能直接运行

分析错了#

v28 = 0;
v27 = 0;
v2 = *(v0 - 4);
if ( *((_BYTE *)&v27 + v2) )
  break;
*((_BYTE *)&v27 + v2) = 1;
v3 = *(v0 - 3);
if ( *((_BYTE *)&v27 + v3) )
  break;
*((_BYTE *)&v27 + v3) = 1;
v4 = *(v0 - 2);
if ( *((_BYTE *)&v27 + v4) )
  break;
*((_BYTE *)&v27 + v4) = 1;
v5 = *(v0 - 1);
if ( *((_BYTE *)&v27 + v5) )
  break;
*((_BYTE *)&v27 + v5) = 1;
if ( *((_BYTE *)&v27 + *v0) )
  break;
++v1;
v0 += 5;

这里的代码我以为是初始化,实际上是为了保证每一行的元素都不能相同

下面的代码是保证了每一列中的元素不能相同——就是数独

map = [[0] * 5, [0] * 5, [0,0,4,0,0], [0,0,0,3,0], [0] * 5]
row = [[0,0,0,1],[1,0,0,0],[2,0,0,1], [0] * 4, [1,0,1,0]]
col = [[0,0,2,0,2], [0]* 5, [0,0,0,1,0], [0,1,0,0,1]]

from z3 import *

solver = Solver()
flag = []
for i in range(25):
    if i == (2 * 5 + 2) or i == (3 * 5 + 3):
        flag.append(b'0')
    else:
        v = Int(f"a_{i}")
        flag.append(v)
        solver.add(v >= ord('0'))
        solver.add(Not(v - ord('0') > 5))

print(flag)

# 初始化
# 必须刚好是25,而且指定位置的字符必须是0
for i in range(5):
    for j in range(5):
        tmp = flag[i*5 + j]
        if map[i][j] != 0:
            continue
        else:
            map[i][j] = tmp - ord('0')

for i in range(5): # 遍历行
    for j in range(5): # 遍历咧
        for k in range(5): # 再遍历列/行
            if j != k:
                solver.add(map[i][j] != map[i][k])
            if i != k:
                solver.add(map[i][j] != map[k][j])

# 这里是把row/col当做指令,根据指令来对map进行操作
for i in range(5):
    for j in range(4):
        match row[i][j]:
            case 2:
                solver.add(Not(map[i][j] > map[i][j+1]))
            case 1:
                solver.add(Not(map[i][j] < map[i][j+1]))

for i in range(4):
    for j in range(5):
        match col[i][j]:
            case 2:
                solver.add(Not(map[i][j] < map[i+1][j]))
            case 1:
                solver.add(Not(map[i][j] > map[i+1][j]))

print(solver.check())
m = solver.model()

r = ''
for i in range(25):
    if i == (2 * 5 + 2) or i == (3 * 5 + 3):
        r += '0'
    else:
        r += chr(m[flag[i]].as_long())
print(r)

import hashlib
print(hashlib.md5(r.encode()).hexdigest())
CISCN{MD5(0524332051230104010251324)}