-
-
[原创]KCTF2022春季赛第二题 解题过程
-
发表于: 2022-5-15 22:37 7439
-
算法分析题,有众多的printf打印信息,整个流程比较清晰,有正确的提示。从输入开始进行流程分析。
step1:输入ID,最多41个字符,第42个会设为0。
step2:计算CRC8(ID)
step3:计算CRC32(ID),不过这里要注意,正常CRC32计算的时候定义为unsigned int类型,这里识别的是int类型,在进行移位的时候如果是负数,则高位添加0xff。
step4:将输入的ASCII码类型字符串,转换为int类型。Ascii2Raw_4010B7((int)ID, iLenOfID);
step5:直接搜索3*n+1是什么数列,得知为Callztz数列,无论初始输入为多少,最终的结果就是变为1、4、2的循环,猜测经过200次变换,最后3个值为(1 4 2)、(4 2 1)或(2 1 4)的一种。
第一次校验:输入的前3个数的异或值为7。ID[2] ^ ID[1] ^ ID[0] == 7
step6:判断ID[3:7]是否为KCTF。(下图略掉printf)
step7:mod测试:
ID[7]%1 == 0
(ID[7]*10 + ID[8]) %2 == 0
(ID[7]*100 + ID[8]*10 + ID[9] ) %3 == 0
...
(ID[7]*100000000 + ID[8]*10000000 + ... + ID[15]) % 9 == 0
随后对ID[7:16]共9个数字进行冒泡排序,排序后为123456789,说明ID[7:16]为123456789的组合。
编程求解得解为:ID[7:16] == 381654729
step8:如果输入字符长度超过16,则对后续的字符判断是否为8字节的倍数,进行变换sub_4010E1,不过简单分析感觉并不可逆。如果长度正好为16则校验ID_CRC32_R == 0xF52E0765。
假设输入ID正好为16字符,综合以上分析,只需CRC32(XYZKCTF381654219) = ~0xF52E0765,且X^Y^Z==7。直接编程进行穷尽即可,注意这里的CRC32计算时为int类型。最后得421KCTF381654219。
printf_40100C(
Format
, (char)byte_4055C0);
scanf_40103A(
"%s"
, (char)
ID
);
printf_40100C(asc_403160, v33);
ID
[
41
]
=
0
;
iLenOfID
=
strlen(
ID
);
printf_40100C(
Format
, (char)byte_4055C0);
scanf_40103A(
"%s"
, (char)
ID
);
printf_40100C(asc_403160, v33);
ID
[
41
]
=
0
;
iLenOfID
=
strlen(
ID
);
v5
=
0
;
t_
=
iLenOfID;
v6
=
iLenOfID;
ID_CRC8
=
0
;
if
( iLenOfID )
{
v7
=
ID
;
do
{
v5 ^
=
*
v7;
-
-
v6;
+
+
v7;
v8
=
8
;
do
{
v9
=
2
*
v5;
v10
=
v9 ^
7
;
if
( v9 >
=
0
)
v10
=
v9;
v5
=
v10;
-
-
v8;
}
while
( v8 );
}
while
( v6 );
iLenOfID
=
t_;
ID_CRC8
=
v10;
}
v5
=
0
;
t_
=
iLenOfID;
v6
=
iLenOfID;
ID_CRC8
=
0
;
if
( iLenOfID )
{
v7
=
ID
;
do
{
v5 ^
=
*
v7;
-
-
v6;
+
+
v7;
v8
=
8
;
do
{
v9
=
2
*
v5;
v10
=
v9 ^
7
;
if
( v9 >
=
0
)
v10
=
v9;
v5
=
v10;
-
-
v8;
}
while
( v8 );
}
while
( v6 );
iLenOfID
=
t_;
ID_CRC8
=
v10;
}
CRC32_Init_40106C();
ID_CRC32
=
0xFFFFFFFF
;
for
( i
=
0
; i < iLenOfID;
+
+
i )
ID_CRC32
=
dword_405B20[(unsigned __int8)(ID_CRC32 ^
ID
[i])] ^ (ID_CRC32 >>
8
);
ID_CRC32_R
=
~ID_CRC32;
CRC32_Init_40106C();
ID_CRC32
=
0xFFFFFFFF
;
for
( i
=
0
; i < iLenOfID;
+
+
i )
ID_CRC32
=
dword_405B20[(unsigned __int8)(ID_CRC32 ^
ID
[i])] ^ (ID_CRC32 >>
8
);
ID_CRC32_R
=
~ID_CRC32;
v13
=
ID_CRC8;
imod
=
1
;
v68
=
ID_CRC8
+
1
;
v14
=
v68;
do
{
v15
=
v13;
for
( j
=
1
; j <
200
;
+
+
j )
/
/
Callatz
{
if
( (v15 &
1
) !
=
0
)
v15
=
3
*
v15
+
1
;
else
v15 >>
=
1
;
CallatzTable[j]
=
v15;
}
+
+
v13;
}
while
( v13 < v14 );
value_7
=
CallatzTable[
198
] | CallatzTable[
197
] | CallatzTable[
196
];
v18
=
t_;
if
( value_7 !
=
(
ID
[
2
] ^
ID
[
1
] ^
ID
[
0
]) )
/
/
b0111 的组合
{
printf_40100C(
"\n%s"
, (char)&unk_405594);
printf_40100C(
"\n%s\n%s"
, (char)&unk_405678);
printf_40100C(
"\n%s"
, (char)&unk_405118);
printf_40100C(
"\n%s"
, (char)&unk_4053A4);
goto LABEL_57;
}
v13
=
ID_CRC8;
imod
=
1
;
v68
=
ID_CRC8
+
1
;
v14
=
v68;
do
{
v15
=
v13;
for
( j
=
1
; j <
200
;
+
+
j )
/
/
Callatz
{
if
( (v15 &
1
) !
=
0
)
v15
=
3
*
v15
+
1
;
else
v15 >>
=
1
;
CallatzTable[j]
=
v15;
}
+
+
v13;
}
while
( v13 < v14 );
value_7
=
CallatzTable[
198
] | CallatzTable[
197
] | CallatzTable[
196
];
v18
=
t_;
if
( value_7 !
=
(
ID
[
2
] ^
ID
[
1
] ^
ID
[
0
]) )
/
/
b0111 的组合
{
printf_40100C(
"\n%s"
, (char)&unk_405594);
printf_40100C(
"\n%s\n%s"
, (char)&unk_405678);
printf_40100C(
"\n%s"
, (char)&unk_405118);
printf_40100C(
"\n%s"
, (char)&unk_4053A4);
goto LABEL_57;
}
if
(
ID
[
3
] !
=
20
)
/
/
K
{
/
/
goto LABEL_57;
}
/
/
if
(
ID
[
4
] !
=
12
)
/
/
C
{
/
/
goto LABEL_57;
}
/
/
if
(
ID
[
5
] !
=
29
)
/
/
T
{
/
/
goto LABEL_57;
}
/
/
if
(
ID
[
6
] !
=
15
)
/
/
F
{
/
/
goto LABEL_57;
}
if
(
ID
[
3
] !
=
20
)
/
/
K
{
/
/
goto LABEL_57;
}
/
/
if
(
ID
[
4
] !
=
12
)
/
/
C
{
/
/
goto LABEL_57;
}
/
/
if
(
ID
[
5
] !
=
29
)
/
/
T
{
/
/
goto LABEL_57;
}
/
/
if
(
ID
[
6
] !
=
15
)
/
/
F
{
/
/
goto LABEL_57;
}
if
( value_9 >
0
)
{
istart
=
1
;
do
{
v23
=
ID
[istart
+
6
]
+
10
*
before;
before_
=
v23
-
926365495
;
/
/
junkcode
if
( v23 <
=
1262703685
)
before_
=
v23;
before
=
before_;
if
( before_
%
imod )
/
/
mod
1
2
3
4
5
6
7
8
9
中间必须是
5
goto LABEL_50;
t
=
t_
+
1
;
istart
=
imod
+
1
;
t_
=
t;
+
+
imod;
}
while
( t < value_9 );
}
value_8
=
value_9
-
1
;
if
( value_9
-
1
>
0
)
{
value_8_
=
value_9
-
1
;
do
{
i_
=
0
;
if
( value_8 >
0
)
{
do
{
v28
=
ID
[i_
+
7
];
/
/
冒泡排序 从小到大 排序后为
123456789
v29
=
ID
[i_
+
8
];
if
( v28 > v29 )
{
ID
[i_
+
7
]
=
v29;
ID
[i_
+
8
]
=
v28;
}
+
+
i_;
}
while
( i_ < value_8 );
v3
=
0
;
}
-
-
value_8;
-
-
value_8_;
}
while
( value_8_ );
}
Ascii2Raw_4010B7((
int
)a1234567890Abcd, value_9);
/
/
123456789
i__
=
0
;
if
( value_9 >
0
)
{
while
( a1234567890Abcd[i__]
=
=
ID
[i__
+
7
] )
{
if
(
+
+
i__ >
=
value_9 )
goto LABEL_41;
}
goto LABEL_49;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [原创]第七题解题 4407
- [原创]KCTF2022春季赛第三题 解题过程 7655
- [原创]KCTF2022春季赛第三题:解题过程 7346
- [原创]KCTF2022春季赛第二题 解题过程 7440