1
2
3
4
5
6
7
|
if
( input_len !
=
156
)
/
/
输入长度
156
{
LABEL_16:
v12
=
fun_printf(std::cout,
"fail"
);
std::basic_ostream<char,std::char_traits<char>>::operator<<(v12, sub_1400030E0);
goto LABEL_233;
}
|
1
2
3
4
5
6
7
|
v20
=
errno();
v21
=
v20;
v22
=
(const char
*
)&
Str
;
if
( v149 >
=
0x10
)
v22
=
Str
;
*
v20
=
0
;
n4First
=
strtol(v22, &EndPtr,
10
);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
if
( !MaxCount || (v27
=
memchr(v24,
'2'
, MaxCount))
=
=
0i64
|| v27
-
(_BYTE
*
)v24
=
=
-
1
)
{
v28
=
errno();
v29
=
v28;
v30
=
(const char
*
)&
Str
;
if
( v149 >
=
0x10
)
v30
=
Str
;
*
v28
=
0
;
v31
=
strtol(v30, &v146,
2
);
/
/
if
( v30
=
=
v146 )
goto LABEL_245;
if
(
*
v29
=
=
34
)
{
std::_Xout_of_range(
"stoi argument out of range"
);
__debugbreak();
LABEL_245:
std::_Xinvalid_argument(
"invalid stoi argument"
);
__debugbreak();
LABEL_246:
std::_Xout_of_range(
"stoi argument out of range"
);
__debugbreak();
LABEL_247:
std::_Xinvalid_argument(
"invalid stoi argument"
);
__debugbreak();
LABEL_248:
sub_1400012C0(
0x80004005
);
}
if
( v31
=
=
15
)
{
v126
=
fun_printf(std::cout,
"Fail"
);
std::basic_ostream<char,std::char_traits<char>>::operator<<(v126, sub_1400030E0);
goto LABEL_228;
}
v26
=
v149;
v25
=
Str
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
v41
=
memchr(str4First_1,
'2'
, MaxCount);
/
/
又查找
2
。。。
if
( v41 )
{
if
( v41
-
(_BYTE
*
)str4First_1 !
=
-
1
)
{
v42
=
0
;
v43
=
0
;
v44
=
*
((signed
int
*
)Unicode4First
-
4
);
LODWORD(v45)
=
0
;
if
( (signed
int
)v44 <
=
0
)
{
v13
=
v134;
}
else
{
do
{
v46
=
(signed
int
)v45;
if
( Unicode4First[v46]
=
=
'2'
)
{
if
( !v43 )
{
v43
=
1
;
if
( ((
1
-
*
((_DWORD
*
)Unicode4First
-
2
)) | (
*
((_DWORD
*
)Unicode4First
-
3
)
-
(signed
int
)v44)) <
0
)
{
sub_140002D70(&v150, v44);
Unicode4First
=
v150;
}
}
Unicode4First[v46]
=
'1'
;
+
+
v42;
}
v45
=
(v46
*
2
+
2
) >>
1
;
}
while
( (signed
int
)v45 < (signed
int
)v44 );
n4First
=
v138;
if
( v43 )
{
if
( (signed
int
)v44 >
*
((_DWORD
*
)Unicode4First
-
3
) )
sub_1400012C0(
0x80070057
);
*
((_DWORD
*
)Unicode4First
-
4
)
=
v44;
Unicode4First[v44]
=
0
;
}
if
( v42
=
=
4
)
{
v62
=
fun_printf(std::cout,
"Fail"
);
std::basic_ostream<char,std::char_traits<char>>::operator<<(v62, sub_1400030E0);
goto LABEL_225;
}
v13
=
v134;
}
}
|
1
2
|
if
( n4First <
=
n4FirstLast )
break
;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
if
(
+
+
v0 >
=
39
)
/
/
v0进来是
0
,所以说实质上,是遍历
39
轮,每轮处理
4
字节
{
v57
=
0
;
if
( input_len_1 )
{
v58
=
0i64
;
do
{
v59
=
v57
/
39
;
/
/
0
1
2
3
v60
=
v57
%
39
;
/
/
0
1
2
...
38
v61
=
input_2;
if
( v153 >
=
0x10
)
v61
=
(void
*
*
)input_2[
0
];
switch (
*
((_BYTE
*
)v61
+
v58) )
{
case
0x30
:
*
(_DWORD
*
)(
*
(_QWORD
*
)(qword_1400098A8
+
8i64
*
v59)
+
4i64
*
v60)
=
0
;
break
;
case
0x31
:
*
(_DWORD
*
)(
*
(_QWORD
*
)(qword_1400098A8
+
8i64
*
v59)
+
4i64
*
v60)
=
1
;
break
;
case
0x32
:
*
(_DWORD
*
)(
*
(_QWORD
*
)(qword_1400098A8
+
8i64
*
v59)
+
4i64
*
v60)
=
-
1
;
break
;
default:
goto LABEL_16;
}
+
+
v57;
+
+
v58;
}
while
( v57 < input_len_1 );
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
if
( v65
=
=
v66 )
/
/
他们俩为啥都是
0
呢
{
*
*
(_DWORD
*
*
)(v64
+
qword_1400098B8)
=
0
;
}
else
{
v96
=
-
1
;
if
( v65 < v66 )
v96
=
1
;
*
*
(_DWORD
*
*
)(v64
+
qword_1400098B8)
=
v96;
}
if
( v67 )
/
/
这里还是要求每行
1
和
2
的数量相等
goto LABEL_16;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
v139
=
0
;
/
/
直接从这里开始分析!
v108
=
0i64
;
v144
=
0i64
;
v140
=
0x67452301
;
v141
=
0xEFCDAB89
;
v142
=
0x98BADCFE
;
v143
=
0x10325476
;
v109
=
(char
*
)input_2;
if
( v153 >
=
0x10
)
/
/
0x9F
v109
=
(char
*
)input_2[
0
];
fun_md5init((__int64)&v139, v109, input_len_1);
plain_md5
=
fun_md5update((__int64)&v139);
.
.
.
v121
=
*
(_QWORD
*
)v136 !
=
32i64
|| memcmp(v118,
"aac82b7ad77ab00dcef90ac079c9490d"
,
0x20ui64
);
|
然后就是写脚本瞎跑,1天也没跑出来。然后看到网页里有提示。。
[作者提示:序列号转换后的数值数组:
1、列向量组里不存在相反值,如[1,-1,1,0]与[-1,1,-1,0]不能同时存在
2、每个行向量里的 0 的数量 占 1/3
2023/9/3 20:55
]
根据提示重新写脚本跑数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/
/
标记
39
层,每层选取的元素是谁
unsigned
int
id02[
39
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
};
/
/
判断差值是否合规
1
=
合规
0
=
错误
int
judge(
int
value)
{
int
precision
=
9
;
if
((value <
0
) && (
0
-
value > precision))
return
0
;
if
((value >
0
) && (value > precision))
return
0
;
return
1
;
}
/
/
depth表示当前层级,一共遍历
39
层
void search02(unsigned
int
*
arr,
int
depth,
int
qian,
int
bai,
int
shi,
int
ge)
{
if
(depth
=
=
39
)
{
if
(qian
=
=
0
&& bai
=
=
0
&& shi
=
=
0
&& ge
=
=
0
)
{
unsigned
int
final39[
39
]
=
{
0
};
for
(
int
i
=
0
; i <
39
; i
+
+
)
final39[i]
=
*
(arr
+
2
*
i
+
id02[i]);
/
/
获取当前数值
Bubble_sort(final39,
39
);
/
/
对final39数组排序
/
/
构造
156
位字符串,计算md5
unsigned char
*
input
=
(unsigned char
*
)malloc(
4
*
39
+
1
);
memset(
input
,
'0'
,
4
*
39
);
input
[
4
*
39
]
=
0
;
for
(
int
i
=
0
; i <
39
; i
+
+
)
{
int
value
=
final39[i];
/
/
从对元素中取一个
int
bit0
=
value
/
1000
;
/
/
千位 第一行
int
bit1
=
value
%
1000
/
100
;
/
/
百位 第二行
int
bit2
=
value
%
100
/
10
;
/
/
int
bit3
=
value
%
10
;
input
[i]
=
bit0
+
'0'
;
input
[i
+
39
]
=
bit1
+
'0'
;
input
[i
+
39
*
2
]
=
bit2
+
'0'
;
input
[i
+
39
*
3
]
=
bit3
+
'0'
;
}
char
*
res
=
getMd5(
input
);
if
(strcmp(res,
"aac82b7ad77ab00dcef90ac079c9490d"
)
=
=
0
)
{
printf(
"%s\n"
,
input
);
printf(
"%s\n"
, res);
free(
input
);
free(res);
exit(
0
);
}
free(
input
);
free(res);
}
}
for
(
int
i
=
0
; i <
2
; i
+
+
)
{
int
value
=
*
(arr
+
2
*
depth
+
i);
/
/
从对元素中取一个
int
bit0
=
value
/
1000
;
/
/
千位 第一行
int
bit1
=
value
%
1000
/
100
;
/
/
百位 第二行
int
bit2
=
value
%
100
/
10
;
/
/
int
bit3
=
value
%
10
;
if
(bit0
=
=
2
) bit0
=
-
1
;
if
(bit1
=
=
2
) bit1
=
-
1
;
if
(bit2
=
=
2
) bit2
=
-
1
;
if
(bit3
=
=
2
) bit3
=
-
1
;
if
(judge(qian
+
bit0) && judge(bai
+
bit1) && judge(shi
+
bit2) && judge(ge
+
bit3))
{
id02[depth]
=
i;
search02(arr, depth
+
1
, qian
+
bit0, bai
+
bit1, shi
+
bit2, ge
+
bit3);
id02[depth]
=
-
1
;
}
}
return
;
}
void ctf02()
{
/
/
准备对立数组
unsigned
int
arr[
39
][
2
]
=
{
{
1
,
2
},{
10
,
20
},{
11
,
22
},{
12
,
21
},{
100
,
200
},{
101
,
202
},{
102
,
201
},{
110
,
220
},{
111
,
222
},{
112
,
221
},
{
120
,
210
},{
121
,
212
},{
122
,
211
},{
1000
,
2000
},{
1001
,
2002
},{
1002
,
2001
},{
1010
,
2020
},{
1011
,
2022
},{
1012
,
2021
},{
1020
,
2010
},
{
1021
,
2012
},{
1022
,
2011
},{
1100
,
2200
},{
1101
,
2202
},{
1102
,
2201
},{
1110
,
2220
},{
1112
,
2221
},{
1120
,
2210
},{
1121
,
2212
},{
1122
,
2211
},
{
1200
,
2100
},{
1201
,
2102
},{
1202
,
2101
},{
1210
,
2120
},{
1211
,
2122
},{
1212
,
2121
},{
1220
,
2110
},{
1221
,
2112
},{
1222
,
2111
}
};
search02((unsigned
int
*
)arr,
0
,
0
,
0
,
0
,
0
);
}
|
更多【KCTF2023第二题 CN星际基地】相关视频教程:www.yxfzedu.com