-
-
[原创]KCTF2023 第八题AI核心地带
-
发表于: 2023-9-19 08:43 9830
-
然后整理下大概逻辑:
check数组有初始状态
flag数组是始终不变的
根据input的每一位,计算出一个下标id,选取flag[id]
将check数组5个数,分别跟flag[id] xor,最终会进行一个校验
因为xor具有偶数次消除的性质,所以先编写脚本,跑出最终结果需要flag中的[0] [2] [4] [8]
/
/
称为flag[
10
],看做
10
个
int
数
00402100
66
6C
61
67
7B
42
7A
63
5A
44
6E
66
4E
49
71
6D
flag{BzcZDnfNIqm
00402110
51
43
74
6B
54
47
6C
77
4C
79
44
59
65
69
48
49
QCtkTGlwLyDYeiHI
00402120
6A
78
53
58
77
6B
52
4B
7A
70
46
50
76
7D
00
00
jxSXwkRKzpFPv}..
/
/
称为check[
5
],取
20
字节,看做
5
个
int
00402130
43
61
6E
20
79
6F
75
20
63
72
61
63
6B
20
6D
65
Can you crack me
00402140
3F
5E
6F
6C
6F
5E
00
00
?^olo^.
/
/
称为flag[
10
],看做
10
个
int
数
00402100
66
6C
61
67
7B
42
7A
63
5A
44
6E
66
4E
49
71
6D
flag{BzcZDnfNIqm
00402110
51
43
74
6B
54
47
6C
77
4C
79
44
59
65
69
48
49
QCtkTGlwLyDYeiHI
00402120
6A
78
53
58
77
6B
52
4B
7A
70
46
50
76
7D
00
00
jxSXwkRKzpFPv}..
/
/
称为check[
5
],取
20
字节,看做
5
个
int
00402130
43
61
6E
20
79
6F
75
20
63
72
61
63
6B
20
6D
65
Can you crack me
00402140
3F
5E
6F
6C
6F
5E
00
00
?^olo^.
if
( input_len <
=
0
|| (input_len_1
=
input_len
-
1
,
input
[input_len
-
1
] !
=
'\n'
) )
{
v3
=
1
;
/
/
错误
v27
=
1
;
}
if
( input_len <
=
0
|| (input_len_1
=
input_len
-
1
,
input
[input_len
-
1
] !
=
'\n'
) )
{
v3
=
1
;
/
/
错误
v27
=
1
;
}
input_num
=
input
[v8];
if
( (unsigned
int
)(input_num
-
'0'
) <
=
9
)
/
/
只能输入数字
break
;
v3
=
1
;
/
/
这个数不能等于
1
v27
=
1
;
/
/
这个数也不能等于
1
input_num
=
input
[v8];
if
( (unsigned
int
)(input_num
-
'0'
) <
=
9
)
/
/
只能输入数字
break
;
v3
=
1
;
/
/
这个数不能等于
1
v27
=
1
;
/
/
这个数也不能等于
1
/
/
根据下标和对应的数字,转换出一个
0
-
9
的数
v12
=
(input_num
+
(
0xFFFEC610
>> input_id
%
31
))
%
0xA
;
/
/
奇数位,v12
=
=
0
;偶数位,v12!
=
0
if
( (input_id &
1
) !
=
v12 <
1
)
v27
=
1
;
/
/
将check数组中
5
个
int
做xor,得到
4
字节
=
v28
v28
=
v38 ^ HIDWORD(v37) ^ v37 ^ HIDWORD(v36) ^ v36;
if
( v25 )
/
/
如果是
input
最后一位,就进行校验
{
/
/
v28的 (((bit0 ^ bit2) &
0x1F
)
=
=
0
)
/
/
v28的 (((bit1 ^ bit3) &
0x1F
)
=
=
0
)
if
( ((unsigned __int8)v28 ^ (unsigned __int8)(BYTE2(v38) ^ BYTE6(v37) ^ BYTE2(v37) ^ BYTE6(v36) ^ BYTE2(v36))) &
0x1F
/
/
也就是说这个条件,必须成立
|| (HIBYTE(v28) ^ BYTE1(v28)) &
0x1F
)
{
v13
=
-
1
;
/
/
v13等于
-
1
是成功状态
}
goto LABEL_27;
}
/
/
根据v12取出flag中的
4
字节,分别跟check的
5
个数xor
v17
=
v31[v12];
LODWORD(v36)
=
v17 ^ v36;
/
/
那
20
字节,跟选定的数字xor
HIDWORD(v36) ^
=
v17;
LODWORD(v37)
=
v17 ^ v37;
HIDWORD(v37) ^
=
v17;
/
/
xor后的数据要满足
if
( v12 >
=
6
)
{
if
( ((unsigned __int8)v28 ^ BYTE2(v28)) &
0x1F
)
{
LABEL_26:
v13
=
9
;
/
/
将当前v12重置为
9
goto LABEL_27;
}
v15
=
13
-
v12;
}
else
{
v15
=
8
-
v12;
v16
=
v28;
/
/
=
0
}
if
( (v16 << v15)
+
-
128
=
=
v14 << v15 )
/
/
需要成立
goto LABEL_27;
/
/
根据下标和对应的数字,转换出一个
0
-
9
的数
v12
=
(input_num
+
(
0xFFFEC610
>> input_id
%
31
))
%
0xA
;
/
/
奇数位,v12
=
=
0
;偶数位,v12!
=
0
if
( (input_id &
1
) !
=
v12 <
1
)
v27
=
1
;
/
/
将check数组中
5
个
int
做xor,得到
4
字节
=
v28
v28
=
v38 ^ HIDWORD(v37) ^ v37 ^ HIDWORD(v36) ^ v36;
if
( v25 )
/
/
如果是
input
最后一位,就进行校验
{
/
/
v28的 (((bit0 ^ bit2) &
0x1F
)
=
=
0
)
/
/
v28的 (((bit1 ^ bit3) &
0x1F
)
=
=
0
)
if
( ((unsigned __int8)v28 ^ (unsigned __int8)(BYTE2(v38) ^ BYTE6(v37) ^ BYTE2(v37) ^ BYTE6(v36) ^ BYTE2(v36))) &
0x1F
/
/
也就是说这个条件,必须成立
|| (HIBYTE(v28) ^ BYTE1(v28)) &
0x1F
)
{
v13
=
-
1
;
/
/
v13等于
-
1
是成功状态
}
goto LABEL_27;
}
/
/
根据v12取出flag中的
4
字节,分别跟check的
5
个数xor
v17
=
v31[v12];
LODWORD(v36)
=
v17 ^ v36;
/
/
那
20
字节,跟选定的数字xor
HIDWORD(v36) ^
=
v17;
LODWORD(v37)
=
v17 ^ v37;
HIDWORD(v37) ^
=
v17;
/
/
xor后的数据要满足
if
( v12 >
=
6
)
{
if
( ((unsigned __int8)v28 ^ BYTE2(v28)) &
0x1F
)
{
LABEL_26:
v13
=
9
;
/
/
将当前v12重置为
9
goto LABEL_27;
}
v15
=
13
-
v12;
}
else
{
v15
=
8
-
v12;
v16
=
v28;
/
/
=
0
}
if
( (v16 << v15)
+
-
128
=
=
v14 << v15 )
/
/
需要成立
goto LABEL_27;
/
/
标记
10
层,每层选取的元素是谁
unsigned
int
id08[
10
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
};
/
/
判断数组是否合规
1
=
合规
0
=
错误
int
judge08(unsigned
int
*
flag, unsigned
int
*
check)
{
unsigned
int
final[
5
]
=
{
0
};
for
(
int
i
=
0
; i <
5
; i
+
+
)
final[i]
=
check[i];
for
(
int
i
=
0
; i <
10
; i
+
+
)
/
/
flag用
10
次
{
if
(id08[i]
=
=
-
1
)
/
/
不跟这个数参与xor
continue
;
for
(
int
j
=
0
; j <
5
; j
+
+
)
/
/
check中是
5
个
4
位数
{
final[j] ^
=
flag[i];
}
}
final[
0
]
=
final[
0
] ^ final[
1
] ^ final[
2
] ^ final[
3
] ^ final[
4
];
int
bit0
=
(final[
0
] &
0xFF000000
) >>
24
;
int
bit1
=
(final[
0
] &
0xFF0000
) >>
16
;
int
bit2
=
(final[
0
] &
0xFF00
) >>
8
;
int
bit3
=
final[
0
] &
0xFF
;
printf(
"%x\n"
, final[
0
]);
int
e
=
bit0 ^ bit2;
int
f
=
bit1 ^ bit3;
printf(
"%x %x\n"
, e, f);
if
(((e &
0x1F
)
=
=
0
) && ((f &
0x1F
)
=
=
0
))
{
printf(
"%x %x\n"
, (e &
0x1F
), (f &
0x1F
));
return
1
;
}
return
0
;
}
/
/
depth表示当前层级,一共遍历
39
层
void search08(unsigned
int
*
flag, unsigned
int
*
check,
int
depth)
{
if
(depth
=
=
10
)
{
/
/
printArr(id08,
10
);
if
(judge08(flag, check))
{
printf(
"heihei\n"
);
printArr(id08,
10
);
exit(
0
);
}
return
;
}
for
(
int
i
=
0
; i <
2
; i
+
+
)
{
if
(i
=
=
0
)
id08[depth]
=
1
;
else
id08[depth]
=
-
1
;
search08(flag, check, depth
+
1
);
}
return
;
}
/
/
标记
10
层,每层选取的元素是谁
unsigned
int
id08[
10
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
};
/
/
判断数组是否合规
1
=
合规
0
=
错误
int
judge08(unsigned
int
*
flag, unsigned
int
*
check)
{
unsigned
int
final[
5
]
=
{
0
};
for
(
int
i
=
0
; i <
5
; i
+
+
)
final[i]
=
check[i];
for
(
int
i
=
0
; i <
10
; i
+
+
)
/
/
flag用
10
次
{
if
(id08[i]
=
=
-
1
)
/
/
不跟这个数参与xor
continue
;
for
(
int
j
=
0
; j <
5
; j
+
+
)
/
/
check中是
5
个
4
位数
{
final[j] ^
=
flag[i];
}
}
final[
0
]
=
final[
0
] ^ final[
1
] ^ final[
2
] ^ final[
3
] ^ final[
4
];
int
bit0
=
(final[
0
] &
0xFF000000
) >>
24
;
int
bit1
=
(final[
0
] &
0xFF0000
) >>
16
;
int
bit2
=
(final[
0
] &
0xFF00
) >>
8
;
int
bit3
=
final[
0
] &
0xFF
;
printf(
"%x\n"
, final[
0
]);
int
e
=
bit0 ^ bit2;
int
f
=
bit1 ^ bit3;
printf(
"%x %x\n"
, e, f);
if
(((e &
0x1F
)
=
=
0
) && ((f &
0x1F
)
=
=
0
))
{
printf(
"%x %x\n"
, (e &
0x1F
), (f &
0x1F
));
return
1
;
}
return
0
;
}
/
/
depth表示当前层级,一共遍历
39
层
void search08(unsigned
int
*
flag, unsigned
int
*
check,
int
depth)
{
if
(depth
=
=
10
)
{
/
/
printArr(id08,
10
);
if
(judge08(flag, check))
{
printf(
"heihei\n"
);
printArr(id08,
10
);
exit(
0
);
}
return
;
}
for
(
int
i
=
0
; i <
2
; i
+
+
)
{
if
(i
=
=
0
)
id08[depth]
=
1
;
else
id08[depth]
=
-
1
;
search08(flag, check, depth
+
1
);
}
return
;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
- 2024KCTF_第九题 第一次接触-提交题目 1668
- [原创]KCTF2023 第十二题深入内核 3539
- [原创]KCTF2023 第八题AI核心地带 9831
- [原创]KCTF2023 第六题 至暗时刻 9613
- [原创]KCTF2023 第五题 争分夺秒 8543
看原图
赞赏
雪币:
留言: