7
[原创]KCTF2021 春季赛 第四题 英雄救美 WP
source link: https://bbs.pediy.com/thread-267614.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
[原创]KCTF2021 春季赛 第四题 英雄救美 WP-CTF对抗-看雪论坛-安全社区|安全招聘|bbs.pediy.com
[原创]KCTF2021 春季赛 第四题 英雄救美 WP
3天前
695
main函数伪代码如下:
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
len
;
/
/
kr00_4
int
v4;
/
/
ecx
char
*
v5;
/
/
esi
int
v6;
/
/
edi
void (
*
v8)(void);
/
/
[esp
+
Ch] [ebp
-
2CCh
]
int
v9[
22
];
/
/
[esp
+
10h
] [ebp
-
2C8h
] BYREF
int
solve[
128
];
/
/
[esp
+
68h
] [ebp
-
270h
] BYREF
__int128 v11;
/
/
[esp
+
268h
] [ebp
-
70h
] BYREF
char serial[
92
];
/
/
[esp
+
278h
] [ebp
-
60h
] BYREF
printf(
"\t\t\t看雪CTF大赛\r\n"
);
printf(
"\t\t祝愿看雪CTF大赛越办越好\r\n"
);
printf(
"Serial: "
);
scanf_s(
"%s"
, serial);
len
=
strlen(serial);
/
/
先检查序列号是否合法,检测合法则转换成数独的解,然后开始填数独
if
(
len
<
=
64
&& serial2solve(
len
, serial, solve)
=
=
1
&& sudoku((
int
)solve,
len
-
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
)serial, (
int
)v9,
len
);
/
/
计算serial的
hash
,解密shellcode
sub_4015B0((
int
)&v11, (
int
)v9);
sub_401ED0(v4, (unsigned __int8
*
)&v11);
v8
=
(void (
*
)(void))VirtualAlloc(
0
,
0x620u
,
0x1000u
,
0x40u
);
v5
=
(char
*
)v8;
v6
=
98
;
do
{
*
(__m128i
*
)v5
=
_mm_loadu_si128((const __m128i
*
)&v5[&unk_4181A0
-
(_UNKNOWN
*
)v8]);
sub_4028B0((
int
)solve, v5);
v5
+
=
16
;
-
-
v6;
}
while
( v6 );
v8();
}
return
0
;
}
从sudoku函数内可以提取到数独
0
,
4
,
0
,
7
,
0
,
0
,
0
,
0
,
0
9
,
2
,
0
,
0
,
0
,
0
,
6
,
0
,
7
8
,
3
,
0
,
0
,
0
,
5
,
4
,
0
,
0
0
,
1
,
0
,
0
,
0
,
3
,
0
,
0
,
0
0
,
0
,
0
,
2
,
0
,
1
,
0
,
0
,
0
0
,
0
,
0
,
5
,
0
,
0
,
0
,
4
,
0
0
,
0
,
4
,
9
,
0
,
0
,
0
,
7
,
1
3
,
0
,
5
,
0
,
0
,
0
,
0
,
9
,
4
0
,
0
,
0
,
0
,
0
,
8
,
0
,
6
,
0
/
/
懒得解(不会解)数独,直接求助度娘解出来
5
,
4
,
6
,
7
,
1
,
9
,
2
,
3
,
8
9
,
2
,
1
,
8
,
3
,
4
,
6
,
5
,
7
8
,
3
,
7
,
6
,
2
,
5
,
4
,
1
,
9
7
,
1
,
8
,
4
,
6
,
3
,
9
,
2
,
5
4
,
5
,
3
,
2
,
9
,
1
,
7
,
8
,
6
6
,
9
,
2
,
5
,
8
,
7
,
1
,
4
,
3
2
,
8
,
4
,
9
,
5
,
6
,
3
,
7
,
1
3
,
6
,
5
,
1
,
7
,
2
,
8
,
9
,
4
1
,
7
,
9
,
3
,
4
,
8
,
5
,
6
,
2
sudoku函数只在数值为0处填充解,所以把0处的解提取出来
[(5, 6, 1, 9, 2, 3, 8), (1, 8, 3, 4, 5), (7, 6, 2, 1, 9), (7, 8, 4, 6, 9, 2, 5), (4, 5, 3, 9, 7, 8, 6), (6, 9, 2, 8, 7, 1, 3), (2, 8, 5, 6, 3), (6, 1, 7, 2, 8), (1, 7, 9, 3, 4, 5, 2)]
再看serial2solve函数
int
__usercall serial2solve@<eax>(
int
len
@<edx>, char
*
serial@<ecx>,
int
*
solve)
{
int
decnum;
/
/
ebx
int
v4;
/
/
esi
unsigned
int
y;
/
/
edi
char
chr
;
/
/
al
signed
int
v7;
/
/
ecx
int
v9;
/
/
ecx
char
*
v10;
/
/
[esp
+
0h
] [ebp
-
64h
]
int
v11;
/
/
[esp
+
4h
] [ebp
-
60h
]
__int128 strtable[
5
];
/
/
[esp
+
Ch] [ebp
-
58h
]
char v14;
/
/
[esp
+
5Ch
] [ebp
-
8h
]
strtable[
0
]
=
(__int128)_mm_load_si128((const __m128i
*
)&xmmword_416280);
decnum
=
0
;
strtable[
1
]
=
(__int128)_mm_load_si128((const __m128i
*
)&xmmword_4162A0);
v4
=
0
;
v11
=
len
;
v10
=
serial;
v14
=
113
;
strtable[
2
]
=
(__int128)_mm_load_si128((const __m128i
*
)&xmmword_416270);
strtable[
3
]
=
(__int128)_mm_load_si128((const __m128i
*
)&xmmword_416290);
strtable[
4
]
=
(__int128)_mm_load_si128((const __m128i
*
)&xmmword_416260);
if
(
len
<
=
0
)
return
1
;
y
=
0
;
while
(
1
)
{
chr
=
serial[v4];
if
(
chr
>
'0'
&&
chr
<
=
'9'
)
break
;
v7
=
y;
/
/
可以当成strtable的纵坐标
if
( y >
=
81
)
return
0
;
while
(
chr
!
=
*
((_BYTE
*
)strtable
+
v7) )
{
if
( (unsigned
int
)
+
+
v7 >
=
81
)
return
0
;
}
v9
=
v7
%
9
+
1
;
/
/
将strtable的横坐标
+
1
,写到数独的解
if
( v9
=
=
-
1
)
return
0
;
*
solve
=
v9;
serial
=
v10;
+
+
decnum;
+
+
solve;
len
=
v11;
LABEL_13:
if
(
+
+
v4 >
=
len
)
return
1
;
}
if
( decnum
+
chr
=
=
'9'
)
/
/
猜测serial每填满一行数独后就跟一位数字表示没填到的数独的个数
{
decnum
=
0
;
y
+
=
9
;
goto LABEL_13;
}
return
-
1
;
}
清楚序列号转数独解的过程后,撸一份python解出flag即可
resultarr
=
[(
5
,
6
,
1
,
9
,
2
,
3
,
8
), (
1
,
8
,
3
,
4
,
5
), (
7
,
6
,
2
,
1
,
9
), (
7
,
8
,
4
,
6
,
9
,
2
,
5
), (
4
,
5
,
3
,
9
,
7
,
8
,
6
), (
6
,
9
,
2
,
8
,
7
,
1
,
3
), (
2
,
8
,
5
,
6
,
3
), (
6
,
1
,
7
,
2
,
8
), (
1
,
7
,
9
,
3
,
4
,
5
,
2
)]
table
=
"""$BPV:ubfYp}]DtN>aT^MGmJQ#*Hr`O'wjic0!hdy{oZz-@n+?&%s_/g<e[W)XUxRFSLRA;.l=CEkvK-(q"""
flag
=
''
for
i
in
range
(
len
(resultarr)):
for
j
in
range
(
len
(resultarr[i])):
flag
+
=
table[
9
*
i
+
resultarr[i][j]
-
1
]
if
len
(resultarr[i])
-
1
=
=
j:
flag
+
=
chr
(
0x39
-
j
-
1
)
print
(flag)
运行得到flag(下面整行都是)
:u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2
吐槽:目前的flag都不是KCTF{}格式
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK