CISCN 2021 西南赛区 Fix Writeup
感谢队友 ay3 的输出
d1res0lve
read 越界导致栈溢出
ssize_t vuln()
{
char v1[16]; // [sp+38h] [+38h] BYREF
return read(0, v1, 0x28u);
}
修改 read 长度即可
crash
没有检测使用状态和序号范围,并且没有清空函数指针,导致 double free
unsigned __int64 delete()
{
int v1; // [rsp+Ch] [rbp-114h]
char buf[264]; // [rsp+10h] [rbp-110h] BYREF
unsigned __int64 v3; // [rsp+118h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("Give me the data id you want to delete\nid:");
v1 = getInt();
if ( v1 < 0 || v1 > 16 )
puts("Invalid id");
if ( qword_2020E8[2 * v1] )
{
printf("Are you sure?:");
read(0, buf, 0x100uLL);
if ( !strncmp(buf, "yes", 3uLL) )
{
(*(void (__fastcall **)(_QWORD))(qword_2020E8[2 * v1] + 24LL))(qword_2020E8[2 * v1]);
*((_DWORD *)&Strings + 4 * v1) = 0;
}
}
return __readfsqword(0x28u) ^ v3;
}
修改后的代码如下
int delete()
{
unsigned __int64 v0; // rax
int v2; // [rsp+Ch] [rbp-114h]
char buf[264]; // [rsp+10h] [rbp-110h] BYREF
unsigned __int64 v4; // [rsp+118h] [rbp-8h]
v4 = __readfsqword(0x28u);
printf("Give me the data id you want to delete\nid:");
v2 = getInt();
if ( v2 >= 0 && v2 < 16 )
{
if ( use[2 * (unsigned int)v2] )
{
printf("Are you sure?:");
read(0, buf, 0x100uLL);
if ( !strncmp(buf, "yes", 3uLL) )
{
(*(void (__fastcall **)(_QWORD))(list[2 * v2] + 24LL))(list[2 * v2]);
LODWORD(use[2 * v2]) = 0;
}
}
v0 = __readfsqword(0x28u) ^ v4;
}
else
{
LODWORD(v0) = puts("Invalid id");
}
return v0;
}
对应汇编代码如下
.text:0000560F5A19AD70 55 push rbp
.text:0000560F5A19AD71 48 89 E5 mov rbp, rsp
.text:0000560F5A19AD74 48 81 EC 20 01 00 00 sub rsp, 120h
.text:0000560F5A19AD7B 64 48 8B 04 25 28 00+ mov rax, fs:28h
.text:0000560F5A19AD7B 00 00
.text:0000560F5A19AD84 48 89 45 F8 mov [rbp+var_8], rax
.text:0000560F5A19AD88 31 C0 xor eax, eax
.text:0000560F5A19AD8A 48 8D 3D 87 04 00 00 lea rdi, format ; "Give me the data id you want to delete"...
.text:0000560F5A19AD91 B8 00 00 00 00 mov eax, 0
.text:0000560F5A19AD96 E8 15 FC FF FF call _printf
.text:0000560F5A19AD9B E8 B0 FD FF FF call getInt
.text:0000560F5A19ADA0 89 85 EC FE FF FF mov [rbp+var_114], eax
.text:0000560F5A19ADA6 83 BD EC FE FF FF 00 cmp [rbp+var_114], 0
.text:0000560F5A19ADAD 78 09 js short loc_560F5A19ADB8
.text:0000560F5A19ADAF 83 BD EC FE FF FF 10 cmp [rbp+var_114], 10h
.text:0000560F5A19ADB6 7C 0E jl short loc_560F5A19ADC6 ; Keypatch modified this from:
.text:0000560F5A19ADB6 ; jle short loc_DC6
.text:0000560F5A19ADB8
.text:0000560F5A19ADB8 loc_560F5A19ADB8: ; CODE XREF: delete+3D↑j
.text:0000560F5A19ADB8 48 8D 3D 84 04 00 00 lea rdi, aInvalidId ; "Invalid id"
.text:0000560F5A19ADBF E8 AC FB FF FF call _puts
.text:0000560F5A19ADC4 C9 leave
.text:0000560F5A19ADC5 C3 retn
.text:0000560F5A19ADC6 ; ---------------------------------------------------------------------------
.text:0000560F5A19ADC6
.text:0000560F5A19ADC6 loc_560F5A19ADC6: ; CODE XREF: delete+46↑j
.text:0000560F5A19ADC6 8B 85 EC FE FF FF mov eax, [rbp+var_114]
.text:0000560F5A19ADCC 48 C1 E0 04 shl rax, 4
.text:0000560F5A19ADD0 48 89 C2 mov rdx, rax
.text:0000560F5A19ADD3 48 8D 05 06 13 20 00 lea rax, use ; Keypatch modified this from:
.text:0000560F5A19ADD3 ; lea rax, list
Delay2
没有检测使用状态,并且没有清空函数指针,导致 double free
void sub_DC4()
{
unsigned int v0; // [rsp+Ch] [rbp-4h]
puts("id:");
v0 = sub_B66();
if ( v0 <= 9 && qword_202040[v0] )
free((void *)qword_202040[v0]);
else
puts("Invalid id!");
}
修改后的代码如下
void __fastcall sub_DC4(__int64 a1, const pthread_attr_t *a2)
{
__int64 v2; // rdx
void *v3; // rdi
unsigned int v4; // [rsp+Ch] [rbp-4h]
puts("id:");
v4 = sub_B66("id:", a2);
if ( v4 <= 9 && qword_202040[v4] )
{
v2 = v4;
v3 = (void *)qword_202040[v2];
qword_202040[v2] = 0LL;
free(v3);
}
else
{
puts("Invalid id!");
}
}
对应的汇编代码如下
.text:0000000000000DC4 55 push rbp
.text:0000000000000DC5 48 89 E5 mov rbp, rsp
.text:0000000000000DC8 48 83 EC 10 sub rsp, 10h
.text:0000000000000DCC 48 8D 3D 67 02 00 00 lea rdi, aId ; "id:"
.text:0000000000000DD3 E8 68 FB FF FF call puts
.text:0000000000000DD8 E8 89 FD FF FF call sub_B66 ; Keypatch modified this from:
.text:0000000000000DD8 ; call near ptr loc_B5E+3
.text:0000000000000DD8 ; Keypatch modified this from:
.text:0000000000000DD8 ; call near ptr loc_B5E+3
.text:0000000000000DD8 ; Keypatch modified this from:
.text:0000000000000DD8 ; call loc_B5E
.text:0000000000000DDD 89 45 FC mov [rbp+var_4], eax
.text:0000000000000DE0 83 7D FC 09 cmp [rbp+var_4], 9
.text:0000000000000DE4 77 1B ja short loc_E01
.text:0000000000000DE6 8B 45 FC mov eax, [rbp+var_4]
.text:0000000000000DE9 48 8D 14 C5 00 00 00+ lea rdx, ds:0[rax*8] ; start_routine
.text:0000000000000DE9 00
.text:0000000000000DF1 48 8D 05 48 12 20 00 lea rax, qword_202040 ; Keypatch modified this from:
.text:0000000000000DF1 ; lea rax, unk_20203B
.text:0000000000000DF8 48 8B 04 02 mov rax, [rdx+rax]
.text:0000000000000DFC 48 85 C0 test rax, rax
.text:0000000000000DFF 75 0E jnz short loc_E0F
.text:0000000000000E01
.text:0000000000000E01 loc_E01: ; CODE XREF: sub_DC4+20↑j
.text:0000000000000E01 48 8D 3D 36 02 00 00 lea rdi, aInvalidId ; newthread
.text:0000000000000E01 ; Keypatch modified this from:
.text:0000000000000E01 ; lea rdi, aContent+8
.text:0000000000000E01 ; Keypatch modified this from:
.text:0000000000000E01 ; lea rdi, aId+2
.text:0000000000000E08 E8 33 FB FF FF call puts ; Keypatch modified this from:
.text:0000000000000E08 ; call near ptr pthread_create+3
.text:0000000000000E08 ; Keypatch modified this from:
.text:0000000000000E08 ; call near ptr pthread_create+3
.text:0000000000000E08 ; Keypatch modified this from:
.text:0000000000000E08 ; call pthread_create
.text:0000000000000E0D EB 23 jmp short locret_E32 ; Keypatch modified this from:
.text:0000000000000E0D ; jmp short near ptr loc_E2A+3
.text:0000000000000E0D ; Keypatch modified this from:
.text:0000000000000E0D ; jmp short near ptr loc_E2A+3
.text:0000000000000E0D ; Keypatch modified this from:
.text:0000000000000E0D ; jmp short loc_E2A
.text:0000000000000E0F ; ---------------------------------------------------------------------------
.text:0000000000000E0F
.text:0000000000000E0F loc_E0F: ; CODE XREF: sub_DC4+3B↑j
.text:0000000000000E0F 8B 45 FC mov eax, [rbp+var_4]
.text:0000000000000E12 48 8D 14 C5 00 00 00+ lea rdx, ds:0[rax*8]
.text:0000000000000E12 00
.text:0000000000000E1A 48 8D 05 1F 12 20 00 lea rax, qword_202040 ; Keypatch modified this from:
.text:0000000000000E1A ; lea rax, unk_20203B
.text:0000000000000E21 48 8B 3C 02 mov rdi, [rdx+rax] ; Keypatch modified this from:
.text:0000000000000E21 ; mov rax, [rdx+rax]
.text:0000000000000E25 48 C7 04 02 00 00 00+ mov qword ptr [rdx+rax], 0 ; Keypatch modified this from:
.text:0000000000000E25 00 ; mov rdi, rax
.text:0000000000000E25 ; call free
.text:0000000000000E25 ; Keypatch padded NOP to next boundary: 3 bytes
.text:0000000000000E25 ; Keypatch modified this from:
.text:0000000000000E25 ; call free
.text:0000000000000E25 ; mov qword ptr [rdx+rax], 0
.text:0000000000000E25 ; Keypatch padded NOP to next boundary: 5 bytes
.text:0000000000000E25 ; Keypatch modified this from:
.text:0000000000000E25 ; mov rdi, rax
.text:0000000000000E25 ; call loc_92B
.text:0000000000000E2D E8 FE FA FF FF call free ; Keypatch modified this from:
.text:0000000000000E2D ; db 3 dup(0)
.text:0000000000000E2D ; db 2 dup(0)
.text:0000000000000E32
.text:0000000000000E32 locret_E32: ; CODE XREF: sub_DC4+49↑j
.text:0000000000000E32 C9 leave
.text:0000000000000E33 C3 retn
ppprintf
printf 参数可控,格式化字符串漏洞
void __fastcall ppprintf(const char *str)
{
printf(str);
}
修改后代码如下
void __fastcall ppprintf(const char *str)
{
printf("%s", str);
}
对应汇编代码如下
.text:0000000000000990 48 89 FE mov rsi, rdi
.text:0000000000000993 48 8D 3D 28 FF+ lea rdi, aS ; Keypatch modified this from:
.text:0000000000000993 FF FF ; mov rdi, 8C2h
.text:000000000000099A 90 nop
.text:000000000000099B E9 C0 FE FF FF jmp _printf
Weapon2
没有检测序号范围,导致任意 free
int __fastcall drop(__int64 a1)
{
_QWORD *v1; // rax
int v3; // [rsp+1Ch] [rbp-4h]
puts("The Weapon id:");
v3 = sub_B0D();
if ( v3 <= 0xF && *(_QWORD *)(8LL * v3 + a1) )
{
free(*(void **)(8LL * v3 + a1));
v1 = (_QWORD *)(8LL * v3 + a1);
*v1 = 0LL;
}
else
{
LODWORD(v1) = puts("Invalid id!");
}
return (int)v1;
}
修改后代码如下
int __fastcall drop(__int64 a1)
{
_QWORD *v1; // rax
int v3; // [rsp+1Ch] [rbp-4h]
puts("The Weapon id:");
v3 = sub_B0D();
if ( (unsigned int)v3 <= 0xF && *(_QWORD *)(8LL * v3 + a1) )
{
free(*(void **)(8LL * v3 + a1));
v1 = (_QWORD *)(8LL * v3 + a1);
*v1 = 0LL;
}
else
{
LODWORD(v1) = puts("Invalid id!");
}
return (int)v1;
}
对应汇编代码如下
.text:0000000000000E12 mov [rbp+var_4], eax
.text:0000000000000E15 cmp [rbp+var_4], 0Fh
.text:0000000000000E19 ja short loc_E37 ; Keypatch modified this from:
.text:0000000000000E19 ; jg short loc_E37
.text:0000000000000E1B mov eax, [rbp+var_4]