首页
社区
课程
招聘
[原创]2019看雪CTF 团队赛 第六题 RepwnWP
发表于: 2019-3-21 15:24 3317

[原创]2019看雪CTF 团队赛 第六题 RepwnWP

2019-3-21 15:24
3317

用PEID扫描程序,使用了des算法

我们先看看sub_4013B0做了什么

用PEID扫描程序,使用了des算法


第二部分的flag会用到,这里先不看。
int __thiscall sub_4014C0(void *this)
{
  unsigned int v1; // ebx
  char *Str; // [esp+0h] [ebp-68h]
  char v4[4]; // [esp+10h] [ebp-58h]
  int v5; // [esp+20h] [ebp-48h]
  int v6; // [esp+24h] [ebp-44h]
  int v7; // [esp+28h] [ebp-40h]
  int v8; // [esp+2Ch] [ebp-3Ch]
  int v9; // [esp+30h] [ebp-38h]
  int v10; // [esp+34h] [ebp-34h]
  int v11; // [esp+38h] [ebp-30h]
  int v12; // [esp+3Ch] [ebp-2Ch]
  char v13; // [esp+40h] [ebp-28h]

  sub_404970(0x10u, (int)this, (int)Str);
  sub_4044F0();
  v1 = 0;
  v5 = 'yt^';
  v6 = '+pLc';
  v7 = 'a+SG';
  v8 = 'G-QG';
  v9 = 'Gl(V';
  v10 = ')y}J';
  v11 = 'SGA)';
  v12 = 'ea+';
  strcpy(v4, "Ansome_Is_Wrong");
  while ( v1 < strlen((const char *)&v5) )
    *((_BYTE *)&v5 + v1++) ^= 0x18u;
  puts("Please Input Your Key_ Now!");
  scanf("%s", &v13);
  if ( sub_4012F0((int)&v13) )
  {
    sub_401460(&v13);
    system("pause");
  }
  else
  {
    puts(v4);
  }
  return 0;
}
分析下sub_4012F0,sub_401460
int __thiscall sub_4014C0(void *this)
{
  unsigned int v1; // ebx
  char *Str; // [esp+0h] [ebp-68h]
  char v4[4]; // [esp+10h] [ebp-58h]
  int v5; // [esp+20h] [ebp-48h]
  int v6; // [esp+24h] [ebp-44h]
  int v7; // [esp+28h] [ebp-40h]
  int v8; // [esp+2Ch] [ebp-3Ch]
  int v9; // [esp+30h] [ebp-38h]
  int v10; // [esp+34h] [ebp-34h]
  int v11; // [esp+38h] [ebp-30h]
  int v12; // [esp+3Ch] [ebp-2Ch]
  char v13; // [esp+40h] [ebp-28h]

  sub_404970(0x10u, (int)this, (int)Str);
  sub_4044F0();
  v1 = 0;
  v5 = 'yt^';
  v6 = '+pLc';
  v7 = 'a+SG';
  v8 = 'G-QG';
  v9 = 'Gl(V';
  v10 = ')y}J';
  v11 = 'SGA)';
  v12 = 'ea+';
  strcpy(v4, "Ansome_Is_Wrong");
  while ( v1 < strlen((const char *)&v5) )
    *((_BYTE *)&v5 + v1++) ^= 0x18u;
  puts("Please Input Your Key_ Now!");
  scanf("%s", &v13);
  if ( sub_4012F0((int)&v13) )
  {
    sub_401460(&v13);
    system("pause");
  }
  else
  {
    puts(v4);
  }
  return 0;
}
分析下sub_4012F0,sub_401460
signed int __cdecl sub_4012F0(int a1)
{
  signed int v1; // ecx
  signed int v2; // edx
  int v4; // [esp+0h] [ebp-38h]
  int v5; // [esp+10h] [ebp-28h]

  v1 = 8;
  v2 = 0;
  strcpy((char *)&v5, "Your_Input_Is_Wrong");
  strcpy((char *)&v4, "X1Y0uN3tG00d");
  while ( *((_BYTE *)&v4 + v2) == *(_BYTE *)(v1 + a1) )
  {
    ++v2;
    ++v1;
    if ( v2 > 11 )
      return 1;
  }
  return 0;
}
sub_4012F0的代码比较简单,判断输入的key的8-12位是否为"X1Y0uN3tG00d"。
signed int __cdecl sub_4012F0(int a1)
{
  signed int v1; // ecx
  signed int v2; // edx
  int v4; // [esp+0h] [ebp-38h]
  int v5; // [esp+10h] [ebp-28h]

  v1 = 8;
  v2 = 0;
  strcpy((char *)&v5, "Your_Input_Is_Wrong");
  strcpy((char *)&v4, "X1Y0uN3tG00d");
  while ( *((_BYTE *)&v4 + v2) == *(_BYTE *)(v1 + a1) )
  {
    ++v2;
    ++v1;
    if ( v2 > 11 )
      return 1;
  }
  return 0;
}
sub_4012F0的代码比较简单,判断输入的key的8-12位是否为"X1Y0uN3tG00d"。
int __cdecl sub_401460(char *Str)
{
  char Dest; // [esp+8h] [ebp-10h]

  if ( strlen(Str) == 24 )
  {
    if ( sub_4013B0((int)Str) )
    {
      Str[20] -= 0x58;
      Str[21] -= 0x46;
      Str[22] -= 3;
      Str[23] -= 0x6B;
      strcpy(&Dest, Str);
    }
  }
  else
  {
    printf("String Length is Wrong");
  }
  return 0;
}
sub_401460先判断key是否为24位,那我们可以知道key应该是这种形式:xxxxxxxxX1Y0uN3tG00dxxxx。
int __cdecl sub_401460(char *Str)
{
  char Dest; // [esp+8h] [ebp-10h]

  if ( strlen(Str) == 24 )
  {
    if ( sub_4013B0((int)Str) )
    {
      Str[20] -= 0x58;
      Str[21] -= 0x46;
      Str[22] -= 3;
      Str[23] -= 0x6B;
      strcpy(&Dest, Str);
    }
  }
  else
  {
    printf("String Length is Wrong");
  }
  return 0;
}
sub_401460先判断key是否为24位,那我们可以知道key应该是这种形式:xxxxxxxxX1Y0uN3tG00dxxxx。
之后在sub_4013B0继续处理flag,处理完以后将key后4位的值分别减去不同的值,用strcpy覆盖掉堆栈里的返回地址。

