• 看雪CTF第十题


    __int64 sub_140006F50()
    {
      __int64 v0; // r8@1
      __int64 v1; // r9@1
      signed __int64 len; // rax@1
      __int64 v3; // r8@4
      __int64 i; // rdx@4
      char anscii; // cl@5
      char v6; // al@9
      int v7; // eax@14
      const char *v8; // rcx@14
      char rp_rsa_zhishu(n); // [sp+20h] [bp-18h]@12
    
      print_140006EA0("=========================================================================
    ");
      print_140006EA0("                     看雪CTF2017 CrackMe by 海风月影
    
    ");
      print_140006EA0(&unk_14004BF18);
      input_140006F00((__int64)&unk_14004BF2C, (__int64)input_key, v0, v1);
      print_140006EA0(&unk_14004BF30);
      len = -1i64;
      do
        ++len;
      while ( input_key[len] );
      if ( (_DWORD)len == 70 )                      // 长度70
      {
        v3 = 0i64;
        i = 0i64;
        while ( 1 )
        {
          anscii = input_key[i];
          if ( (unsigned __int8)(anscii - 48) > 9u && (unsigned __int8)(anscii - 65) > 031u )// 检查输入字符是否数字或大写字母
            break;
          if ( ++i >= 70 )
          {
            *(_DWORD *)input_key_before6 = *(_DWORD *)input_key;// 输入的前6位字符串  rsa_e
            *(_WORD *)input_key_before6_4 = *(_WORD *)_input_key_4_;
            do
            {
              v6 = input_key[v3 + 6];
              input_key_after6[v3++] = v6;          // 输入的第6位后的64位字符串  rsa_q
            }
            while ( v6 );                           // 初始化rop,并赋值rop = str,其中str是一个表示base进制整数的字符数组
            mpz_init_set_str(&rp_rsa_e, input_key_before6, 16i64);// mpz_init_set_str (mpz_t r, const char *sp, int base)
            mpz_init_set_str(&rp_rsa_p, input_key_after6, 16i64);// mpz_init_set_str (mpz_t r, const char *sp, int base)
            if ( mpz_probab_prime_p(&rp_rsa_p, 500i64) )// mpz_probab_prime_p (const mpz_t n, int reps)
            {                                       // 检测n是否为素数。该函数首先对n进行试除,然后使用米勒-拉宾素性检测对n进行测试,reps表示进行检测的次数。如果n为素数,返回2;如果n可能为素数,返回1;如果n为合数,返回0。
              if ( mpz_probab_prime_p(&rp_rsa_e, 500i64) )
              {                                     // 初始化rop,并将其值设置为op
                mpz_init_set_ui(&rp_rsa_q, 0i64);   // mpz_init_set_ui (mpz_t r, unsigned long int x)
                mpz_init_set_str(
                  &rp_rsa_n,
                  "6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE941C7AA288095F33BC4B255FD983114D480EFFBEE"
                  "2E313E6218A57F9CCC8189",
                  16i64);
                mpz_init_set_str(
                  &rp_rsa_d,
                  "2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D381925EB40CFED8FBE894570155E41569B4EC69"
                  "B26CB0320105A29651CB4B",
                  16i64);
                mpz_init_set_ui(&rp_rsa_zhishu(n), 0i64);// 置 r 为 n mod d
                mpz_mod(&rp_rsa_zhishu(n), &rp_rsa_n, &rp_rsa_p);// mpz_mod (mpz_t r, const mpz_t n, const mpz_t d)
                if ( !(unsigned int)mpz_cmp_si((__int64)&rp_rsa_zhishu(n), 0i64) )// mpz_cmp_si (const mpz_t a, const mpz_t b)
                {
                  // 置 q 为 n/d。 只有预先知道 d 是整除 n 的, 这些函数才返回正确的结果。
                  // 这里使用的程序比其他的除法函数的快得多, 当确知整除发生时它是最好的选
                  // 择, 例如化简有理数为最小项时
                  mpz_divexact(&rp_rsa_q, &rp_rsa_n, &rp_rsa_p);// mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d)
                  // 比较 op1 和 op2。 若 op1 > op2 则返回正值, 若 op1 = op2 则返回 0, 若 op1 <
                  // op2 则返回负值。
                  // 需要注意的是 mpz_cmp_ui 和 mpz_cmp_si 是宏, 它们可能对参数估值一次以
                  // 上。
                  if ( mpz_cmp(&rp_rsa_p, &rp_rsa_q) <= 0 )// mpz_cmp (const mpz_t a, const mpz_t b)
                  {
                    // N = (p-1)*(q-1)
                    mpz_sub_ui(&rp_rsa_p, (__int64)&rp_rsa_p, 1ui64);// mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
                    mpz_sub_ui(&rp_rsa_q, (__int64)&rp_rsa_q, 1ui64);
                    mpz_mul(&rp_rsa_zhishu(n), &rp_rsa_p, &rp_rsa_q);// mpz_mul (mpz_t r, const mpz_t u, const mpz_t v)
                    // 计算 op1 模 op2 的逆, 并将结果置于 rop。 如果逆存在则返回非 0 值, 且 rop 满
                    // 足 0 ? rop < op2。 如果逆不存在, 那么返回 0, 此时 rop 是无意义的
    
                    // e的 φ(n)-1 次方,就是e的模反元素。
                    mpz_invert((__int64)&rp_rsa_zhishu(n), (__int64)&rp_rsa_e, (__int64)&rp_rsa_zhishu(n));// mpz_invert (mpz_t r, const mpz_t u, const mpz_t m)
                    v7 = mpz_cmp(&rp_rsa_d, &rp_rsa_zhishu(n));
                    v8 = "注册成功!!!
    
    ";
                    if ( !v7 )
                      goto LABEL_16;
                  }
                }
              }
            }
            break;
          }
        }
      }
      v8 = "注册失败
    
    ";
    LABEL_16:
      print_140006EA0(v8);
      sub_14002D1B4("pause");
      return 0i64;
    }

    分析发现这是RSA算法,提供了N和D,输入e和p进行匹配。其计算公式如下:

    q=n/p
    N = (p-1)*(q-1)
    d1 = invert(e,N)
    d1 == d?

    其中的invert是求模反元素的函数调用。

  • 相关阅读:
    读书
    Web前端知识体系精简
    让你分分钟理解 JavaScript 闭包
    常用 Git 命令使用教程
    js库写法
    Gitlab的使用
    appium-环境搭建(一)
    Selenium-几种等待方式
    Selenium-免登录的实现
    Selenium-百度登录简单例子
  • 原文地址:https://www.cnblogs.com/qintangtao/p/7193864.html
Copyright © 2020-2023  润新知