这是一道内部测试的ctf题目,源程序的md5是72361DC65F1A1735E6ACA86F3B711EF0


观察程序

首先观察程序的运行周期,搜集一些前期数据

程序运行起来就会直接向用户索取密钥

image-20200417104128716.png

校验失败就会重新循环

从这里可以提取出一个关键的字符串Enter your Password:

寻找main函数

  1. 利用ida加载程序后发现找不到main函数
  2. 并且这是一个x64的程序
  3. 根据main函数的调用约定 手动寻找main函数

找到的main函数如下

image-20200417104654646.png

分析程序逻辑

接下对main函数稍加分析可以得到如下的分析报告

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char str_flag; // [rsp+30h] [rbp-58h]
  char v5; // [rsp+50h] [rbp-38h]

  sub_140001850((__int64)&v5, (__int64)".data");
  sub_1400018E0(&str_flag);
  while ( 1 )
  {
    system("cls");
    std_io(std::cout, "\n\n\n ");
    std_io(std::cout, "Please get the password! ");
    std_io(std::cout, "\n\n\n ");
    std_io(std::cout, "Enter your Password: ");
    sub_140002620(std::cin, &str_flag);         // 关键点:提示用户输入
    if ( (unsigned __int8)sub_140002650((__int64)&str_flag, (__int64)&v5) )// 这里明显是一个比对函数,想办法获取到 v5
      break;
    std_io(std::cout, "\n\n ");
    std_io(std::cout, "\n\n ");
  }
  std_io(std::cout, "\n\n ");
  std_io(std::cout, "The password is the flag! ");
  std_io(std::cout, "\n\n ");
  system("pause");
  sub_140001820(&str_flag);
  sub_140001820(&v5);
  return 0;
}

观察代码可以发现,程序的核心是 16行代码,明显是在比对,那么v5很有可能就是 这题的答案,有两个方案获取目标数据 v5

  1. 动态调试
  2. 分析函数 sub_140001850
  3. 通过参数分析,以及程序逻辑这里 猜测 sub_140001850是字符串复制

静态分析函数sub_140001850 会发现比较复杂,这里采用动态调试

image-20200417151916977.png

那么到这里就可发现v5就是字符串.data,因此sub_140001850就是一个字符串复制的函数

flag

.data

Last modification:April 17, 2020
如果觉得我的文章对你有用,请随意赞赏