# Google CTF 2023
# ZerMatt
给的是混淆后的 lua 的源码 vscode 中 按 shift+alt+f 可格式化
下载 lua5.3 运行一下
luaide 没调起
失败和成功字符串都要经过 v7 函数之后再打印出来 v7 就是一个异或
可疑的 v21 打印就是 flag
CTF{At_least_it_was_not_a_bytecode_base_sandbox_escape} |
# Old School
这个函数是验证密码的组成:
k = 0; | |
m = 0; | |
while ( input[k] ) | |
{ | |
if ( k == 5 || k == 11 || k == 17 || k == 23 ) | |
{ | |
if ( input[k] != 45 ) | |
return 0; | |
} | |
else | |
{ | |
v39 = 0; | |
for ( i = 0; i <= 31; ++i ) | |
{ | |
sub_565C60DA(v20); | |
for ( j = 0; j <= 31; ++j ) | |
{ | |
v3 = sub_565DF8D6(v21, j); // v3=v21[j] | |
v17 = sub_565DF8FA(v20, *v3, j); // v17=v20[j]^v21[j] | |
*sub_565DF8D6(v21, j) = v17; // v21[j]=v17 | |
} // 不同的轮 v20 还是一样 v21 不一样了 | |
*sub_565DF8D6(v21, 32) = 0; // 33 位变 0 | |
v4 = sub_565DF92A(v21); // 指针 | |
if ( *(i + v4) == input[k] ) // 逐位验证 | |
{ | |
v5 = m / 5; | |
v6 = m++; | |
v19[5 * v5 + v6 % 5] = i; | |
v39 = 1; | |
break; // 最终 v19 的值是关键 后面用到 | |
} | |
} | |
if ( v39 != 1 ) | |
return 0; | |
} | |
++k; | |
} |
上面 v21 数组有初值,v20 数组定值
v21 运行会生成一个固定的表进行验证
v4 是一个固定的表:
23456789ABCDEFGHJKLMNPQRSTUVWXYZ
修改构造密码为:33333-22222-33333-44444-55555 或者 33333-22222-AAAAA-BBBBB-CCCCC
v19 里面存的是每个密码相对于对于表中的位置,2→0, 3→1, 4→2
感觉思路是根据后面对 name 的运算 逆向推出 v19 的值,再推出密码
直接在下断点
得 v18 再求其逆矩阵 求 v19 就行 v19 知道了再查表就知道密码了
分析结果就是这个官方 WP 中的图
对于求逆矩阵 写了个 z3 脚本却怎么也没跑出
看了 WP 才发现其实有一个反调试…