首页
社区
课程
招聘
[原创][Flare-on5] Challenge6 magic -Writeup
发表于: 2018-9-14 13:20 7653

[原创][Flare-on5] Challenge6 magic -Writeup

2018-9-14 13:20
7653

main生成个固定seed,之后进入sub_402D47做check,run时发现不会进入branch,先忽略。
接着读输入Key,进入func_proc1,完成后与加密flag做xor,最后进入func_proc2。
一共做666次Chanllenges,全部正确即可拿到flag。

Proc_1:

可以明显看出是个解smc,调用,再复原smc的过程。
设计到有个0x120大小的数据结构
![QQ截图20180914125757.png-45.5kB][1]

一共Check33个函数,意味着就33个这样的结构体。

我们可以手动跑一下得到解smc的函数。
使用脚本:

可以拿到复原后的33个函数。

不难发现,这33个函数分为了7个种类:

于是,我们可以手动解一下(1/666)的Key

这样,Proc1分析完成。

那么现在就有这样的问题:
1/666的check与n/666的Check的不同。
猜测:

难度依次递增。

Proc2:
黑箱测试:Proc2的作用是重写33个数据结构,并且会在进下一轮Proc1之前,将改动写回文件当中。
当完成(1/666)的Proc1,我们就拿到了Proc2的bin,再用脚本还原,可以发现:
函数虽然smc的地址改变了,但函数类型不变,都在这7种。
那么我们就必要硬逆Proc2的算法了。

  让我们梳理下执行逻辑:
1.生成seed为proc_2更新做准备
2.输入key 共666轮
3.Proc_1 Check
4.解密flag 共666轮
5.Proc_2 更新文件(本地写)
6.loop到[2], 直到666轮完成,输出解密flag

那么我们可以在proc_2更新之前,复制出来一份。这一份的我们可以用来手动解smc从而得到33个函数,而不影响正常的proc_2过程。

就算得到了33个函数,那如何实现自动化生成key呢?根据Proc_2的结果我们知道33个函数均在7种类型内,这样就可以通过某一地址上的值两两不同去识别。比如:

以上是以0x30为起点的4字节值,可以注意到0x32地址上值两两不同,即可用于识别函数。
这样,Crack思路就很清晰了:
1.手动解smc,识别33个函数属于的种类
2.根据种类,执行对应的解密算法
3.使用pwntools完成recv和send的自动化。

完整的Crack脚本:

  

  最后,因为Flare-on5直到Oct.5才结束,所以以上的脚本都被我轻微的改动了一下。
  本人仅仅提供一点点思路,还请各位Cracker斧正。

  更新了附件, password: infected
![QQ截图20180914131835.png-1.1kB][2]

 
 
 
 
 
 
 
 
 
 
 
 
signed __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  unsigned __int64 v3; // rax
  unsigned __int64 len; // rax
  __int64 *v6; // [rsp+0h] [rbp-1E0h]
  unsigned int seed; // [rsp+1Ch] [rbp-1C4h]
  unsigned int i; // [rsp+20h] [rbp-1C0h]
  unsigned int j; // [rsp+20h] [rbp-1C0h]
  unsigned int k; // [rsp+24h] [rbp-1BCh]
  char input_s[128]; // [rsp+40h] [rbp-1A0h]
  char a3a; // [rsp+C0h] [rbp-120h]
  char arr_1[72]; // [rsp+140h] [rbp-A0h]
  char v14; // [rsp+188h] [rbp-58h]
  unsigned __int64 v15; // [rsp+1C8h] [rbp-18h]

  v15 = __readfsqword(0x28u);
  seed = 0;
  memset(input_s, 0, sizeof(input_s));
  memset(&a3a, 0, 0x80uLL);
  *arr_1 = 0x45123A7920755C24LL;
  *&arr_1[8] = 0x17263719711D201ELL;
  *&arr_1[16] = 0x4A7C67303E100367LL;
  *&arr_1[24] = 0x11621308555E1B11LL;
  *&arr_1[32] = 0x122C17445A7C6C68LL;
  *&arr_1[40] = 0x576D0C6324095979LL;
  *&arr_1[48] = 0x265D0F6A0C27651FLL;
  *&arr_1[56] = 0xA375C1433594643LL;
  *&arr_1[64] = 0x2C16022663LL;
  memset(&v14, 0, 0x38uLL);
  for ( i = 0; i < strlen("Run, Forrest, run!!"); i += 4 )
    seed ^= *&aRunForrestRun[i];
  srand(seed);
  if ( sub_402D47() )
  {
    v3 = strlen(a2[1]);
    func_proc1(a2[1], v3, &a3a);
    func_proc2(*a2);
    puts("Generated first permutation!");
    exit(0);
  }
  puts("Welcome to the ever changing magic mushroom!");
  printf("%d trials lie ahead of you!\n", 666LL, a2);
  for ( j = 0; j < 666; ++j )
  {
    printf("Challenge %d/%d. Enter key: ", j + 1, 666LL);
    if ( !fgets(input_s, 128, unk_617630) )
      return 0xFFFFFFFFLL;
    len = strlen(input_s);
    func_proc1(input_s, len, &a3a);
    for ( k = 0; k < strlen(input_s); ++k )
      arr_1[k] ^= input_s[k];
    func_proc2(*v6);
  }
  printf("Congrats! Here is your price:\n%s\n", arr_1);
  return 0LL;
}

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

最后于 2019-2-2 11:19 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 3176
活跃值: (1786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
扎实 赞一个
2018-9-14 16:34
0
雪    币: 47147
活跃值: (20415)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
分析的不错
2018-9-17 22:01
0
雪    币: 6314
活跃值: (952)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
看小标题识人 233
2018-9-18 17:37
0
游客
登录 | 注册 方可回帖
返回
//