BUUCTF--[V&N2020 公开赛]strangeCpp

测试文件:https://www.lanzous.com/iauqjsd

 

代码分析

先找到程序运行显示处的代码

 1 // 个数,数组,环境变量
 2 __int64 __fastcall sub_140013AA0(__int64 a1, __int64 a2, __int64 *a3)
 3 {
 4   char *v3; // rdi
 5   signed __int64 i; // rcx
 6   __int64 v5; // rax
 7   __int64 v6; // rax
 8   __int64 v7; // rax
 9   __int64 v8; // rax
10   char v10; // [rsp+0h] [rbp-20h]
11   struct _SYSTEM_INFO SystemInfo; // [rsp+28h] [rbp+8h]
12   __int64 *j; // [rsp+78h] [rbp+58h]
13   __int64 v13; // [rsp+98h] [rbp+78h]
14   __int64 *v14; // [rsp+1A0h] [rbp+180h]
15 
16   v14 = a3;
17   v3 = &v10;
18   for ( i = 94i64; i; --i )
19   {
20     *(_DWORD *)v3 = 3435973836;
21     v3 += 4;
22   }
23   sub_1400110AA((__int64)&unk_140027033);
24   GetSystemInfo(&SystemInfo);
25   putchar(byte_140021004);                      // w
26   putchar(byte_140021005);                      // e
27   putchar(byte_140021006);                      // l
28   putchar(byte_140021007);                      // c
29   putchar(byte_140021019);                      // o
30   putchar(byte_14002101A);                      // m
31   putchar(byte_140021005);                      // e
32   putchar(10);
33   puts("Let me have a look at your computer...");
34   for ( j = v14; *j; ++j )                      // 循环输出环境变量
35   {
36     v13 = *j;
37     sub_140011226("%s\n", v13);
38   }
39   std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127);
40   dword_140021190 = SystemInfo.dwNumberOfProcessors;// CPU数量
41   sub_140011226("now system cpu num is %d\n", SystemInfo.dwNumberOfProcessors);
42   if ( dword_140021190 < 8 )
43   {
44     puts("Are you in VM?");
45     _exit(0);
46   }
47   if ( GetUserNameA(Str1, &pcbBuffer) )         // 获取用户名
48   {
49     v5 = sub_140011172(std::cout, (__int64)"this is useful");
50     std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, sub_140011127);
51   }
52   v6 = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127);
53   v7 = sub_140011172(v6, (__int64)"ok,I am checking...");
54   std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_140011127);
55   if ( !j_strcmp(Str1, "cxx") )
56   {
57     v8 = sub_140011172(std::cout, (__int64)"flag{where_is_my_true_flag?}");
58     std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, sub_140011127);
59     _exit(0);
60   }
61   system("pause");
62   sub_1400113E3((__int64)&v10, (__int64)&unk_14001DE50);
63   return 0i64;
64 }

在我查看第21~25行代码,输出字符串处时

中间插了一个byte_140021008变量,找到引用处

 1 __int64 sub_140013580()
 2 {
 3   __int64 *v0; // rdi
 4   signed __int64 i; // rcx
 5   __int64 result; // rax
 6   __int64 v3; // [rsp+0h] [rbp-20h]
 7   int v4; // [rsp+24h] [rbp+4h]
 8   int j; // [rsp+44h] [rbp+24h]
 9   __int64 v6; // [rsp+128h] [rbp+108h]
10 
11   v0 = &v3;
12   for ( i = 82i64; i; --i )
13   {
14     *(_DWORD *)v0 = -858993460;
15     v0 = (__int64 *)((char *)v0 + 4);
16   }
17   v6 = -2i64;
18   sub_1400110AA((__int64)&unk_140027033);
19   result = sub_140011384((unsigned int)dword_140021190);
20   v4 = result;
21   if ( (_DWORD)result == 607052314 && dword_140021190 <= 14549743 )
22   {
23     for ( j = 0; j < 17; ++j )
24     {
25       putchar((unsigned __int8)(dword_140021190 ^ byte_140021008[j]));
26       result = (unsigned int)(j + 1);
27     }
28   }
29   return result;
30 }

我们首先需要看到第19行代码,进入sub_140011384函数(dword_140021190实际就是我们第一处代码的CPU数量,变量的值可以通过下面if条件,暴力解出值)。

 1 signed __int64 __fastcall sub_140013890(int a1)
 2 {
 3   __int64 *v1; // rdi
 4   signed __int64 i; // rcx
 5   signed __int64 result; // rax
 6   __int64 v4; // [rsp+0h] [rbp-20h]
 7   int v5; // [rsp+24h] [rbp+4h]
 8   int v6; // [rsp+44h] [rbp+24h]
 9   unsigned int v7; // [rsp+64h] [rbp+44h]
10   int v8; // [rsp+160h] [rbp+140h]
11 
12   v8 = a1;
13   v1 = &v4;
14   for ( i = 82i64; i; --i )
15   {
16     *(_DWORD *)v1 = -858993460;
17     v1 = (__int64 *)((char *)v1 + 4);
18   }
19   sub_1400110AA((__int64)&unk_140027033);
20   v5 = v8 >> 12;
21   v6 = v8 << 8;
22   v7 = (v8 << 8) ^ (v8 >> 12);
23   v7 *= 291;
24   if ( v7 )
25     result = v7;
26   else
27     result = 987i64;
28   return result;
29 }

通过这段代码的第22,23行和上段代码的第25行,我们可以解出flag

 

脚本

# -*- coding:utf-8 -*-
import hashlib

result = 0
for v8 in range(14549743):
    v7 = (((v8 << 8) ^ (v8 >> 12))*291)&0xFFFFFFFF # 原文是unsigned int--0~0xFFFFFFFF,输出的值需要截断
    if (v7 == 607052314):
        result = v8
        break

enc = [0x26, 0x2C, 0x21, 0x27, 0x3B, 0x0D, 4, 0x75, 0x68, 0x34, 0x28,
       0x25, 0x0E, 0x35, 0x2D, 0x69, 0x3D]

flag = ""
for i in enc:
    flag += chr((result ^ i)&0xFF) # unsigned __int8--0~0xFF
print (flag)
md = hashlib.md5()
md.update(str(result).encode('utf-8'))
print ("flag{"+md.hexdigest()+"}")

 

get flag!

flag{e10adc3949ba59abbe56e057f20f883e}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值