Lockpick

Description

Forela needs your help! A whole portion of our UNIX servers have been hit with what we think is ransomware. We are refusing to pay the attackers and need you to find a way to recover the files provided. Warning This is a warning that this Sherlock includes software that is going to interact with your computer and files. This software has been intentionally included for educational purposes and is NOT intended to be executed or used otherwise. Always handle such files in isolated, controlled, and secure environments. Once the Sherlock zip has been unzipped, you will find a DANGER.txt file. Please read this to proceed.

Files

└─$ 7z l lockpick1.zip
 
   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2023-06-02 10:38:02 D....            0            0  forela-criticaldata
2023-06-02 10:38:02 .....          153          130  forela-criticaldata/forela_uk_applicants.sql.24bes_note.txt
2023-06-02 10:38:02 .....     64954456     26941691  forela-criticaldata/customer-feedback.json.24bes
2023-06-02 10:38:02 .....       134892       134875  forela-criticaldata/sales_forecast.xlsx.24bes
2023-06-02 10:38:02 .....      1093774       450037  forela-criticaldata/trading-firebase_bkup.json.24bes
2023-06-02 10:38:02 .....       308633        63672  forela-criticaldata/co2_London
2023-06-02 10:38:02 .....        78627        46809  forela-criticaldata/forela_uk_applicants.sql.24bes
2023-06-02 10:38:02 .....          153          130  forela-criticaldata/sales_forecast.xlsx.24bes_note.txt
2023-06-02 10:38:02 .....          153          130  forela-criticaldata/complaints.csv.24bes_note.txt
2023-06-02 10:38:02 .....      5238447      2484636  forela-criticaldata/complaints.csv.24bes
2023-06-02 10:38:02 .....          153          130  forela-criticaldata/it_assets.xml.24bes_note.txt
2023-06-02 10:38:02 .....          153          130  forela-criticaldata/trading-firebase_bkup.json.24bes_note.txt
2023-06-02 10:38:02 .....          153          130  forela-criticaldata/customer-feedback.json.24bes_note.txt
2023-06-02 10:38:02 .....      6634991      1363391  forela-criticaldata/it_assets.xml.24bes
2023-07-10 10:49:59 .....         3890         3902  bescrypt.zip
2023-07-10 10:48:49 .....         1050          553  DANGER.txt
------------------- ----- ------------ ------------  ------------------------
2023-07-10 10:49:59           78449678     31490346  15 files, 1 folders
 
└─$ 7z x lockpick1.zip -p'hacktheblue'
└─$ cat DANGER.txt
Dear User,

This text file is to warn you that the ZIP file contains software that is going to interact with your computer and files. This software has been intentionally included for educational purposes and is NOT intended to be executed or used otherwise.Always handle such files in isolated, controlled, and secure environments. 

It is strongly recommend you proceed by:
1 - Running the sample in a controlled environment, for example EP Pwnbox or an isolated virtual machine. 
2 - Only unzip the software in this controlled environment, using the password provided.
3 - Unzip the file in the VM and enjoy analysing!

PLEASE EXERCISE EXTREME CAUTION!

The ZIP file containing the software is password-protected for your safety. The password is "E@iwyzXK7HK&". It is strongly recommended that you do NOT extract or execute the contents of this ZIP file unless you understand the risks involved.

By reading this file and using the provided password to unzip the file, you acknowledge and fully understand the risks as detailed in this warning. 

Tasks

Task 1. Please confirm the encryption key string utilized for the encryption of the files provided?

Open the malware in Ghidra and start static analysis. In the main function we see only 1 function, process_directory which seems to be taking directory and some string.

Writeup.png

some string turns out to be a key for encryption.

Writeup-1.png
Writeup-2.png

Task 2. We have recently received an email from wbevansn1@cocolog-nifty.com demanding to know the first and last name we have him registered as. They believe they made a mistake in the application process. Please confirm the first and last name of this applicant.

Pretty much the encryption takes filename, reads it, XORs with key, saves encrypted file, adds note and deletes the original file. To recover files we can use say key because XOR is symmetrical.

