0x1
感觉这题最大的难点是bc,实际内容很容易推理出是数独,如果知道了bc是什么,就比较容易解出。
0x2
最开始得到的是bc文件,什么是bc文件,个人觉得就是还没编译完成的中间文件,可以接着将它编译成我们能进行正常逆向分析的文件,
图是其他师傅画的,yeah
我们可以用clang将bc文件编译为elf文件
clang baby.bc -o baby
将得到的elf文件拖入ida,就可以进行内容的分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned __int64 v4; // [rsp+10h] [rbp-28h]
unsigned __int64 i; // [rsp+18h] [rbp-20h]
size_t v6; // [rsp+20h] [rbp-18h]
__isoc99_scanf(&unk_4015B4, input, envp);
if ( (unsigned int)strlen((const char *)(unsigned int)input) == 25 )// len==25
{
if ( input[0] )
{
if ( (unsigned __int8)(input[0] - 48) > 5u )
return 0;
v6 = strlen((const char *)(unsigned int)input);
for ( i = 1LL; ; ++i )
{
v4 = i;
if ( i >= v6 )
break;
if ( (unsigned __int8)(input[v4] - 48) > 5u )// input[i]<=5&&input[i]>0
return 0;
}
}
if ( (check1(input) & 1) != 0 && (check2() & 1) != 0 )
printf("CISCN{MD5(%s)}", input);
}
return 0;
}
确定输入值的len,范围
check1函数是为了确保如果5*5的数组内如果原始值不为零的时候,你输入的值需要为零
check2的分析内容如下
__int64 check()
{
char v1; // [rsp+34h] [rbp-B4h]
__int64 v2; // [rsp+38h] [rbp-B0h]
__int64 l; // [rsp+48h] [rbp-A0h]
__int64 v4; // [rsp+58h] [rbp-90h]
__int64 j; // [rsp+60h] [rbp-88h]
__int64 v6; // [rsp+80h] [rbp-68h]
char v7; // [rsp+8Fh] [rbp-59h]
__int64 v8; // [rsp+A8h] [rbp-40h]
__int64 k; // [rsp+B8h] [rbp-30h]
__int64 i; // [rsp+C8h] [rbp-20h]
char v11[6]; // [rsp+DCh] [rbp-Ch] BYREF
char v12[6]; // [rsp+E2h] [rbp-6h] BYREF
i = 0LL;
do // 同一排中不能有相同值
{
v8 = i;
memset(v12, 0, sizeof(v12));
if ( v12[(unsigned __int8)flag[5 * i]]
|| (v12[(unsigned __int8)flag[5 * i]] = 1, v12[(unsigned __int8)flag[5 * i + 1]])
|| (v12[(unsigned __int8)flag[5 * i + 1]] = 1, v12[(unsigned __int8)flag[5 * i + 2]])
|| (v12[(unsigned __int8)flag[5 * i + 2]] = 1, v12[(unsigned __int8)flag[5 * i + 3]])
|| (v12[(unsigned __int8)flag[5 * i + 3]] = 1, v12[(unsigned __int8)flag[5 * i + 4]]) )
{
v7 = 0;
return v7 & 1;
}
++i;
}
while ( v8 + 1 < 5 );
k = 0LL;
while ( 1 ) // 同一列中不能有相同值
{
v6 = k;
memset(v11, 0, sizeof(v11));
if ( v11[(unsigned __int8)flag[k]] )
break;
v11[(unsigned __int8)flag[k]] = 1;
if ( v11[(unsigned __int8)byte_602055[k]] )
break;
v11[(unsigned __int8)byte_602055[k]] = 1;
if ( v11[(unsigned __int8)byte_60205A[k]] )
break;
v11[(unsigned __int8)byte_60205A[k]] = 1;
if ( v11[(unsigned __int8)byte_60205F[k]] )
break;
v11[(unsigned __int8)byte_60205F[k]] = 1;
if ( v11[(unsigned __int8)byte_602064[k]] )
break;
++k;
if ( v6 + 1 >= 5 )
{
j = 0LL; // 相邻两列进行设置限制
while ( 1 ) // 0==>无限制,1==>小于,2==>大于
{
v4 = j;
if ( rule1[4 * j] == 1 )
{
if ( (unsigned __int8)flag[5 * j] < (unsigned __int8)flag[5 * j + 1] )
goto LABEL_27;
}
else if ( rule1[4 * j] == 2 && (unsigned __int8)flag[5 * j] > (unsigned __int8)flag[5 * j + 1] )
{
LABEL_27:
v7 = 0;
return v7 & 1;
}
if ( arr1[4 * j] == 1 ) // arr1[0]=n[1]
{
if ( (unsigned __int8)flag[5 * j + 1] < (unsigned __int8)flag[5 * j + 2] )
goto LABEL_27;
}
else if ( arr1[4 * j] == 2 && (unsigned __int8)flag[5 * j + 1] > (unsigned __int8)flag[5 * j + 2] )
{
goto LABEL_27;
}
if ( arr2[4 * j] == 1 )
{
if ( (unsigned __int8)flag[5 * j + 2] < (unsigned __int8)flag[5 * j + 3] )
goto LABEL_27;
}
else if ( arr2[4 * j] == 2 && (unsigned __int8)flag[5 * j + 2] > (unsigned __int8)flag[5 * j + 3] )
{
goto LABEL_27;
}
if ( arr3[4 * j] == 1 )
{
if ( (unsigned __int8)flag[5 * j + 3] < (unsigned __int8)flag[5 * j + 4] )
goto LABEL_27;
}
else if ( arr3[4 * j] == 2 && (unsigned __int8)flag[5 * j + 3] > (unsigned __int8)flag[5 * j + 4] )
{
goto LABEL_27;
}
++j;
if ( v4 + 1 >= 5 )
{
l = 0LL; // 相邻两行进行设置限制
while ( 1 )
{
v2 = l + 1; // 0==>无限制,1==>大于,2==>小于
if ( rule2[5 * l] == 1 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l] > (unsigned __int8)flag[5 * v2] )
goto LABEL_26;
}
else if ( rule2[5 * l] == 2 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l] < (unsigned __int8)flag[5 * v2] )
{
LABEL_26:
v7 = v1;
return v7 & 1;
}
}
if ( Arr1[5 * l] == 1 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 1] > (unsigned __int8)flag[5 * v2 + 1] )
goto LABEL_26;
}
else if ( Arr1[5 * l] == 2 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 1] < (unsigned __int8)flag[5 * v2 + 1] )
goto LABEL_26;
}
if ( Arr2[5 * l] == 1 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 2] > (unsigned __int8)flag[5 * v2 + 2] )
goto LABEL_26;
}
else if ( Arr2[5 * l] == 2 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 2] < (unsigned __int8)flag[5 * v2 + 2] )
goto LABEL_26;
}
if ( Arr3[5 * l] == 1 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 3] > (unsigned __int8)flag[5 * v2 + 3] )
goto LABEL_26;
}
else if ( Arr3[5 * l] == 2 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 3] < (unsigned __int8)flag[5 * v2 + 3] )
goto LABEL_26;
}
if ( byte_602094[5 * l] == 1 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 4] > (unsigned __int8)flag[5 * v2 + 4] )
goto LABEL_26;
}
else if ( byte_602094[5 * l] == 2 )
{
v1 = 0;
if ( (unsigned __int8)flag[5 * l + 4] < (unsigned __int8)flag[5 * v2 + 4] )
goto LABEL_26;
}
++l;
v1 = 1;
if ( v2 >= 4 ) // 运行四次
goto LABEL_26;
}
}
}
}
}
v7 = 0;
return v7 & 1;
}
由于只是5*5的数独,自己可以手动推一下,也可以使用z3实现数独解密
import hashlib
from z3 import *
a=[0, 0, 0, 1, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0] #行 0==>无限制,1==>小于,2==>大于
b=[0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1] #列 0==>无限制,1==>大于,2==>小于
s=Solver()
sudu=[[None]*5,[None]*5,[None]*5,[None]*5,[None]*5]
for i in range(5):
for j in range(5):
sudu[i][j]=Int("%d" %(i*5+j))
s.add(sudu[2][2]==4,sudu[3][3]==3)
for i in range(5):
for j in range(5):
s.add(sudu[i][j]>=1,sudu[i][j]<=5)
for i in range(5):
for j in range(5):
for k in range(j):
s.add(sudu[i][j]!=sudu[i][k])
for i in range(5):
for j in range(5):
for k in range(j):
s.add(sudu[j][i]!=sudu[k][i])
for i in range(5):
for j in range(4):
if a[4*i+j]==1:
s.add(sudu[i][j]>sudu[i][j+1])
elif a[4*i+j]==2:
s.add(sudu[i][j]<sudu[i][j+1])
for i in range(4):
for j in range(5):
if b[5*i+j]==1:
s.add(sudu[i][j]<sudu[(i+1)][j])
elif b[5*i+j]==2:
s.add(sudu[i][j]>sudu[(i+1)][j])
if s.check()==sat:
print("yeah")
strflag=""
m=s.model()
for i in range(5):
for j in range(5):
if (i==2 and j==2) or (i==3 and j==3):
strflag+="0"
continue
strflag+=str(m[sudu[i][j]].as_long())
# print(strflag)
print(hashlib.md5(strflag.encode()).hexdigest())
else:
print("emmm")
得到flag:
CISCN{8a04b4597ad08b83211d3adfa1f61431}