首页
社区
课程
招聘
[原创] CTF2019 Q3 readyu crackme 第十三题:大圣归来 题目与设计思路
发表于: 2019-8-27 00:00 9326

[原创] CTF2019 Q3 readyu crackme 第十三题:大圣归来 题目与设计思路

2019-8-27 00:00
9326

[原创] CTF2019 Q3 readyu crackme 设计思路

密码学题目, VC++6编译的Win32程序。取名“完璧归赵”。

(1) 序列号
这个程序默认只有一个SN,用户名内置为username。输入正确的SN提示good,错误的SN提示bad。

本题唯一序列号SN为:
usernameKXCTFXXXX753350C5A24300015025083AFBAE5D206A7D83E2C7F98D09ADB6EF51ACFDC83

就方程本身而言,每个name有1个key。格式为 ( || 表示字符串相加 ):

key = name || KXCTFXXXX || M0
彩蛋(额外赠送的)进入方式:
(a) SN验证通过,再点击2下,可进入解锁模式,可针对不同的用户名验证SN。
{ V_e2 [ V_e1(M0 + h1) + h2 ]  +  h4 } = h3   mod N   ... (a)

M0 = { V_d1 [ V_d2 (h3 - h4) - h2 ]  - h1  }  mod N   ... (b)
在本题中, V_e(m) mod N是Lucas序列函数的V序列, 或者简写为 Lucas V_e(m,1) mod N 。
参考luc公钥系统, 对公钥e有非对称解d, 可以求逆 (V可类比RSA的幂模运算)。
从而,这道题就可以求解了。具体求解代码,参见附件keygen的cpp源代码。 

说明: 公开的论文认为luc强度与RSA相当,至少不弱于RSA。
但是luc计算速度要慢于RSA。 Lucas序列采用迭代算法,比RSA的快速幂模运算步骤要多,速度慢了不止一倍。所以实际上应用并不多。

Lucas序列有一些有趣的性质。参见(5)参考文档,或者wiki:

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-9-25 14:18 被readyu编辑 ,原因:
上传的附件:
收藏
免费 4
支持
分享
最新回复 (7)
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
2
crackme_CTF19Q3_132K.exe

Size: 135168 bytes

MD5: 47A01296CF25832D67B43256DDC88B40
SHA1: 996B335E5EACFE381A53C252F8E3C5B499A51829
CRC32: 7B9CE11F

最后于 2019-8-31 23:11 被readyu编辑 ,原因:
2019-8-27 09:41
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
3
keygen和crackme都更新了。
2019-9-1 08:10
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
4
/*
KANXUE/PEDIY KCTF2019Q3  crackme's keygen
by Readyu @201908

based on: Lucas pubkey system
*/
#include <Windows.h>
#include "big.h"
#include "sha1.h"

#ifdef __cplusplus
extern "C" {
#endif    
#include "miracl.h"
#pragma comment( lib, "miracl531.lib" )
#ifdef __cplusplus
}
#endif

using namespace std;

Big lcm( const Big &X , const Big &Y )
{
  Big g = X/gcd(X, Y);
  g *= Y;
  return g;
}

string  calc_sn(string head, string name, string kxctf, bool uselcm)
{
    Miracl precision(1024, 2);     /* include MIRACL system */
    mr_mip->IOBASE=16;

    unsigned char hash[5][20] = {0};
    char key[1024] = {0}, buf[4096] = {0},  sm0[1024] = {0};
    Big h[5], m[4], n, d[3], bnkey, phi, p, q, r, e[3];
 
    string body = head, tail="完璧归赵";  
    body.append(name);
    
    sha160_hash(head.data(), head.size(), hash[1]);
    sha160_hash(name.data(), name.size(), hash[2]);
    sha160_hash(body.data(), body.size(), hash[3]);
    sha160_hash(tail.data(), tail.size(), hash[4]);
    
    for(int i = 1; i <= 4; i++)
        h[i] = from_binary(20, (char *)hash[i]);

    // sha256 固定的,无需动态计算。
    // n = sha-256("完璧归赵完璧归赵") = sha256(CDEAE8B5B9E9D5D4CDEAE8B5B9E9D5D4)
    // 3fbdad083dbc11a52fa2af1a0829c522c1492907f1b9523a17b7a8e65679bb01
   // factor(n),  n= p*q*r
    n = "3fbdad083dbc11a52fa2af1a0829c522c1492907f1b9523a17b7a8e65679bb01";
    p = "1F7BF";
    q = "F1059E73CFB296F8B";
    r = "2267D9CC91A552E23D284260B563CE490B0F7475F9D";
    phi = (p-1)*(p+1)*(q-1)*(q+1)*(r-1)*(r+1);

    if(uselcm == 1)
        phi = lcm(p-1, lcm(p+1, lcm(q-1, lcm(q+1, lcm(r-1, r+1)))));

    // 20 bytes FF  |  KXCTF19Q3
    // "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B5843544631395133" ;
    string s_e1(20, (unsigned char)0xFF);
    s_e1.append(kxctf);
    e[1] = from_binary(s_e1.size(), (char *)s_e1.data());;
    e[2] = n;

    // get d[1], d[2]
    d[1] = inverse(e[1], phi) ;
    d[2] = inverse(e[2], phi) ;
    
/*   对方程1 做逆运算即可得到M0 , 即 方程2
(1) verify:   { V_e2 [ V_e1(M0 + h1) + h2 ]  +  h4 } = h3   mod N

(2) sign:    M0 = { V_d1 [ V_d2 (h3 - h4) - h2 ]  - h1  }   mod N
*/
    // lucas round 1
    m[3] = (n + h[3] - h[4]) % n;
    m[2] = luc(m[3], d[2], n, NULL);

    // lucas round 2
    m[1] = (n + m[2] - h[2]) % n;
    m[0] = luc(m[1] , d[1], n, NULL);

    // ok, get key
    bnkey = (n + m[0] - h[1]) % n;
    key << bnkey;
    sm0 << m[0];
    sprintf(buf, "head=%s\nname=%s\nm[0]=%s\nkey=\n%sKXCTFXXXX%s", head.c_str(), name.c_str(), sm0, name.c_str(), key);
    return string(buf);
}

int main(int argc, char ** argv)
{
    string head = "PEDIY_CTF2019_Q3_完璧归赵_Crackme_Readyu_";
    string name = "username";
    string kxctf = "KXCTF19Q3";

    printf("%s\n\n",  calc_sn(head, "username", kxctf, 0).c_str());
    printf("%s\n\n",  calc_sn(head, "KCTF", kxctf, 0).c_str());
    printf("%s\n\n",  calc_sn(head, "蔺相如", kxctf, 0).c_str());
    printf("%s\n\n",  calc_sn(head, "廉颇", kxctf, 0).c_str());

    printf("%s\n\n",  calc_sn(head, "username", kxctf, 1).c_str());
    printf("%s\n\n",  calc_sn(head, "KCTF", kxctf, 1).c_str());
    printf("%s\n\n",  calc_sn(head, "蔺相如", kxctf, 1).c_str());
    printf("%s\n\n",  calc_sn(head, "廉颇", kxctf, 1).c_str());
    getchar();
    return 0;
}

2019-9-25 10:44
0
雪    币: 10845
活跃值: (1054)
能力值: (RANK:190 )
在线值:
发帖
回帖
粉丝
5
佩服
2019-9-25 12:43
0
雪    币: 6839
活跃值: (3714)
能力值: ( LV13,RANK:1664 )
在线值:
发帖
回帖
粉丝
6
楼主,我能说我很想和你认识一下吗?Q2和Q3都是卡在你的题目上面,让别人绝地翻盘,欲哭无泪啊。
2019-9-26 01:44
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
7
looklook队 半夜攻题,实在太猛了啊
最后于 2019-9-26 13:19 被readyu编辑 ,原因:
2019-9-26 13:17
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
8
xym 楼主,我能说我很想和你认识一下吗?Q2和Q3都是卡在你的题目上面,让别人绝地翻盘,欲哭无泪啊。
@xym,   Q4 你一举成功,tql
2019-12-23 17:01
0
游客
登录 | 注册 方可回帖
返回
//