首页
社区
课程
招聘
[原创] 签到题writeup
2021-5-10 16:32 1435

[原创] 签到题writeup

2021-5-10 16:32
1435

静态分析

先将程序拖入IDA分析,发现main函数中间有一部分没有被识别成代码,使用快捷键强制转换成代码也分析不出来。

看起来很像加密的shellcode。解密shellcode的逻辑应该就在这段数据的上方。解密shellcode的逻辑大致来说就是一个循环,中间有一些解密算法。向上看有一个函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __usercall sub_401470@<eax>(unsigned int a1@<edx>, _DWORD *a2@<ecx>, int a3)
{
  unsigned int v3; // edx
  int result; // eax
 
  v3 = a1 >> 2;
  if ( v3 )
  {
    result = a3;
    do
    {
      *a2 ^= a3;
      ++a2;
      --v3;
    }
    while ( v3 );
  }
  return result;
}

这个循环异或就很像。要还原出代码就很简单了。

动态调试

载入x64dbg,运行到这个函数直接单步步过。程序中校验flag的代码就直接解密出来了,然后将调用这个函数的call直接nop掉。再用Scylla dump一下就可以了。

 

最后一步

将dump出来EXE拖入IDA重新分析一下,main函数结果如下(为方便观看,部分函数变量名重命名过了):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  int v4; // [esp+1Ch] [ebp-22Ch]
  char Dst; // [esp+3Dh] [ebp-20Bh]
  char input_flag[256]; // [esp+13Ch] [ebp-10Ch]
  int v7; // [esp+23Ch] [ebp-Ch]
  __int16 v8; // [esp+240h] [ebp-8h]
 
  input_flag[0] = 0;
  memset(&input_flag[1], 0, 0xFFu);
  memset(&Dst, 0, 0xFFu);
  printf("KCTF 2021 春季赛!\n");
  printf("http://bbs.pediy.com\n");
  printf("Please input your flag: ");
  scanf_s("%s", input_flag, 256);
  if ( &input_flag[strlen(input_flag) + 1] - &input_flag[1] == 12 )
  {
    if ( input_flag[0] != 'f'
      || input_flag[1] != 'l'
      || input_flag[2] != 'a'
      || input_flag[3] != 'g'
      || input_flag[4] != '{'
      || input_flag[11] != '}' )
    {
      goto LABEL_16;
    }
    v7 = *(_DWORD *)&input_flag[5];
    v8 = *(_WORD *)&input_flag[9];
    sub_401000();
    v4 = strcmp(sub_401050(input_flag, 12), "ZmxhZ3trYW54dWV9");
    if ( v4 )
      v4 = -(v4 < 0) | 1;
    if ( v4 )
    {
LABEL_16:
      printf("Try again!\n");
      result = -1;
    }
    else
    {
      printf("You are winner!\n");
      result = 0;
    }
  }
  else
  {
    printf("Try again!\n");
    result = -1;
  }
  return result;
}

分析过后发现程序只要经过将flag通过sub_401050处理过后与字符串“ZmxhZ3trYW54dWV9”比较。第一时间就猜到了base64(毕竟签到题难度不会太高),然后看了一下这个函数的逻辑,果然就是base64。然后就很简单了,直接解下base64就能得出flag.

 

最后将dump的exe放在附件中。


[培训]《安卓高级研修班(网课)》月薪三万计划

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回