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
id:");
  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
id:");
  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]
原文地址:https://www.cnblogs.com/algonote/p/14854378.html