首页
社区
课程
招聘
[原创]CTF2017 第十题 海风月影cm 解题报告
2017-6-20 22:02 4354

[原创]CTF2017 第十题 海风月影cm 解题报告

2017-6-20 22:02
4354

CTF2017 第十题 海风月影cm

反汇编

通过查看字符串发现用的是 gmp 库,对比源码分析出程序 main 函数

int main(int argc, char* argv[])
{
  printf("=========================================================================\n");
  printf("                     看雪CTF2017 CrackMe by 海风月影\n\n");
  printf("    请输入序列号:");
  scanf("%s", iptkey);
  printf("\n\n");
  keylen = -1i64;
  do
    ++keylen;
  while ( iptkey[keylen] );
  if ( (_DWORD)keylen == 70 )
  {
    j = 0i64;
    i = 0i64;
    while ( 1 )
    {
      cc = iptkey[i];
      if ( (unsigned __int8)(cc - '0') > 9u && (unsigned __int8)(cc - 'A') > 25u )
        break;                                  // 要求数字和大写字母
      if ( ++i >= 70 )
      {
        *(_DWORD *)hex_x = *(_DWORD *)iptkey;
        *(_WORD *)&hex_x[4] = *(_WORD *)&iptkey[4];// 注意这里 hex_x 只有 6 字节
        do
        {
          v8 = iptkey[j + 6];
          hex_y[j++] = v8;
        }
        while ( v8 );                           // hex_y 有 70-6 = 64 字节
        mpf_init_set_str(&x, hex_x, 16u);
        mpf_init_set_str(&y, hex_y, 16u);
        if ( mpz_millerrabin(&y, 500u) )        // 检测是素数
        {
          if ( mpz_millerrabin(&x, 500u) )
          {
            mpf_init_set_si(&z, 0i64);
            mpf_init_set_str(
              &p,
              "6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE941C7AA288095F33BC4B255FD983114D480EFFBEE"
              "2E313E6218A57F9CCC8189",
              16u);
            mpf_init_set_str(
              &q,
              "2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D381925EB40CFED8FBE894570155E41569B4EC69"
              "B26CB0320105A29651CB4B",
              16u);
            mpf_init_set_si(&t, 0i64);
            mpz_mod(&t, &p, &y);
            if ( !(unsigned int)mpz_cmp_ui(&t, 0i64) )// p % y == 0
            {
              mpz_divexact(&z, &p, &y);         // z = p / y  ->   p = y * z
              if ( (signed int)mpz_cmp(&y, &z) <= 0 )// y <= z  注意 y 比 z 小
              {
                mpz_sub_ui(&y, &y, 1ui64);
                mpz_sub_ui(&z, &z, 1ui64);
                mpz_mul(&t, &y, &z);            // t = (y - 1) * (z - 1)
                mpz_invert(&t, &x, &t);
                ok = mpz_cmp(&q, &t);           // q * x = 1 (mod t)
                msg = "注册成功!!!\n\n";
                if ( !ok )
                  goto LABEL_16;
              }
            }
          }
        }
        break;
      }
    }
  }
  msg = "注册失败\n\n";
LABEL_16:
  printf((char *)msg);
  system("pause");
  return 0i64;
}

解题

这题和第八题差不多都是考的同余式的一些性质和相关定理,如果你看了我第八题的解题报告,应该也能解出这道题

代码

import gmpy2
p = long("6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE941C7AA288095F33BC4B255FD983114D480EFFBEE2E313E6218A57F9CCC8189", 16)
q = long("2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D381925EB40CFED8FBE894570155E41569B4EC69B26CB0320105A29651CB4B", 16)
tmp1 = tmp2 = gmpy2.powmod(2, q, p)
for x in xrange(1, 0xFFFFFF):
    if tmp2 == 2:
        break
    # 这里用余等性质枚举比每次都模幂要快
    tmp2 = tmp2 * tmp1 % p
print "x:", x
tmp1 = x * q - 1
n = 1
while True:
    if tmp1 % n == 0:
        t = tmp1 / n
        if t < p:
            break
    n += 1
print "n:", n
m = p - t + 1
y = (m - gmpy2.isqrt(m*m - 4*p)) / 2
# 输出结果
print "key:", (hex(x)[2:].rstrip("L") + hex(y)[2:].rstrip("L")).upper()



[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!

收藏
免费 3
打赏
分享
最新回复 (1)
雪    币: 10477
活跃值: (2515)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
joker陈 2017-6-22 08:42
2
0
无愧是精华啊,欧拉这人真牛逼
游客
登录 | 注册 方可回帖
返回