[CISCN 2021 初赛]silverwolf WP的解题思路有哪些?
摘要:一、题目来源 NSSCTF_Pwn_[CISCN 2021 初赛]silverwolf 二、信息搜集 通过 file 命令查看文件类型: 通过 checksec 命令查看文件开启的保护机制: 根据题目给的 libc 文件确定 glibc 版
一、题目来源
NSSCTF_Pwn_[CISCN 2021 初赛]silverwolf
二、信息搜集
通过 file 命令查看文件类型:
通过 checksec 命令查看文件开启的保护机制:
根据题目给的 libc 文件确定 glibc 版本是 2.27。
三、反汇编文件开始分析
程序的开头能看到设置了沙箱:
__int64 sub_C70()
{
__int64 v0; // rbx
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
v0 = seccomp_init(0);
seccomp_rule_add(v0, 2147418112, 0, 0);
seccomp_rule_add(v0, 2147418112, 2, 0);
seccomp_rule_add(v0, 2147418112, 1, 0);
return seccomp_load(v0);
}
通过工具可以分析出这个沙箱的作用:
ORW 被 ALLOW,那么本题的是不是和它有关呢?先打个问号。
根据输出提示,能知道程序的四大功能(exit 就不多说了):
puts("1. allocate");
puts("2. edit");
puts("3. show");
puts("4. delete");
puts("5. exit");
逐一进行分析。
1、allocate
unsigned __int64 allocate()
{
size_t v1; // rbx
void *v2; // rax
size_t size; // [rsp+0h] [rbp-18h] BYREF
unsigned __int64 v4; // [rsp+8h] [rbp-10h]
v4 = __readfsqword(0x28u);
__printf_chk(1, "Index: ");
__isoc99_scanf(&unk_1144, &size);
if ( !size )
{
__printf_chk(1, "Size: ");
__isoc99_scanf(&unk_1144, &size);
v1 = size;
if ( size > 0x78 )
{
__printf_chk(1, "Too large");
}
else
{
v2 = malloc(size);
if ( v2 )
{
qword_202050 = v1;
buf = v2;
puts("Done!");
}
else
{
puts("allocate failed");
}
}
}
return __readfsqword(0x28u) ^ v4;
}
虽然让我们指定了下标(index),但是根据代码 if ( !size ) 我们知道:若要成功申请 chunk,那么 index 就只能为 0。但是,这也就意味着,我们可以一直申请 chunk,只要指定 index 为 0。
三个信息点:
chunk 的大小是我们自己指定的,但是最大不超过 0x78(size > 0x78 )。
全局变量 qword_202050 会存放我们申请 chunk 的大小(不含 chunk header)。
全局变量 buf 会指向 chunk 的 user data 部分。
