-
-
[原创]KCTF 第二题 末日邀请 暴力解题
-
发表于: 2022-5-11 21:36 5832
-
分析完代码后,可以通过第二关得到字符串为 ???KCTF??????????
分析第四关,可以知道后面接的CTF字符串肯定是 1234567890等,因为会排序,那么可能是以下几种
1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890
通过动态调试可以知道如果是1234[\x0\x0]这种会被第三关干扰从而生成别的字符串,不符合逻辑,那么大胆猜测就是1-9的字符串
通过第一关可以快速遍历得到所有 前三个字符
如下:
然后我就目测了一下,感觉那个 Hi[
很像, 然后就走入了误区
合在一起是 Hi[KCTF]1-8
, 然后就越走越远了,最后才发现可能是其他的字符+KCTF+1-9
写下如下代码,进行尝试性破解
思路就是遍历所有三个字符符合条件的来匹配,因为实在不知道哪三个字符符合条件,包括后面的判断也没有看出来,只能盲猜所有可能,之前误判为Hi[
走错了后,改进为所有可能。
进行第五关的校验,就是所有的字符串参与计算,分拆前面7个字符先初始化得到值。
然后就是1-9的排列组合,直接生成所有排列可能,然后参与计算对比得到结果,结果如下:
带入到程序中, 421KCTF381654729
, 验证通过。
补一个sbox
表格
char first(unsigned char
*
str
,
int
len
)
{
char tmp
=
0
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
tmp ^
=
str
[i];
for
(
int
j
=
0
; j <
8
; j
+
+
)
{
char v9
=
2
*
tmp;
tmp
=
v9 >
=
0
? v9 : (v9 ^
7
);
}
}
return
tmp;
}
void second(char v,
int
out[
200
])
{
unsigned char v15
=
v;
for
(
int
i
=
1
; i <
200
; i
+
+
)
{
if
((v15 &
1
) !
=
0
)
v15
=
3
*
v15
+
1
;
else
v15 >>
=
1
;
out[i]
=
v15;
printf(
"%.2x "
, v15);
if
((i
+
1
)
%
0x10
=
=
0
)
printf(
"\r\n"
);
}
printf(
"\r\n"
);
}
unsigned char to_hex(unsigned char a)
{
return
(a >
=
0x3a
) ? (a
-
0x37
) : (a
-
0x30
);
}
int
sub_4010B7(unsigned char
*
str
,
int
len
)
{
for
(
int
i
=
0
; i <
len
;
+
+
i)
{
str
[i]
=
to_hex(
str
[i]);
}
return
0
;
}
int
ctf_1(unsigned char
*
ctf,
int
len
)
{
int
tmp
=
0
;
int
tk
=
1
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
int
v23
=
ctf[i]
+
tmp
*
10
;
int
v24
=
v23
-
0x37373737
;
if
(v23 <
=
0x4b435445
)
v24
=
v23;
tmp
=
v24;
if
(v24
%
tk
+
+
)
return
-
1
;
}
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
/
/
/
取字符串
sub_40103A(
"%s"
, (char)
str
);
/
/
/
异或处理
int
len
=
strlen(
str
);
char a
=
first(
str
,
len
);
/
/
/
初始化sbox, 直接拷贝即可
sub_40106C();
/
/
/
哈希计算
int
v
=
-
1
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
v
=
((unsigned
int
*
)sbox)[(unsigned char)(v ^ s[i])] ^ (v >>
8
);
}
/
/
/
must be
0xf52e0765
v ~
=
v;
/
/
/
字符转换
hex
?
sub_4010B7(
str
,
len
);
/
/
/
第一关,其值为
0x07
char tbox[
200
]
=
{
0
};
second(a, tbox);
/
/
/
观察tbox的结果, tbox[
198
] | tbox[
197
] | tbpx[
196
] 为
0x07
/
/
/
注意:有符号的情况下不能通过第一关,可以修改
0x12A7
edi
=
=
0x07
, 后面会用到
char k
=
str
[
0
] ^
str
[
1
] ^
str
[
2
];
if
(k !
=
0x07
) failed(
-
1
);
/
/
/
第二关 {
3
-
5
}
-
>
'KCTF'
if
(
str
[
3
] !
=
0x14
||
str
[
4
] !
=
0xc
||
str
[
5
] !
=
0x1d
||
str
[
6
] !
=
0x0f
)
failed(
-
1
);
/
/
/
第三关 {未解}
/
/
/
0x13E4
-
> nop
*
6
ctf
=
&
str
[
7
];
if
(ctf_1(ctf, strlen(ctf)!
=
0
)
failed(
-
1
);
/
/
/
第四关
/
/
/
1
-
排序 从低到高
sort(ctf, strlen(ctf));
/
/
/
2
-
比较字符串
char
cmp
[]
=
'1234567890_A...'
;
sub_4010B7(
cmp
,
10
);
/
/
/
3
-
比较ctf
if
(strncmp(ctf,
cmp
, strlen(ctf)))
failed(
-
1
);
/
/
/
第五关
if
(v!
=
0xF52E0765
)
failed(
-
1
);
return
ok();
}
char first(unsigned char
*
str
,
int
len
)
{
char tmp
=
0
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
tmp ^
=
str
[i];
for
(
int
j
=
0
; j <
8
; j
+
+
)
{
char v9
=
2
*
tmp;
tmp
=
v9 >
=
0
? v9 : (v9 ^
7
);
}
}
return
tmp;
}
void second(char v,
int
out[
200
])
{
unsigned char v15
=
v;
for
(
int
i
=
1
; i <
200
; i
+
+
)
{
if
((v15 &
1
) !
=
0
)
v15
=
3
*
v15
+
1
;
else
v15 >>
=
1
;
out[i]
=
v15;
printf(
"%.2x "
, v15);
if
((i
+
1
)
%
0x10
=
=
0
)
printf(
"\r\n"
);
}
printf(
"\r\n"
);
}
unsigned char to_hex(unsigned char a)
{
return
(a >
=
0x3a
) ? (a
-
0x37
) : (a
-
0x30
);
}
int
sub_4010B7(unsigned char
*
str
,
int
len
)
{
for
(
int
i
=
0
; i <
len
;
+
+
i)
{
str
[i]
=
to_hex(
str
[i]);
}
return
0
;
}
int
ctf_1(unsigned char
*
ctf,
int
len
)
{
int
tmp
=
0
;
int
tk
=
1
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
int
v23
=
ctf[i]
+
tmp
*
10
;
int
v24
=
v23
-
0x37373737
;
if
(v23 <
=
0x4b435445
)
v24
=
v23;
tmp
=
v24;
if
(v24
%
tk
+
+
)
return
-
1
;
}
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
/
/
/
取字符串
sub_40103A(
"%s"
, (char)
str
);
/
/
/
异或处理
int
len
=
strlen(
str
);
char a
=
first(
str
,
len
);
/
/
/
初始化sbox, 直接拷贝即可
sub_40106C();
/
/
/
哈希计算
int
v
=
-
1
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
v
=
((unsigned
int
*
)sbox)[(unsigned char)(v ^ s[i])] ^ (v >>
8
);
}
/
/
/
must be
0xf52e0765
v ~
=
v;
/
/
/
字符转换
hex
?
sub_4010B7(
str
,
len
);
/
/
/
第一关,其值为
0x07
char tbox[
200
]
=
{
0
};
second(a, tbox);
/
/
/
观察tbox的结果, tbox[
198
] | tbox[
197
] | tbpx[
196
] 为
0x07
/
/
/
注意:有符号的情况下不能通过第一关,可以修改
0x12A7
edi
=
=
0x07
, 后面会用到
char k
=
str
[
0
] ^
str
[
1
] ^
str
[
2
];
if
(k !
=
0x07
) failed(
-
1
);
/
/
/
第二关 {
3
-
5
}
-
>
'KCTF'
if
(
str
[
3
] !
=
0x14
||
str
[
4
] !
=
0xc
||
str
[
5
] !
=
0x1d
||
str
[
6
] !
=
0x0f
)
failed(
-
1
);
/
/
/
第三关 {未解}
/
/
/
0x13E4
-
> nop
*
6
ctf
=
&
str
[
7
];
if
(ctf_1(ctf, strlen(ctf)!
=
0
)
failed(
-
1
);
/
/
/
第四关
/
/
/
1
-
排序 从低到高
sort(ctf, strlen(ctf));
/
/
/
2
-
比较字符串
char
cmp
[]
=
'1234567890_A...'
;
sub_4010B7(
cmp
,
10
);
/
/
/
3
-
比较ctf
if
(strncmp(ctf,
cmp
, strlen(ctf)))
failed(
-
1
);
/
/
/
第五关
if
(v!
=
0xF52E0765
)
failed(
-
1
);
return
ok();
}
unsigned char st
=
0x20
;
unsigned char se
=
0x7f
;
for
(unsigned char x
=
st; x <
=
se; x
+
+
)
{
for
(unsigned char y
=
st; y <
=
se; y
+
+
)
{
for
(unsigned char z
=
st; z <
=
se; z
+
+
)
{
if
((to_hex(x) ^ to_hex(y) ^ to_hex(z))
=
=
0x07
)
{
printf(
"%c%c%c\n"
, x, y, z);
}
}
}
}
unsigned char st
=
0x20
;
unsigned char se
=
0x7f
;
for
(unsigned char x
=
st; x <
=
se; x
+
+
)
{
for
(unsigned char y
=
st; y <
=
se; y
+
+
)
{
for
(unsigned char z
=
st; z <
=
se; z
+
+
)
{
if
((to_hex(x) ^ to_hex(y) ^ to_hex(z))
=
=
0x07
)
{
printf(
"%c%c%c\n"
, x, y, z);
}
}
}
}
#include <iostream>
#include <algorithm>
unsigned char st
=
0x20
;
unsigned char se
=
0x7f
;
unsigned char buf[
9
]
=
{
0
};
memcpy(&buf[
3
],
"KCTF"
,
4
);
for
(unsigned char x
=
st; x <
=
se; x
+
+
)
{
for
(unsigned char y
=
st; y <
=
se; y
+
+
)
{
for
(unsigned char z
=
st; z <
=
se; z
+
+
)
{
if
((to_hex(x) ^ to_hex(y) ^ to_hex(z))
=
=
0x07
)
{
buf[
0
]
=
x;
buf[
1
]
=
y;
buf[
2
]
=
z;
int
v
=
get_ctf((char
*
)buf,
7
);
check(v, (char
*
)buf);
}
}
}
}
int
get_ctf(char
*
s,
int
len
)
{
int
v
=
-
1
;
for
(
int
i
=
0
; i <
len
; i
+
+
)
{
v
=
((unsigned
int
*
)sbox)[(unsigned char)(v ^ s[i])] ^ (v >>
8
);
}
return
v;
}
void check(
int
v, char
*
s)
{
char arr[]
=
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'0'
};
char arr2[sizeof(arr)]
=
{
0
};
for
(
int
i
=
1
; i < sizeof(arr); i
+
+
)
{
arr2[i]
=
0
;
memcpy(arr2, arr, i);
do {
if
(check_ctf2(arr2, i, v)) {
printf(
"found: \n"
);
printf(
"%s\n"
, s);
print_hex((unsigned char
*
)arr2, i);
printf(
"%s\n"
, arr2);
}
}
while
(std::next_permutation(arr2, arr2
+
i));
}
}
#include <iostream>
#include <algorithm>
赞赏
他的文章
看原图
赞赏
雪币:
留言: