zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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}

  • 相关阅读:
    c#泛型的使用
    如何调试由于heap corruption导致的程序崩溃的简单示例
    Windows的SEH机理简要介绍
    利用定制行为扩展WCF之利用MessageInsepctor behaviourExtension扩展WCF行为(自定义消息头)
    欧拉函数
    JZOJ.1349 最小公约数
    关于扩展中国剩余定理(excrt)的证明与拙见
    【USACO 2021 US Open, Gold】United Cows of Farmer John & JZOJ7220
    线性求逆元
    【USACO 2021 January Contest, Platinum】Problem 1. Sum of Distances JZOJ.7241
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/12609782.html
Copyright © 2011-2022 走看看