我们先看看sub_4013B0做了什么

int __cdecl sub_4013B0(int a1)
{
  int v1; // ebx
  int v2; // ecx
  int v3; // esi
  int result; // eax

  sub_401380(a1);                               // 只能输入十进制整数
  v1 = key4 + 1000 * key1 + 100 * key2 + 10 * key3;
  v2 = key6 + 10 * key5;
  v3 = key8 + 10 * key7;
  result = 2 * (v1 + v2);
  if ( result == 4040 )
  {
    result = 3 * v2 / 2;
    if ( result + 100 * v3 == 115 )
    {
      result = 1;
      if ( v1 - 110 * v3 != 1900 )
        result = printf("Key_Is_Wrong,Please_Input_Again!");
    }
  }
  return result;
}
int __cdecl sub_4013B0(int a1)
{
  int v1; // ebx
  int v2; // ecx
  int v3; // esi
  int result; // eax

  sub_401380(a1);                               // 只能输入十进制整数
  v1 = key4 + 1000 * key1 + 100 * key2 + 10 * key3;
  v2 = key6 + 10 * key5;
  v3 = key8 + 10 * key7;
  result = 2 * (v1 + v2);
  if ( result == 4040 )
  {
    result = 3 * v2 / 2;
    if ( result + 100 * v3 == 115 )
    {
      result = 1;
      if ( v1 - 110 * v3 != 1900 )
        result = printf("Key_Is_Wrong,Please_Input_Again!");
    }
  }
  return result;
}
sub_401380是将前8位key都减去0x30,然后添加到全局变量地址里面,这里我把地址重新命名了。
要算出key,我们可以先列出关于v1,v2,v3的方程组
2 v1 + 2 v2 = 4040
2 v1 + 2 v2 = 4040
1.5 v2 + 100 v3 = 115
v1 - 110 v3 = 1900
可解得v1=2010,v2=10,v3=1

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

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