awdp pwn

第十八届CISCN&CCB半决赛

awdp pwn

typo

snprintf() 是一个 C 语言标准库函数,用于格式化输出字符串,并将结果写入到指定的缓冲区,与 sprintf() 不同的是,snprintf() 会限制输出的字符数,避免缓冲区溢出。

C 库函数 int snprintf(char str, size_t size, const char format, ...) 设将可变参数 (...) 按照 format 格式化成字符串,并将字符串复制到 str 中,size** 为要写入的字符的最大数目,超过 size 会被截断,最多写入 size-1 个字符。

sprintf() 函数不同的是,snprintf() 函数提供了一个参数 size,可以防止缓冲区溢出。如果格式化后的字符串长度超过了 size-1,则 snprintf() 只会写入 size-1 个字符,并在字符串的末尾添加一个空字符(\0)以表示字符串的结束。

声明:

下面是 snprintf() 函数的声明。

int snprintf ( char * str, size_t size, const char * format, ... );

看到 edit​ 函数,当时就在分析怎么改这个 snprintf​ 函数,感觉是参数不对

unsigned __int64 edit()
{
  signed int v1; // [rsp+4h] [rbp-11Ch] BYREF
  unsigned __int64 v2; // [rsp+8h] [rbp-118h]
  char s[264]; // [rsp+10h] [rbp-110h] BYREF
  unsigned __int64 v4; // [rsp+118h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  printf("Index: ");
  __isoc99_scanf("%d", &v1);
  if ( (unsigned int)v1 < 0x20 )
  {
    if ( *((_QWORD *)&unk_4060 + v1) )
    {
      v2 = **((_QWORD **)&unk_4060 + v1);
      printf("New size of content: ");
      memset(s, 0, 0x100uLL);
      read(0, s, 0x100uLL);
      snprintf(*((char **)&unk_4060 + v1), (size_t)"%lu", s, 8LL);// 比赛的时候就觉得这个有问题,但不知道怎么改
      if ( v2 < **((_QWORD **)&unk_4060 + v1) )
      {
        puts("Too large");
        **((_QWORD **)&unk_4060 + v1) = v2;
      }
      printf("What do you want to say: ");
      read(0, (void *)(*((_QWORD *)&unk_4060 + v1) + 8LL), **((_QWORD **)&unk_4060 + v1));
    }
    else
    {
      puts("No card here");
    }
  }
  else
  {
    puts("Invalid index");
  }
  return __readfsqword(0x28u) ^ v4;
}

image-20250319125127408

image-20250319125136166

Prompt

off by null 给它 nop掉

image-20250319125152332

找到 sub_1A40函数,猜测memcpy存在溢出,把rdx改小

unsigned __int64 __fastcall sub_1A40(__int64 a1)
{
  signed int v2; // [rsp+18h] [rbp-18h]
  signed int v3; // [rsp+1Ch] [rbp-14h]
  unsigned __int64 v4; // [rsp+28h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  if ( *(_QWORD *)(a1 + 48) )
  {
    if ( *(_QWORD *)(a1 + 32) )
    {
      v2 = **(_DWORD **)(a1 + 56);
      v3 = **(_DWORD **)(a1 + 40);
      if ( (unsigned int)v2 < 0x10 && *((_QWORD *)&unk_5060 + v2) && (unsigned int)v3 <= 0x500 )
      {
        qword_50E0[v2] = v3;
        if ( *(_QWORD *)(a1 + 64) && *(_QWORD *)(a1 + 72) )
          memcpy(*((void **)&unk_5060 + v2), *(const void **)(a1 + 72), 0LL);
        else
          memset(*((void **)&unk_5060 + v2), 0, v3);
      }
    }
  }
  return v4 - __readfsqword(0x28u);
}

找到 sub_1A40函数,memcpy存在溢出,改rdx参数为0

unsigned __int64 __fastcall sub_17BB(__int64 a1)
{
  int i; // [rsp+18h] [rbp-18h]
  signed int v3; // [rsp+1Ch] [rbp-14h]
  unsigned __int64 v4; // [rsp+28h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  if ( *(_QWORD *)(a1 + 32) )
  {
    v3 = **(_DWORD **)(a1 + 40);
    if ( (unsigned int)v3 <= 0x500 )
    {
      for ( i = 0; i <= 15 && *((_QWORD *)&unk_5060 + i); ++i )
        ;
      if ( i <= 15 )
      {
        qword_50E0[i] = v3;
        *((_QWORD *)&unk_5060 + i) = malloc(v3);
        if ( !*((_QWORD *)&unk_5060 + i) )
          exit(1);
        memset(*((void **)&unk_5060 + i), 0, v3);
        if ( *(_QWORD *)(a1 + 64) && *(_QWORD *)(a1 + 72) )
          memcpy(*((void **)&unk_5060 + i), *(const void **)(a1 + 72), 0LL);
      }
    }
  }
  return v4 - __readfsqword(0x28u);
}

其他方法:

在第一个函数 sub_17BB 里面

image-20250319125231993

把0x500改成0x100,防止large bin attack之类的

image-20250319125243157

patch后

image-20250319125309767

这里有个 off by null ,把这一行nop掉(比赛中有改,我应该是改改这个和上面的 memcpy 一起成功的)

image-20250319125320504

image-20250319125328798

这个函数有 uaf 比赛时没看到,把0x1000改小

image-20250319125336811

image-20250319125351573

成了

post_quantum

输入函数,把0x20改小

int sub_1441()
{
  char buf[56]; // [rsp+0h] [rbp-40h] BYREF
  unsigned __int64 v2; // [rsp+38h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  read(0, buf, 0x20uLL);
  return atoi(buf);
}

image-20250319125402847

同样 off by null 把free 下面一行 nop 掉

image-20250319125420643

image-20250319125427838

这样就改成了,上传就修复成功了

还可以改这个 0x1F 改小

image-20250319125436470

image-20250319125444990

posted @ 2025-03-19 12:59  cosyQAQ  阅读(79)  评论(0)    收藏  举报