NCTU BCG crackme 解题报告

Reading time ~1 minute

今天又来试着做NCTU,于是乎挑了这道题,题目描述如下:

BCG's full name is BeGiNnEr'S CrAcKiNg Group....

Do you have the ability to crack this program?.... 

press "start" then download it!

Hint1: The checkin key is the "content"...

Hint2: key length is the asked length, and all character is same as the first one.

这道题做完之后确实的说,也是挺简单的,但由于自己还是太弱,做的时候就没有这么顺利了。

首先打开程序,会发现上面有着各种说明,似乎这题是BCG申请加入时的题,程序上写的那些限制我也没太弄明白,不过这里既然只是解题,就不管了。

IDA反汇编程序会发现,程序只有一个很短的start,感觉应该是自解压的程序,于是乎先打开程序,再将OD附加到该程序上便开始调试。然而,尝试了半天之后,还是没有什么收获,一直没能看到什么关键代码。

实在无奈之下,用PEiD查了下,发现是有个aspack壳,于是在网上找了个脱壳软件将壳脱掉,再用IDA查看,顿时感觉就是柳暗花明。

程序很明确,一眼就看到关键程序,用IDA反编译得:

int __stdcall DialogFunc(HWND hDlg, int a2, int a3, int a4)
{
  int result; // eax@4
  int v5; // eax@14

  if ( a2 == 273 )
  {
    if ( a3 == 1 )
      return MessageBoxA(0, "中, "OfficialCrackme", 0x1000u);
    if ( a3 == 2 )
      return EndDialog(hDlg, 0);
    if ( a3 != 3 )
      return 0;
  }
  else
  {
    if ( a2 != 272 )
    {
      if ( a2 != 16 )
        return 0;
      return EndDialog(hDlg, 0);
    }
    SetDlgItemTextA(hDlg, 10, String);
  }
  hFile = CreateFileA("[BCG].Key", 0xC0000000u, 3u, 0, 3u, (DWORD)"€", 0);
  if ( hFile == (HANDLE)-1 )
    goto LABEL_22;
  if ( !ReadFile(hFile, (LPVOID)&String2, 0xAu, &NumberOfBytesRead, 0) )
    goto LABEL_22;
  if ( !ReadFile(hFile, String1, 0xAu, &NumberOfBytesRead, 0) )
    goto LABEL_22;
  CloseHandle(hFile);
  v5 = 0;
  do
  {
    *(&String2 + v5) ^= 0x58u;
    ++v5;
  }
  while ( *(&String2 + v5) );
  if ( !lstrcmpA(String1, &String2) )
    result = MessageBoxA(0, "注册验证成功,恭喜, "OfficialCrackme", 0x1000u);
  else
LABEL_22:
    result = MessageBoxA(0, "革, "OfficialCrackme", 0x1000u);
  return result;
}

程序流程很清楚,是从[BCG].Key中读出两个长度为0xA的字符串,然后其中一个字符串与0x58异或之后的结果正好要为另一个字符串,那我们可以取'0' xor 'h',于是在文件中写入hhhhhhhhhh0000000000,再尝试运行程序。可是,结果却与我们的预期大相径庭,还是告诉我们“革命尚未成功”。

下断点再调试程序发现,String2和String1在内存空间上正好相距10,也就是说String2的后面没有字符串结尾标志,这样导致异或的时候String2和String1都被异或的,这还不止,在lstrcmpA的时候,更是认为String1是String2的字串了,那么看来,这两个字符串肯定不会相等了。

为了解决这个问题,第一想法就是在文件中写入,然String2并不能真正读入10个字符或者说让第10个字符为,但这样且不说是否可行,但至少是相当麻烦的,那再仔细想想会发现,如果我们输入的String2中有字符X(即0x58),那么异或的时候就会产生,这样在lstrcmpA的时候,两个字符串就可以相等了。

那么,我们直接在文件中写入20个X,运行程序便成功弹出正确的提示框,得以解决。

PS:chekckin的时候需要注意,是提交10个X即可,不要提交20个,这问题坑了我半天……

bcgcrackme.rar

挂载网络文件夹后网络故障时文件操作命令卡死

挂载 NFS 或者 Samba 的时候,经常会由于网络故障导致挂载好的链接断掉。此时如果尝试进行 ls、cd、df 等各种命令,只要与此目录沾上边,就会卡住。如果使用了类似 oh-my-zsh 这种配置的,只要在网络目录中,弹出命令提示符前就会直接卡住。这个时候第一反应就是...… Continue reading

路由折腾记 第四弹

Published on September 02, 2017