フラグを復号してくれるのは良いけど,表示してくれない!!

解説

とりあえずGhidraで開きます

void main(int argc,char **argv,char **envp)

{
  int local_54;
  int local_50;
  char *local_48;
  long local_40;
  long local_38;
  long local_30;

  megaInit();
  local_30 = 9;
  _global_argv = argv;
  _global_argc = argc;
  _global_envp = envp;
  do {
    switch(local_30) {
    case 0:
      local_50 = 2;
      local_30 = 0xb;
      break;
    case 2:
      local_30 = _1_main_flag_func_0(local_38,-1,0x10,5);
      break;
    case 5:
      if (local_50 == 6) {
        local_30 = 0x12;
      }
      else {
        local_30 = 8;
      }
      break;
    case 6:
      if (local_40 == 0) {
        local_30 = 0;
      }
      else {
        local_30 = 0xb;
      }
      break;
    case 8:
      fwrite("prease not trace me...\n",1,0x17,stderr);
                    /* WARNING: Subroutine does not return */
      exit(1);
    case 9:
      local_54 = 0;
      local_30 = 10;
      break;
    case 10:
      switch(local_54) {
      case 0:
        local_30 = 0x16;
        break;
      case 1:
        local_30 = 0xf;
        break;
      case 2:
        local_30 = 0x13;
        break;
      case 3:
        local_30 = 0x14;
        break;
      case 4:
        local_30 = 0x11;
        break;
      case 5:
        local_30 = 0x15;
        break;
      default:
        local_30 = 0x12;
      }
      break;
    case 0xb:
      local_38 = ptrace(PTRACE_TRACEME,0,1,0);
      local_30 = 2;
      break;
    case 0xf:
      local_48 = (char *)malloc(0x10);
      local_30 = 0x12;
      break;
    case 0x10:
      local_50 = local_50 * 3;
      local_30 = 5;
      break;
    case 0x11:
      puts("flag decrypted. bye.");
      local_30 = 0x12;
      break;
    case 0x12:
      local_54 = local_54 + 1;
      local_30 = 10;
      break;
    case 0x13:
      generate_key(local_48);
      local_30 = 0x12;
      break;
    case 0x14:
      rc4(e,local_48);
      local_30 = 0x12;
      break;
    case 0x15:
                    /* WARNING: Subroutine does not return */
      exit(0);
    case 0x16:
      local_50 = 0;
      local_40 = ptrace(PTRACE_TRACEME,0,1,0);
      local_30 = 6;
    }
  } while( true );
}

rc4でフラグを復号したあと、そのアドレスをそのまま破棄しているようです
rc4の後に実行フローの制御に用いている変数の代入処理があるので、かわりに復号した値を出力する処理にすりかえてしまえばflagが得られそうです

ということでRC4の処理を行なった直後のアドレスである0x129cをCutterで開きます
そして、そこで編集→Instructionsで以下のアセンブリにすりかえます

mov rdi, rax ;
call 0x1040 ;

0x1040はsym.imp.putsのアドレスです

実行するとflagの表示処理が無限ループで回ります

ctf4b{d1d_y0u_d3crypt_rc4?}