-
-
[原创]2021 KCTF 春季赛 第四题 英雄救美 wp
-
发表于: 2021-5-14 18:50 5715
-
windows32位控制台程序.
输入错误时没有回显.
输入成功的提示是段shellcode, 使用VirtualAlloc分配地址解密shellcode再执行.
观察验证逻辑, 不难发现是个9*9的经典数独游戏.
ida F5, main函数逻辑如下:
输入完serial后, 要执行成功的回显, 必须要满足三个条件:
1.输入length不大于64
2.fun_convert_input(sub_401240)验证通过
3.fun_check_game(sub_401000)验证通过
分析fun_convert_input和fun_check_game两个函数的逻辑.
将输入的serial每个字符进行转换.
遇到非数字字符, 查表的第n行(n从1开始)转换对应下标.
遇到数字字符, 验证这行转换了的下标个数加上数字字符是不是等于'9'(满足数独一行有9个数字), 并且切换查表的下一行(n++).
把转换好的下标(1~9数字)填入游戏格子内.
验证数独是否成立(每行每列每个九宫格都是数字1~9).
先到网页上在线解数独:链接
每行需要填的数字为:
根据fun_convert_input里的字符表进行转换:
每行最后加上数字(9-要填写的数字个数), 最后得到:
:u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2
验证通过!
拿到flag后处于好奇瞅了一眼成功提示的MessageBox代码, 和之前猜测的一样, 是段shellcode.
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
nLen;
/
/
kr00_4
int
v4;
/
/
ecx
__m128i
*
v5;
/
/
esi
int
v6;
/
/
edi
void (
*
v8)(void);
/
/
[esp
+
10h
] [ebp
-
2C8h
]
int
v9[
22
];
/
/
[esp
+
14h
] [ebp
-
2C4h
] BYREF
char v10[
508
];
/
/
[esp
+
6Ch
] [ebp
-
26Ch
] BYREF
__int128 v11;
/
/
[esp
+
26Ch
] [ebp
-
6Ch
] BYREF
char v12[
88
];
/
/
[esp
+
27Ch
] [ebp
-
5Ch
] BYREF
printf(
"\t\t\t看雪CTF大赛\r\n"
);
printf(
"\t\t祝愿看雪CTF大赛越办越好\r\n"
);
printf(
"Serial: "
);
scanf_s(
"%s"
, (char
*
)&v11
+
12
);
nLen
=
strlen((const char
*
)&v11
+
12
);
if
( nLen <
=
64
&& fun_convert_input((
int
)&v11
+
12
, nLen, &v9[
21
])
=
=
1
&& fun_check_game((
int
)v10, nLen
-
9
)
=
=
1
)
{
v11
=
0i64
;
memset(v9,
0
, sizeof(v9));
v9[
5
]
=
0
;
v9[
4
]
=
0
;
v9[
0
]
=
0x67452301
;
v9[
1
]
=
0xEFCDAB89
;
v9[
2
]
=
0x98BADCFE
;
v9[
3
]
=
0x10325476
;
sub_4014E0((
int
)v12, (
int
)v9, nLen);
sub_4015B0((
int
)&v11, (
int
)v9);
sub_401ED0(v4, (unsigned __int8
*
)&v11);
v8
=
(void (
*
)(void))VirtualAlloc(
0
,
0x620u
,
0x1000u
,
0x40u
);
v5
=
(__m128i
*
)v8;
v6
=
0x62
;
do
{
*
v5
=
_mm_loadu_si128((__m128i
*
)((char
*
)v5
+
&sub_4181A0
-
(_UNKNOWN
*
)v8));
((void (__fastcall
*
)(char
*
, __m128i
*
))loc_4028B0)(v10, v5
+
+
);
-
-
v6;
}
while
( v6 );
v8();
}
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
nLen;
/
/
kr00_4
int
v4;
/
/
ecx
__m128i
*
v5;
/
/
esi
int
v6;
/
/
edi
void (
*
v8)(void);
/
/
[esp
+
10h
] [ebp
-
2C8h
]
int
v9[
22
];
/
/
[esp
+
14h
] [ebp
-
2C4h
] BYREF
char v10[
508
];
/
/
[esp
+
6Ch
] [ebp
-
26Ch
] BYREF
__int128 v11;
/
/
[esp
+
26Ch
] [ebp
-
6Ch
] BYREF
char v12[
88
];
/
/
[esp
+
27Ch
] [ebp
-
5Ch
] BYREF
printf(
"\t\t\t看雪CTF大赛\r\n"
);
printf(
"\t\t祝愿看雪CTF大赛越办越好\r\n"
);
printf(
"Serial: "
);
scanf_s(
"%s"
, (char
*
)&v11
+
12
);
nLen
=
strlen((const char
*
)&v11
+
12
);
if
( nLen <
=
64
&& fun_convert_input((
int
)&v11
+
12
, nLen, &v9[
21
])
=
=
1
&& fun_check_game((
int
)v10, nLen
-
9
)
=
=
1
)
{
v11
=
0i64
;
memset(v9,
0
, sizeof(v9));
v9[
5
]
=
0
;
v9[
4
]
=
0
;
v9[
0
]
=
0x67452301
;
v9[
1
]
=
0xEFCDAB89
;
v9[
2
]
=
0x98BADCFE
;
v9[
3
]
=
0x10325476
;
sub_4014E0((
int
)v12, (
int
)v9, nLen);
sub_4015B0((
int
)&v11, (
int
)v9);
sub_401ED0(v4, (unsigned __int8
*
)&v11);
v8
=
(void (
*
)(void))VirtualAlloc(
0
,
0x620u
,
0x1000u
,
0x40u
);
v5
=
(__m128i
*
)v8;
v6
=
0x62
;
do
{
*
v5
=
_mm_loadu_si128((__m128i
*
)((char
*
)v5
+
&sub_4181A0
-
(_UNKNOWN
*
)v8));
((void (__fastcall
*
)(char
*
, __m128i
*
))loc_4028B0)(v10, v5
+
+
);
-
-
v6;
}
while
( v6 );
v8();
}
return
0
;
}
$BPV:ubfY
p}]DtN>aT
^MGmJQ
#*H
r`O'wjic0
!hdy{oZz
-
@n
+
?&
%
s_
/
g<e[W)XUx
RFSLRA;.l
=
CEkvK
-
(q
$BPV:ubfY
p}]DtN>aT
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: