首页
社区
课程
招聘
[原创]看雪CTF2017 第二题分析
发表于: 2017-6-4 12:01 2893

[原创]看雪CTF2017 第二题分析

2017-6-4 12:01
2893

ida pro 打开,来到main函数

  fgets(sn, 260, &stru_4090E0);
  v3 = strlen(sn) - 1;
  if ( v3 < 8 || v3 > 20 )
  {
    sub_401BE0(aKeyLenErrorD__);
    return 0;
  }

输入长度为8-20个字符

  if ( v3 > 0 )
  {
    do
    {
      v6 = sn[v5];
      if ( v6 <= '0' || v6 > '9' )
        ++v4;
      ++v5;
    }
    while ( v5 < v3 );
    if ( v4 )
    {
      sub_401BE0(aKeyFormatError);
      return 0;
    }
  }

字符组成为1-9

  big_init(&b1);
  v22 = 0;
  big_load(&b1, sn);
  nullsub_1();
  big_mul((int)&b1, 9);

sn做为大数*9,即b1 = sn * 9

  while ( 1 )
  {
    big_init3(&b2, sn);
    LOBYTE(v22) = 1;
    v7 = big_mul2((int)&b1, (int)&b2);
    v8 = big_mul((int)&b1, 9) + v7;
    nullsub_1();
    if ( v8 || big_len((int)&b1) % 2 != 1 )
      goto LABEL_16;
    v9 = big_len((int)&b1);
    v10 = big_val((int)&b1, v9 >> 1);
    v11 = big_val((int)&b2, 0);
    v12 = &b2;
    if ( v10 == v11 )
      break;
LABEL_17:
    LOBYTE(v22) = 0;
    sub_401390(v12);
    if ( v8 )
    {
      sub_401BE0(aWrongKey___);
      goto LABEL_19;
    }
  }

循环计算 b1 = b1 * sn * 9,直到b1长度为奇数且b1[len/2] == sn[0],其中b2 == sn

  b2_len = big_len((int)&b2) - 1;
  v14 = 1 - big_len((int)&b2);
  b1_len = big_len((int)&b1);
  v16 = big_compare(&b1, (int)&b2, b1_len + v14, 1, b2_len, 0);
  v17 = big_len((int)&b2);
  if ( big_compare(&b1, (int)&b2, 0, 1, v17 - 1, 1) + v16 )
  {
    v8 = 0;
LABEL_16:
    v12 = &b2;
    goto LABEL_17;
  }
  sub_401BE0(aWellDone);

正向和反向比较b1和sn,长度为sn - 1,即sn[1]开始的数字,至此可以确定是在求回文数。

下面程序进行穷举:

import os


def length(number):
    n = number
    l = 0
    while n > 0 :
        n = n / 10
        l+=1
    return l


def isok(number):
    res = 0
    n = number

    while n > 0:
        res = res * 10 + n % 10
        n = n / 10
        
    if res == number :
        return 1
    return 0


def test(a):
    b2 = a * 9
    i = 0
    while i < 2:
        b2 *= a
        b2 *= 9
        if (isok(b2) == 1):
            print ("%d => %d\n" % (a, b2))
            break
        i+=1

    return 0


def skip(a):
    b = 1
    n = a
    while n > 0 :
        if ((n % 10) == 0):
            a += b
        n = n / 10
        b = b * 10
    return a


def main():
    print skip(10089000)
    
    i=11111111
    while i <= 99999999:
        i = skip(i)
        test(i)
        i+=1
    
    print "over"
    return 0


if __name__ == "__main__":
    main()

输出结果为:

12345679 => 12345678987654321

需要反向输入,即

sn=97654321



[峰会]看雪.第八届安全开发者峰会10月23日上海龙之梦大酒店举办!

收藏
免费 0
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/06/06
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//