void encrypt_file(char *filename,char *key) {
  byte bVar1;
  int iVar2;
  size_t sVar3;
  char note_filename [1024];
  char filename_enc [1032];
  FILE *fp_note;
  void *buffer;
  size_t current_position;
  FILE *fp;
  ulong i;
  ulong j;
  
  fp = fopen(filename,"rb");
  if (fp == (FILE *)0x0) {
    printf("Error opening file: %s\n",filename);
  }
  else {
    fseek(fp,0,2);
    current_position = ftell(fp);
    rewind(fp);
    buffer = malloc(current_position);
    fread(buffer,1,current_position,fp);
    fclose(fp);
    for (i = 0; j = i, (long)i < (long)current_position; i = i + 1) {
      bVar1 = *(byte *)((long)buffer + i);
      sVar3 = strlen(key);
      *(byte *)((long)buffer + i) = bVar1 ^ key[j % sVar3];
    }
    snprintf(filename_enc,0x400,"%s.24bes",filename);
    fp = fopen(filename_enc,"wb");
    fwrite(buffer,1,current_position,fp);
    fclose(fp);
    free(buffer);
    snprintf(note_filename,0x400,"%s_note.txt",filename_enc);
    fp_note = fopen(note_filename,"w");
    if (fp_note == (FILE *)0x0) {
      printf("Error creating note file: %s\n",note_filename);
    }
    else {
      fwrite("This file has been encrypted by bes24 group, please contact us at bes24@protonmail.com  to discuss payment for us providing you the decryption software..\n"
             ,1,0x99,fp_note);
      fclose(fp_note);
    }
    iVar2 = remove(filename);
    if (iVar2 != 0) {
      printf("Error deleting original file: %s\n",filename);
    }
  }
  return;
}

Decrypt the files:

from pwn import xor
from pathlib import Path

key = b'bhUlIshutrea98liOp'
files = Path('./forela-criticaldata').glob('*.24bes')
for file in files:
    with open(file, 'rb') as enc, open(file.with_suffix(''), 'wb') as dec:
        print(file)
        while True:
            data = enc.read(5400)
            if not data: break
            dec.write(xor(data, key))
└─$ grep 'wbevansn1@cocolog-nifty.com' . -Rain
./forela-criticaldata/forela_uk_applicants.sql:872:(830,'Walden','Bevans','wbevansn1@cocolog-nifty.com','Male','Aerospace Manufacturing','2023-02-16'),

Answer: Walden Bevans

Task 3. What is the MAC address and serial number of the laptop assigned to Hart Manifould?

└─$ grep 'Manifould' . -Rain
./customer-feedback.json:12080:{"id":12080,"first_name":"Filbert","last_name":"Manifould","email":"fmanifould9bj@ed.gov","gender":"Male","ip_address":"252.14.12.2","customer_id":12080,"feedback_date":"12/4/2022","feedback_rating":1.3,"feedback_comments":"Fusce posuere felis sed lacus. Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl. Nunc rhoncus dui vel sem.","customer_name":"Filbert Manifould","customer_email":"fmanifould9bj@latimes.com","customer_phone":"624-952-1917","product_name":"Financial Planning","product_category":"Category 2"},
./it_assets.xml:.................TOO MUCH OUTPUT.....

xml should have the answers, so I decided to parse it:

# xml2csv.py
import xml.etree.ElementTree as ET
import csv
from tqdm import tqdm
import sys


def xml_to_csv(xml_file, csv_file):
    context = ET.iterparse(xml_file, events=("start", "end"))
    context = iter(context)
    event, root = next(context)  # Get the root element
    total_records = sum(1 for event, elem in ET.iterparse(xml_file) if elem.tag == "record")

    with open(csv_file, 'w', newline='') as csvfile:
        csvwriter = csv.writer(csvfile)

        headers_written = False
        with tqdm(total=total_records, desc="Processing records") as pbar:
            for event, elem in context:
                if event == "end" and elem.tag == "record":
                    if not headers_written:
                        headers = [child.tag for child in elem]
                        csvwriter.writerow(headers)
                        headers_written = True

                    row = [child.text for child in elem]
                    csvwriter.writerow(row)

                    root.clear()
                    pbar.update(1)

filename = sys.argv[1]
output = sys.argv[2] if len(sys.argv) > 1 else filename.replace('.xml', '.csv')
xml_to_csv(xml_file=filename, csv_file=output)

Find the answer:

└─$ head -1 it_assets.csv
asset_id,MAC,asset_type,serial_number,purchase_date,last_patch_date,patch_status,assigned_to,location
└─$ grep 'Manifould' ./it_assets.csv  -in
502:501,E8-16-DF-E7-52-48,laptop,1316262,8/3/2022,1/6/2023,pending,Hart Manifould,Room 1156

Task 4. What is the email address of the attacker?

They left notes all over the place about who they were.

Task 5. City of London Police have suspicions of some insider trading taking part within our trading organization. Please confirm the email address of the person with the highest profit percentage in a single trade alongside the profit percentage.

The data which we should analyze is trading-firebase_bkup.json:

└─$ cat trading-firebase_bkup.json | jq '."-NTy-bkyce9Wh7gfISHY"'
{
  "id": 1,
  "first_name": "Gibby",
  "last_name": "Torrance",
  "email": "gtorrance0@dailymotion.com",
  "gender": "Male",
  "ip_address": "108.38.40.45",
  "stock_name": "Gap, Inc. (The)",
  "stock_symbol": "GPS",
  "purchase_price": 490247.44,
  "sale_price": 418518.11,
  "quantity": 826376,
  "purchase_date": "12/15/2022",
  "sale_date": "1/12/2023",
  "profit": -71729.33,
  "profit_percentage": -14.6312502927093306188401514,
  "industry": "Healthcare"
}

Get max percentage:

└─$ cat trading-firebase_bkup.json | jq -r 'to_entries | max_by(.value.profit_percentage)'
{
  "key": "-NTy-crBi1fPrGaU6Uiu",
  "value": {
    "id": 1559,
    "first_name": "Farah",
    "last_name": "Mosedale",
    "email": "fmosedale17a@bizjournals.com",
    "gender": "Female",
    "ip_address": "79.9.35.201",
    "stock_name": "Pennsylvania Real Estate Investment Trust",
    "stock_symbol": "PEI^A",
    "purchase_price": 304.1,
    "sale_price": 433048.13,
    "quantity": 842496,
    "purchase_date": "5/1/2022",
    "sale_date": "8/2/2022",
    "profit": 432744.03,
    "profit_percentage": 142303.1996053929628411706675436,
    "industry": "Energy"
  }
}

Task 6. Our E-Discovery team would like to confirm the IP address detailed in the Sales Forecast log for a user who is suspected of sharing their account with a colleague. Please confirm the IP address for Karylin O'Hederscoll.

Open the sales_forecast.xlsx in Excel, Ctrl+T to create table, filter first_name for Karylin.

Writeup-3.png

Task 7. Which of the following file extensions is not targeted by the malware? .txt, .sql,.ppt, .pdf, .docx, .xlsx, .csv, .json, .xml

In process directory we find a filter for extensions. The only one not included from question list is ppt

Writeup-4.png

Task 8. We need to confirm the integrity of the files once decrypted. Please confirm the MD5 hash of the applicants DB.

└─$ md5sum forela-criticaldata/forela_uk_applicants.sql
f3894af4f1ffa42b3a379dddba384405  forela-criticaldata/forela_uk_applicants.sql

Task 9. We need to confirm the integrity of the files once decrypted. Please confirm the MD5 hash of the trading backup.

└─$ md5sum forela-criticaldata/trading-firebase_bkup.json
87baa3a12068c471c3320b7f41235669  forela-criticaldata/trading-firebase_bkup.json

Task 10. We need to confirm the integrity of the files once decrypted. Please confirm the MD5 hash of the complaints file.

└─$ md5sum forela-criticaldata/complaints.csv
c3f05980d9bd945446f8a21bafdbf4e7  forela-criticaldata/complaints.csv

Last updated