首页
社区
课程
招聘
[原创] 京东-看雪 -2018 春季赛 - 第四题 - 密届寻踪
发表于: 2018-6-24 10:37 2855

[原创] 京东-看雪 -2018 春季赛 - 第四题 - 密届寻踪

aqs 活跃值
5
2018-6-24 10:37
2855

逆向还是太菜了,还要走很长的路。。。
题目全程靠猜。。没什么时间,先占个坑,后面有时间再重新分析一遍

 

运行一下程序

************看雪-京东CTF2018*************
serial:11111111
error请按任意键继续. . .

可以输入一个 字符串,输完会给你error 或者 success

 

逻辑大概是下面这样的

 while ( (unsigned int)(v3 - v2) > 0xFFF );
  *(_DWORD *)(a1 - 20) = 'g`wr';
  *(_DWORD *)(a1 - 16) = 'tu`';
  *(_WORD *)(a1 - 12) = 0;
  *(_DWORD *)(a1 - 32) = 'kqpd';
  *(_WORD *)(a1 - 28) = 'w';
  *(_DWORD *)(a1 - 26) = 0;
  *(_BYTE *)(a1 - 56) = 0;
  *(_DWORD *)(a1 - 55) = 0;
  *(_DWORD *)(a1 - 51) = 0;
  *(_DWORD *)(a1 - 47) = 0;
  *(_DWORD *)(a1 - 43) = 0;
  *(_DWORD *)(a1 - 39) = 0;
  *(_WORD *)(a1 - 35) = 0;
  *(_BYTE *)(a1 - 33) = 0;
  *(_BYTE *)(a1 - 60) = 0;
  *(_WORD *)(a1 - 59) = 0;
  printmsg();
  j_startinfo();
  msg_str(a1 - 20);                             // success
  msg_str(a1 - 32);                             // error
  scanf("%s", a1 - 56, 24);                     // a1-56 === input
  if ( strlen((const char *)(a1 - 56)) > 0x17 )
  {
    printf((const char *)(a1 - 32));            // len(input) < 0x17
    exit(0);
  }
  len_3_ = strlen((const char *)(a1 - 53));     // input[3:]
  tohex(a1 - 53, (int)&hex_3__495660, len_3_);
  *(_DWORD *)(a1 - 4) = sub_40125D();           // iamahandsomeguyhaha1
  memcpy((void *)(a1 - 60), (const void *)(a1 - 56), 3u);// a1-60 == input[:3]
  if ( isdigit(a1 - 60) )
  {                                             // 判断前三位是不是 数字
    *(_DWORD *)(a1 - 8) = sub_40128F(a1 - 60);  // 对数字进行操作
    if ( *(_DWORD *)(a1 - 8) + *(_DWORD *)(a1 - 4) == 2 )// 如果两次返回的都是1 即可
      printf((const char *)(a1 - 20));
    else
      printf((const char *)(a1 - 32));
    system("pause");
    result = 0;
  }
  else
  {
    printf((const char *)(a1 - 32));
    result = 0;
  }
  return result;
}

用 msg_str 这个函数来生成 success ,error 字符串
这个函数也比较简单,读入一段字符,按 (index+1) 异或即可

 

后面读取一段长度 <0x17 的 字符串
转换成 hex 编码放到 bss 段上
接下来就是 两个 函数,sub_40125D, sub_40128F ,如果两个函数返回都是1 的话就是正确的
第一个 函数 sub_40125d 传入的是 input[3:] 这段字符串
第二个函数 sub_40128f 传入的是 input[:3] ,并且三位都必须要是数字

 

看一下第一个函数,ida f5 有点问题,直接alt+k 改了一下sp, 但是代码很难看,主要逻辑在下面

BOOL __usercall rsa_some_402A3A@<eax>(int a1@<ebp>)
{
  int v1; // eax

  ((void (*)(void))((char *)&loc_402A35 + 1))();
  msg_str(a1 - 204);                            // ecx:"7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585"
  msg_str(a1 - 804);                            // edx:"208CBB7CD6ECC64516D07D978F5F0681F534EAD235D5C49ADD72D2DB840D5304"
  *(_DWORD *)(*(_DWORD *)(a1 - 4) + 564) = 16;
  *(_DWORD *)(a1 - 808) = malloc_409350(0);
  *(_DWORD *)(a1 - 812) = malloc_409350(0);
  *(_DWORD *)(a1 - 820) = malloc_409350(0);
  *(_DWORD *)(a1 - 816) = malloc_409350(0);
  copysome_40D1E0(*(_DWORD *)(a1 - 820), (int)&hex_3__495660);
  copysome_40D1E0(*(_DWORD *)(a1 - 808), a1 - 804);// enc str
  copysome_40D1E0(*(_DWORD *)(a1 - 812), (int)"3e9");// 3e9
  if ( sub_40A2C0(*(_DWORD **)(a1 - 820), *(_DWORD **)(a1 - 808)) != -1 )
    return 0;                                   // (input[3:], 3e9, 7da_str,dst)
  main_enc_40C110(*(_DWORD *)(a1 - 820), *(_DWORD *)(a1 - 812), *(_DWORD *)(a1 - 808), *(_DWORD *)(a1 - 816));
  sub_40B280(0, *(_DWORD **)(a1 - 816), (_BYTE *)(a1 - 404), 0);
  clean_409CA0(*(_DWORD *)(a1 - 808));
  clean_409CA0(*(_DWORD *)(a1 - 812));
  clean_409CA0(*(_DWORD *)(a1 - 820));
  clean_409CA0(*(_DWORD *)(a1 - 816));
  clean();
  v1 = strlen((const char *)(a1 - 404));
  tohex_40100F(a1 - 404, a1 - 604, v1);
  return strcmp((const char *)(a1 - 204), (const char *)(a1 - 604)) == 0;
}

前面主要是 一些内存分配,copy 的操作,后面是 free 内存,转换成hex 比较的过程,主要是中间的过程
调用了 main_enc_40C110 这个函数
传入 参数
(input[3:],0x3e9, 7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585,dst)

 

对输入进行加密,加密之后得到的 dst hex 编码之后和
208CBB7CD6ECC64516D07D978F5F0681F534EAD235D5C49ADD72D2DB840D5304 比较,一样即返回1
不过这个函数太大了,可能是已有的什么加密,调试的时候 发现输入
111\x01 得到的是 01 , 改成 \x02 的话得到的是
(2^0x3e9)%/7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585
看起来是 rsa 加密,直接将 7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585 模数分解一下,然后就可以 求出 input了

import gmpy                                                                

e=gmpy.mpz(0x3e9)                                                          

p=208096057845685678782766058500526476379                                  
q=273086345401562743300402731618892888991                                  

n=0x7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585       
p=gmpy.mpz(p)                                                              
q=gmpy.mpz(q)                                                              
phi_n=(p-1)*(q-1)                                                          

d=gmpy.invert(e,phi_n)                                                     

print hex(d)                                                               


m=pow(c,d,n)                                                               

print hex(m)

得到input

iamahandsomeguyhaha1

大帅锅haha

 

第一个函数过了,接下来第二层是个 3 位的数字,die 查看加密特征和发现这里用了 aes 加密,不过只是三位数字而已,爆破一下?
手动测试了一下,p一下输个 520 发现居然过了
完整flag

520iamahandsomeguyhaha1

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2018-6-24 10:39 被aqs编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//