-
-
[分享]2021 MAR DASCTF RE题解
-
发表于: 2021-4-7 08:58 5020
-
这次比赛, 没有向以前一样爆零了,就很舒服
赛后官方提供了复盘,就用 复盘一下,写一下wp
主函数逻辑
去花指令
明显的一个 tea 加密
密钥在main 函数里面
flag{fake_flag!}get out!
解密代码
有点坑, 当使用魔数 0x61C88647 时, 解密的初始化数值必须是 0xC6EF3720
de4dot 反混淆后,base64 变表解密,得到key, 再修改代码,输入key 即可得到flag
将所有等待时间删掉
getflag
是一个 hook ,将 IsDebugParent 执行流程替换, 再里面将 最后的比较进行了替换, 有一层很复杂的东西, 手撕不动(指我自己) , 哭了,我怎么这么菜
main 函数
代码简洁,易懂
最后替换的函数,也是解题的关键
参考这位师傅 replace 解法: https://www.cnblogs.com/c10udlnk/p/14606861.html
师傅们tql
变形栅栏 + 盒子变换
最后 md5 提交
这题,比赛的时候,上面的盒子变换都给我看傻了, 下面的栅栏直接给我干死,然后直接放弃这一题, 看师傅们随随便便解出来,我真的感觉自己是个废物
这题预期解是 开发扫雷外挂,并在几秒钟内解出来。 然后我也看不懂里面的代码,连异常咋触发的都看不懂, 哭了。靠着师傅们的wp, 勉强维持生活。
最后在出题人师傅不留余力的帮助下,完成了 扫雷外挂的开发, 太难了
使用工具:
这里面出题人师傅关闭了 aslr , 所以基地址是直接固定的, 格子的大小是 16 * 16 ,sendmessage 点击是呈比例的, 和缩放与布局有关, 其他的也没啥, 具体参考:
https://www.xuenixiang.com/thread-2989-1-1.html
完整代码
getflag
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
HANDLE v3;
/
/
eax
void
*
v4;
/
/
esi
int
result;
/
/
eax
DWORD v6;
/
/
edi
char
*
v7;
/
/
esi
DWORD v8;
/
/
ebx
HANDLE v9;
/
/
eax
void
*
v10;
/
/
esi
DWORD NumberOfBytesRead;
/
/
[esp
+
Ch] [ebp
-
8h
] BYREF
DWORD NumberOfBytesWritten;
/
/
[esp
+
10h
] [ebp
-
4h
] BYREF
sub_401000();
puts(aWelcomeToMyTea);
v3
=
CreateFileA(FileName,
0xC0000000
,
0
,
0
,
3u
,
0x80u
,
0
);
v4
=
v3;
if
( v3
=
=
(HANDLE)
-
1
)
{
puts(aIThinkYouDoNot);
result
=
0
;
}
else
{
v6
=
GetFileSize(v3,
0
);
if
( v6 <
0xEA60
)
{
SetFilePointer(v4,
0
,
0
,
0
);
NumberOfBytesRead
=
0
;
ReadFile(v4, &unk_409988, v6, &NumberOfBytesRead,
0
);
CloseHandle(v4);
if
( v6 >>
3
)
{
v7
=
(char
*
)&unk_409988;
v8
=
v6 >>
3
;
do
{
/
/
关键函数,但是被 嵌入了花指令, 负责了关键部分数据处理
((void (__cdecl
*
)(char
*
, void
*
))loc_4010A0)(v7, &unk_407030);
v7
+
=
8
;
-
-
v8;
}
while
( v8 );
}
v9
=
CreateFileA(aTeaPngOut,
0xC0000000
,
0
,
0
,
2u
,
0x80u
,
0
);
v10
=
v9;
if
( v9
=
=
(HANDLE)
-
1
)
{
puts(aIThinkYouDoNot);
}
else
{
NumberOfBytesWritten
=
0
;
WriteFile(v9, &unk_409988, v6, &NumberOfBytesWritten,
0
);
CloseHandle(v10);
puts(aNowThisCupOfTe);
}
result
=
0
;
}
else
{
puts(aYourTeaIsTooHo);
result
=
0
;
}
}
return
result;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
HANDLE v3;
/
/
eax
void
*
v4;
/
/
esi
int
result;
/
/
eax
DWORD v6;
/
/
edi
char
*
v7;
/
/
esi
DWORD v8;
/
/
ebx
HANDLE v9;
/
/
eax
void
*
v10;
/
/
esi
DWORD NumberOfBytesRead;
/
/
[esp
+
Ch] [ebp
-
8h
] BYREF
DWORD NumberOfBytesWritten;
/
/
[esp
+
10h
] [ebp
-
4h
] BYREF
sub_401000();
puts(aWelcomeToMyTea);
v3
=
CreateFileA(FileName,
0xC0000000
,
0
,
0
,
3u
,
0x80u
,
0
);
v4
=
v3;
if
( v3
=
=
(HANDLE)
-
1
)
{
puts(aIThinkYouDoNot);
result
=
0
;
}
else
{
v6
=
GetFileSize(v3,
0
);
if
( v6 <
0xEA60
)
{
SetFilePointer(v4,
0
,
0
,
0
);
NumberOfBytesRead
=
0
;
ReadFile(v4, &unk_409988, v6, &NumberOfBytesRead,
0
);
CloseHandle(v4);
if
( v6 >>
3
)
{
v7
=
(char
*
)&unk_409988;
v8
=
v6 >>
3
;
do
{
/
/
关键函数,但是被 嵌入了花指令, 负责了关键部分数据处理
((void (__cdecl
*
)(char
*
, void
*
))loc_4010A0)(v7, &unk_407030);
v7
+
=
8
;
-
-
v8;
}
while
( v8 );
}
v9
=
CreateFileA(aTeaPngOut,
0xC0000000
,
0
,
0
,
2u
,
0x80u
,
0
);
v10
=
v9;
if
( v9
=
=
(HANDLE)
-
1
)
{
puts(aIThinkYouDoNot);
}
else
{
NumberOfBytesWritten
=
0
;
WriteFile(v9, &unk_409988, v6, &NumberOfBytesWritten,
0
);
CloseHandle(v10);
puts(aNowThisCupOfTe);
}
result
=
0
;
}
else
{
puts(aYourTeaIsTooHo);
result
=
0
;
}
}
return
result;
}
int
*
__cdecl sub_4010A0(
int
*
a1, _DWORD
*
a2)
{
int
*
result;
/
/
eax
int
v3;
/
/
[esp
+
Ch] [ebp
-
14h
]
int
i;
/
/
[esp
+
14h
] [ebp
-
Ch]
int
v5;
/
/
[esp
+
18h
] [ebp
-
8h
]
int
v6;
/
/
[esp
+
1Ch
] [ebp
-
4h
]
v5
=
0
;
v6
=
a1[
1
];
v3
=
*
a1;
for
( i
=
0
; i <
32
;
+
+
i )
{
v5
-
=
0x61C88647
;
v3
+
=
(a2[
1
]
+
(v6 >>
5
)) ^ (v5
+
v6) ^ (
*
a2
+
16
*
v6);
v6
+
=
(a2[
3
]
+
(v3 >>
5
)) ^ (v5
+
v3) ^ (a2[
2
]
+
16
*
v3);
}
a1[
1
]
=
v6;
result
=
a1;
*
a1
=
v3;
return
result;
}
int
*
__cdecl sub_4010A0(
int
*
a1, _DWORD
*
a2)
{
int
*
result;
/
/
eax
int
v3;
/
/
[esp
+
Ch] [ebp
-
14h
]
int
i;
/
/
[esp
+
14h
] [ebp
-
Ch]
int
v5;
/
/
[esp
+
18h
] [ebp
-
8h
]
int
v6;
/
/
[esp
+
1Ch
] [ebp
-
4h
]
v5
=
0
;
v6
=
a1[
1
];
v3
=
*
a1;
for
( i
=
0
; i <
32
;
+
+
i )
{
v5
-
=
0x61C88647
;
v3
+
=
(a2[
1
]
+
(v6 >>
5
)) ^ (v5
+
v6) ^ (
*
a2
+
16
*
v6);
v6
+
=
(a2[
3
]
+
(v3 >>
5
)) ^ (v5
+
v3) ^ (a2[
2
]
+
16
*
v3);
}
a1[
1
]
=
v6;
result
=
a1;
*
a1
=
v3;
return
result;
}
/
/
tea加解密.cpp : 此文件包含
"main"
函数。程序执行将在此处开始并结束。
/
/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
void decrypt(unsigned
int
*
v, unsigned
int
*
key) {
int
l;
/
/
[esp
+
Ch] [ebp
-
14h
]
int
sum
;
/
/
[esp
+
18h
] [ebp
-
8h
]
int
r;
/
/
[esp
+
1Ch
] [ebp
-
4h
]
r
=
v[
1
];
l
=
v[
0
];
sum
=
0xC6EF3720
;
for
(size_t i
=
0
; i <
32
; i
+
+
) {
/
/
sum
-
=
0x61C88647
;
r
-
=
(key[
3
]
+
(l >>
5
)) ^ (
sum
+
l) ^ (key[
2
]
+
(
16
*
l));
l
-
=
(key[
1
]
+
(r >>
5
)) ^ (
sum
+
r) ^ (key[
0
]
+
(
16
*
r));
sum
+
=
0x61C88647
;
/
/
r
-
=
((l
*
16
)
+
key[
2
]) ^ (l
+
sum
) ^ ((l >>
5
)
+
key[
3
]);
/
/
l
-
=
((r
*
16
)
+
key[
0
]) ^ (r
+
sum
) ^ ((r >>
5
)
+
key[
1
]);
}
v[
0
]
=
l;
v[
1
]
=
r;
}
void de_file() {
char file_path[]
=
{
"C:\\Users\\Dell\\Desktop\\Test\\tea.png.out"
};
FILE
*
file_point
=
fopen(file_path,
"rb"
);
fseek(file_point,
0
, SEEK_END);
int
len
=
ftell(file_point);
fseek(file_point,
0
, SEEK_SET);
char
*
file_content
=
(char
*
)malloc(
len
);
memset(file_content,
0
,
len
);
fread(file_content,
1
,
len
, file_point);
fclose(file_point);
char new_file_path[]
=
{
"C:\\Users\\Dell\\Desktop\\Test\\tea.png"
};
FILE
*
new_file_point
=
fopen(new_file_path,
"wb"
);
char secry_key[]
=
{
0x66
,
0x6C
,
0x61
,
0x67
,
0x7B
,
0x66
,
0x61
,
0x6B
,
0x65
,
0x5F
,
0x66
,
0x6C
,
0x61
,
0x67
,
0x21
,
0x7D
,
0x67
,
0x65
,
0x74
,
0x20
,
0x6F
,
0x75
,
0x74
,
0x21
,
0x20
,
0x0A
,
0x00
};
for
(
int
i
=
0
; i <
len
; i
+
=
8
) {
decrypt((unsigned
int
*
)(file_content
+
i), (unsigned
int
*
)secry_key);
}
fwrite(file_content,
1
,
len
, new_file_point);
fclose(new_file_point);
}
void main() {
de_file();
}
/
/
tea加解密.cpp : 此文件包含
"main"
函数。程序执行将在此处开始并结束。
/
/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
void decrypt(unsigned
int
*
v, unsigned
int
*
key) {
int
l;
/
/
[esp
+
Ch] [ebp
-
14h
]
int
sum
;
/
/
[esp
+
18h
] [ebp
-
8h
]
int
r;
/
/
[esp
+
1Ch
] [ebp
-
4h
]
r
=
v[
1
];
l
=
v[
0
];
sum
=
0xC6EF3720
;
for
(size_t i
=
0
; i <
32
; i
+
+
) {
/
/
sum
-
=
0x61C88647
;
r
-
=
(key[
3
]
+
(l >>
5
)) ^ (
sum
+
l) ^ (key[
2
]
+
(
16
*
l));
l
-
=
(key[
1
]
+
(r >>
5
)) ^ (
sum
+
r) ^ (key[
0
]
+
(
16
*
r));
sum
+
=
0x61C88647
;
/
/
r
-
=
((l
*
16
)
+
key[
2
]) ^ (l
+
sum
) ^ ((l >>
5
)
+
key[
3
]);
/
/
l
-
=
((r
*
16
)
+
key[
0
]) ^ (r
+
sum
) ^ ((r >>
5
)
+
key[
1
]);
}
v[
0
]
=
l;
v[
1
]
=
r;
}
void de_file() {
char file_path[]
=
{
"C:\\Users\\Dell\\Desktop\\Test\\tea.png.out"
};
FILE
*
file_point
=
fopen(file_path,
"rb"
);
fseek(file_point,
0
, SEEK_END);
int
len
=
ftell(file_point);
fseek(file_point,
0
, SEEK_SET);
char
*
file_content
=
(char
*
)malloc(
len
);
memset(file_content,
0
,
len
);
fread(file_content,
1
,
len
, file_point);
fclose(file_point);
char new_file_path[]
=
{
"C:\\Users\\Dell\\Desktop\\Test\\tea.png"
};