2016kxctf第19题

2016kxctf第19题

Posted by gxkyrftx on January 6, 2019

0.前言

1.程序分析

1.0 关闭aslr

方法使用CFF,具体操作见 http://gxkyrftx.xyz/2019/01/04/2016kxctf%E7%AC%AC28%E9%A2%98/ 中的1.0

1.1 main

比较短,就直接放出来了

 n_8v1 = 0;
  v0 = 65;
  v1 = "A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D";// 这是一个大整数
  do                                            // do——while循环,把上面的大数加载到内存
  {
    v2 = (unsigned __int8)byte_4281B0[v0];
    shift(&n_8v1, &n_8v1);
    push(v2);
    v0 = (v1++)[1];
  }
  while ( v0 );
  v3 = (void (*)(const char *, ...))printf;
  printf("Please input username:");
  memset(username, 0, 0x2800u);
  sscanf("www.51asm.com", "%s", username);
  printf("%s\n", "www.51asm.com");
  init_username(username, strlen(username));
  printf("Please input vericode:");
  memset(username, 0, 0x2800u);
  scanf("%s", username);
  v4 = 0;
  v5 = strlen(username);
  if ( v5 )                                     // if判断,输入的字符串是否含有非法输入
  {
    while ( 1 )
    {
      v6 = username[v4];
      if ( (unsigned __int8)(v6 - '0') > 9u && (unsigned __int8)(v6 - 'a') > 25u && (unsigned __int8)(v6 - 'A') > 25u )
        break;
      if ( ++v4 >= v5 )
        goto LABEL_8;
    }
    printf("Invalid char found in input string");
    getch();
    result = 0;
  }
  else
  {
LABEL_8:
    v7 = username[0];
    n_8v8 = 0;
    if ( username[0] )
    {
      v8 = username;
      do                                        // 把输入也加入内存
      {
        v9 = (unsigned __int8)byte_4281B0[v7];
        shift(&n_8v8, &n_8v8);
        push(v9);
        v7 = (v8++)[1];
      }
      while ( v7 );
      v3 = (void (*)(const char *, ...))printf;
    }
    v3("\ninput accepted as:\n");
    Size = 10240;
    change_to_ascii(&n_8username, username);    // 变为ascii码
    v3("Username : %s\n", username);
    Size = 10240;
    change_to_ascii(&n_8v8, username);
    v3("Vericode : %s\n", username);
    v3("\nverifying...\n");
    sub_403E30(&n_8username);
    sub_403E30(&n_8v8);
    if ( sub_401510() )
      v3("%s\n", &unk_448EB5);
    else
      v3("failed\n");
    getch();
    result = 0;
  }
  return result;
}

1.2 问题

1.此题ida反编译出来的有点问题,反编译的结果跟正确的对不上,有几个函数参数是不对的

2.还有一些莫名其妙的问题,很长时间都没解决。函数无法反编译,这还怎么分析。。

1

1.3 程序流程

根据大佬wp直接贴出程序的验证流程,大佬wp https://bbs.pediy.com/thread-214562.htm

1.3.1 rsa算法

这个密码学学过。

1.选取两个强伪素数p和q。
2.计算φ(n)=(p-1)x(q-1)
3.选一个素数e,使(e,φ(n))=1。
4.计算e x d≡1 mod(φ(n)) 加密过程

c≡m^e(mod n) 解密过程

m=c^d(mod n)

1.3.2 本题中的e

通过用户名和17生成e,即:username^17%N = e,这里N为 A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D,以下所有的N都为此大数。可以通过动态调试直接看到

2

e=9CA87DE3775787F7695F3F316E503600348AB6F58BEF375D0ED8F8BE84425FA7A6C3

e 循环 0 - 0x63,且每次e + 1,对sn 进行解密,解密后结果与 “Happy Birthday Buddy” 比较,成功则返回 1

1.3.3 本题中的n

n=A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D

尝试分解n

十进制n=4836049822470645700707675549457249771340211537787234319173530875014794666294415181

分解后的p=62822928286347608648869628628072621308819。q=76979057716441943100156208562083628995999

十六进制表示p=B89EB7E0C9A568202F38B169D9D7E27B93,q=E2389B3C140BE6423EE5EB9DB5DAC2559F

得到d=1744216077318152194595333927534931955784044014454366651043557545108022731860010209

十六进制d=3AD75813052BC545DAC589519734FF0972200E8E31DFA08DE50D15CFA2667132E4E1

3

2.解题

将“Happy Birthday Buddy\x0ok”转换为16进制,并且反向排列,结果为

正向:4861707079204269727468646179204275646479306f6b
反向:6B6F007964647542207961646874726942207970706148
10进制:10290094653093735596660535282149174213262877870668144968

使用CrpTool计算十进制sn和Big Interger calculator转换16进制 结果如下

4

3.后续

这个题目调试有问题,以后调试手段熟练了,重新编辑一下,找不到问题在哪,难受。


本文访问量: