首页
社区
课程
招聘
[原创] KCTF 2024 第一次接触 wp by CrackE
发表于: 2024-9-2 14:24 1870

[原创] KCTF 2024 第一次接触 wp by CrackE

2024-9-2 14:24
1870

ida32反编译,main如下

很明显把输入平均拆成了3个字符串,分别检查,最后md5加密比较

sub_2F6BCB看出来第一个字符串前8位为"hellocat"

sub_2F78CD看出来输入全为数字,各个数位和为13,j_unknown_libname_84(Str)50211202,正好数字和为13,因此原来的应该是20211205

sub_2F6E78把输入的字符串再次分为了4个2字节,均由sub_2F8232进行检查

sub_2F8232如下

检查逻辑是输入两个字符,第一个a-d,第二个1-4,处理完后分别代表4*4表的下标,保证4次传入设置byte_3D1EA0数组某个值为1时,不在同一行同一列同一对角线上,此时只有两种情况

再回去看,sub_2F8232必然返回1,所以可是前四个或运算完dword_3D1E9C不可能等于0x10000039(dword_3D1E9C初始值为0),所以前四个if也不能成立,此时只有两种输入a3b1c4d2a2b4c1d3

因此可知dword_3D1E9C初始值不应该为0,应该是0x39,双击查看位置发现正好在输入字符串的下方,因此只要输入9个字符,最后一个是9即可覆盖,保证检查函数返回值为1

同理,前面的两个输入长度也应该是9,第一个字符串后面拼接的不知道只能遍历,第二个要想保证检查条件只能+0

所以写脚本爆破下即可获得注册码

int __cdecl main_0(int argc, const char **argv, const char **envp)
{//...
  __CheckForDebuggerJustMyCode(byte_3D5028);
  sub_2F548D((int)&unk_3AAE70, v4);
  j__memset(Str, 0, 0x12Cu);
  sub_2F591F("%[^\n]", (char)Str);
  v12 = j__strlen(Str);
  if ( !(v12 % 3) && v12 )                      // 长度3的倍数
  {
    for ( i = 0; i < v12; ++i )
    {
      if ( (Str[i] < 97 || Str[i] > 122) && (Str[i] < 48 || Str[i] > 57) )  // 限定范围
        goto LABEL_3;
    }
    Count = v12 / 3;
    Destination = (char *)j__malloc(__CFADD__(v12 / 3, 1) ? -1 : v12 / 3 + 1);
    v8 = (char *)j__malloc(__CFADD__(Count, 1) ? -1 : Count + 1);
    Source = (char *)j__malloc(__CFADD__(Count, 1) ? -1 : Count + 1);
    j__memset(Destination, 0, v12 / 3 + 1);
    j__memset(v8, 0, v12 / 3 + 1);
    j__memset(Source, 0, v12 / 3 + 1);
    j__strncpy(Destination, Str, v12 / 3);      // 前1/3
    j__strncpy(v8, &Str[Count], Count);         // 中间1/3
    j__strncpy(Source, &Str[2 * Count], Count); // 后1/3
    if ( sub_2F6BCB(Destination) && sub_2F78CD(v8) && sub_2F6E78(Source) )
    {
      Str1 = (char *)sub_2F79F4(Str);
      if ( !j__strcmp(Str1, "40d511825ecbc207eb6ef9a7b1c6e34b") )
        sub_2F548D((int)"Success~\n", v5);
      else
        sub_2F548D((int)"WR0NG!\n", v5);
      j__free(Str1);
    }
    else
    {
      sub_2F548D((int)"WR0NG!\n", v5);
    }
    j__free(Destination);
    j__free(v8);
    j__free(Source);
    return 0;
  }
  else
  {
LABEL_3:
    sub_2F548D((int)"WRONG!\n", v5);
    return 0;
  }
}
int __cdecl main_0(int argc, const char **argv, const char **envp)
{//...
  __CheckForDebuggerJustMyCode(byte_3D5028);
  sub_2F548D((int)&unk_3AAE70, v4);
  j__memset(Str, 0, 0x12Cu);
  sub_2F591F("%[^\n]", (char)Str);
  v12 = j__strlen(Str);
  if ( !(v12 % 3) && v12 )                      // 长度3的倍数
  {
    for ( i = 0; i < v12; ++i )
    {
      if ( (Str[i] < 97 || Str[i] > 122) && (Str[i] < 48 || Str[i] > 57) )  // 限定范围
        goto LABEL_3;
    }
    Count = v12 / 3;
    Destination = (char *)j__malloc(__CFADD__(v12 / 3, 1) ? -1 : v12 / 3 + 1);
    v8 = (char *)j__malloc(__CFADD__(Count, 1) ? -1 : Count + 1);
    Source = (char *)j__malloc(__CFADD__(Count, 1) ? -1 : Count + 1);
    j__memset(Destination, 0, v12 / 3 + 1);
    j__memset(v8, 0, v12 / 3 + 1);
    j__memset(Source, 0, v12 / 3 + 1);
    j__strncpy(Destination, Str, v12 / 3);      // 前1/3
    j__strncpy(v8, &Str[Count], Count);         // 中间1/3
    j__strncpy(Source, &Str[2 * Count], Count); // 后1/3
    if ( sub_2F6BCB(Destination) && sub_2F78CD(v8) && sub_2F6E78(Source) )
    {
      Str1 = (char *)sub_2F79F4(Str);
      if ( !j__strcmp(Str1, "40d511825ecbc207eb6ef9a7b1c6e34b") )
        sub_2F548D((int)"Success~\n", v5);
      else
        sub_2F548D((int)"WR0NG!\n", v5);
      j__free(Str1);
    }
    else
    {
      sub_2F548D((int)"WR0NG!\n", v5);
    }
    j__free(Destination);
    j__free(v8);
    j__free(Source);
    return 0;
  }
  else
  {
LABEL_3:
    sub_2F548D((int)"WRONG!\n", v5);
    return 0;
  }
}
int __cdecl sub_2F6BCB(char *Str1)
{
  return sub_2FC360(Str1);
}
BOOL __cdecl sub_2FC360(char *Str1)
{
  __CheckForDebuggerJustMyCode(&byte_3D5028);
  sub_2F5816(Str1);
  return j__strncmp(Str1, "hellocat", 8u) == 0;
}
int __cdecl sub_2F6BCB(char *Str1)
{
  return sub_2FC360(Str1);
}
BOOL __cdecl sub_2FC360(char *Str1)
{
  __CheckForDebuggerJustMyCode(&byte_3D5028);
  sub_2F5816(Str1);
  return j__strncmp(Str1, "hellocat", 8u) == 0;
}
int __cdecl sub_2F78CD(char *Str)
{
  return sub_2FC400(Str);
}
BOOL __cdecl sub_2FC400(char *Str)
{
  size_t i; // [esp+D4h] [ebp-14h]
  int v3; // [esp+E0h] [ebp-8h]
 
  __CheckForDebuggerJustMyCode(&byte_3D5028);
  sub_2F5357(Str);  // reverse
  v3 = 0;
  for ( i = 0; i < j__strlen(Str); ++i )
    v3 = v3 + Str[i] - 48;                      // 全是数字,和为13
  return v3 == dword_3D1004 && dword_3D1008 * j_unknown_libname_84(Str) == 150633606;   // dword_3D1008=3
}
int __cdecl sub_2F78CD(char *Str)
{
  return sub_2FC400(Str);
}
BOOL __cdecl sub_2FC400(char *Str)
{
  size_t i; // [esp+D4h] [ebp-14h]
  int v3; // [esp+E0h] [ebp-8h]
 
  __CheckForDebuggerJustMyCode(&byte_3D5028);
  sub_2F5357(Str);  // reverse
  v3 = 0;
  for ( i = 0; i < j__strlen(Str); ++i )
    v3 = v3 + Str[i] - 48;                      // 全是数字,和为13
  return v3 == dword_3D1004 && dword_3D1008 * j_unknown_libname_84(Str) == 150633606;   // dword_3D1008=3
}
int __cdecl sub_2F6E78(char *Source)
{
  return sub_2FC500(Source);
}
BOOL __cdecl sub_2FC500(char *Source)
{
  __CheckForDebuggerJustMyCode(&byte_3D5028);
  j__strcpy(&Str, Source);
  if ( j__strlen(&Str) < 8 )
    return 0;
  dword_3D1E9C |= 0x10000000u;
  if ( Str >= *(&Str + 2) )
    dword_3D1E9C |= 0x88u;
  if ( *(&Str + 2) >= *(&Str + 4) )
    dword_3D1E9C |= 0x90u;
  if ( *(&Str + 4) >= *(&Str + 6) )
    dword_3D1E9C |= 0xA0u;
  if ( !sub_2F8232(&Str) )
    dword_3D1E9C = 1;
  if ( !sub_2F8232(&unk_3D1E96) )
    dword_3D1E9C ^= 8u;
  if ( !sub_2F8232(&unk_3D1E98) )
    dword_3D1E9C ^= 0x10u;
  if ( !sub_2F8232(&unk_3D1E9A) )
    dword_3D1E9C ^= 0x20u;
  return dword_3D1E9C == 0x10000039;
}
int __cdecl sub_2F6E78(char *Source)
{
  return sub_2FC500(Source);
}
BOOL __cdecl sub_2FC500(char *Source)
{
  __CheckForDebuggerJustMyCode(&byte_3D5028);
  j__strcpy(&Str, Source);
  if ( j__strlen(&Str) < 8 )
    return 0;
  dword_3D1E9C |= 0x10000000u;
  if ( Str >= *(&Str + 2) )
    dword_3D1E9C |= 0x88u;
  if ( *(&Str + 2) >= *(&Str + 4) )
    dword_3D1E9C |= 0x90u;
  if ( *(&Str + 4) >= *(&Str + 6) )
    dword_3D1E9C |= 0xA0u;
  if ( !sub_2F8232(&Str) )
    dword_3D1E9C = 1;
  if ( !sub_2F8232(&unk_3D1E96) )

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//