// HackTheBox  ·  writeup

Detroit Becomes Human

HackTheBox Hard SQLiteMFTECmdEvtxECmdRBCmdRECmdregipyJohn the Ripper7-ZipPython
DFIR

Scenario

Alonzo Spire is fascinated by AI after noticing the recent uptick in usage of AI tools to help aid in daily tasks. He came across a sponsored post on social media about an AI tool by Google. The post had a massive reach, and the Page which posted had 200k + followers. Without any second thought, he downloaded the tool provided via the Post. But after installing it he could not find the tool on his system which raised his suspicions. A DFIR analyst was notified of a possible incident on Forela’s sysadmin machine. You are tasked to help the analyst in analysis to find the true source of this odd incident.

Executive Summary

A sponsored Facebook post for a fake Google AI assistant led a Forela sysadmin to a download hosted on Google Drive. The download was a password-protected RAR holding an MSI, which the user installed. The installer dropped its files into a legitimate-looking Google folder under Program Files (x86), including a batch file that launched a PowerShell script with the execution policy bypassed and a tiny JavaScript file that looks like a browser-extension content script. With no AI tool to be found, the user searched Explorer for it, grew suspicious and deleted the archive within a few minutes. The deleted RAR stayed in the Recycle Bin, so the original installer could still be extracted and hashed.

Artifacts

Timestamp note: Every answer is UTC in YYYY-MM-DD HH:MM:SS. The NTUSER hive is dirty; replay the logs with RECmd before reading it, because regipy on the raw hive missed keys.

Initial Access

Q1 — What is the full link of a social media post which is part of the malware campaign, and was unknowingly opened by Alonzo spire?

Start in Edge, since the scenario says the lure was a social media post. Copy the History database out of the evidence and list the urls table by most recent visit. One Facebook post URL on a Page named after a Google AI product sits right before the download activity, and its long pfbid token is the full post link.

sqlite3 work/edge/History "SELECT url, title, last_visit_time FROM urls WHERE url LIKE '%facebook.com%' ORDER BY last_visit_time"
Click flag to reveal https://www.facebook.com/AI.ultra.new/posts/pfbid0BqpxXypMtY5dWGy2GDfpRD4cQRppdNEC9SSa72FmPVKqik9iWNa2mRkpx9xziAS1l
Q2 — Can you confirm the timestamp in UTC when alonzo visited this post?

From Q1 the pivot is the post URL. Chrome-epoch times in urls.last_visit_time and visits.visit_time convert to UTC with datetime(x/1000000-11644473600,'unixepoch'). visits and urls hold times one second apart for this post.

sqlite3 work/edge/History "SELECT datetime(last_visit_time/1000000-11644473600,'unixepoch'), visit_count FROM urls WHERE url LIKE '%AI.ultra.new/posts/pfbid0Bqpx%'"

Gotcha: The first row in visits (04:29:59) is not what the task wants. The value stored in urls.last_visit_time, from the second visit, is the accepted one.

Click to reveal answer 2024-03-19 04:30:00
Q3 — Alonzo downloaded a file on the system thinking it was an AI Assistant tool. What is name of the archive file downloaded?

The downloads table in the same database lists every file Edge saved. The only archive is a RAR named like a Gemini Ultra desktop build, saved after the Facebook visit.

sqlite3 work/edge/History "SELECT target_path, tab_url, datetime(start_time/1000000-11644473600,'unixepoch') FROM downloads"
Click flag to reveal AI.Gemini Ultra For PC V1.0.1.rar
Q4 — What was the full direct url from where the file was downloaded?

downloads.tab_url only shows the page the user was on. The real fetch URL is the last hop in downloads_url_chains for the download ID from Q3, which resolves to a direct Google Drive usercontent link rather than a Facebook or lookalike domain.

sqlite3 work/edge/History "SELECT id, chain_index, url FROM downloads_url_chains ORDER BY id, chain_index"
Click to reveal answer https://drive.usercontent.google.com/download?id=1z-SGnYJCPE0HA_Faz6N7mD5qf0E-A76H&export=download
Q16 — Looking back at the starting point of this infection, please find the md5 hash of the malicious installer.

Alonzo deleted the RAR (see Q15), so the original is in the Recycle Bin as an $R file. It is password-protected, so extraction needs the password first. rar2john produces a hash that john cracks against rockyou, giving the password 022024. Extract the MSI with 7z and hash it. The hash is of the extracted MSI, not of the RAR.

rar2john '$R2MU60B.rar' > rar.hash && john rar.hash --wordlist=/usr/share/dict/rockyou.txt
7z x -p022024 '$R2MU60B.rar' && md5sum *.msi

Tip: Hashing the archive instead of its contents gives a different value; the installer is the MSI inside.

Click to reveal answer BF17D7F8DAC7DF58B37582CEC39E609D

Execution

Q5 — Alonzo then proceeded to install the newly download app, thinking that its a legit AI tool. What is the true product version which was installed?

MSI installs are logged by MsiInstaller in the Application log. Parse the logs to CSV with EvtxECmd and grep for the provider. The installation event (1033) carries the product name and version, and the version in the MSI metadata differs from the “V1.0.1” in the archive name, which is the point of “true”.

EvtxECmd -d evidence/logs --csv work/evtx --csvf all.csv
grep MsiInstaller work/evtx/all.csv
Click flag to reveal 3.32.3
Q6 — When was the malicious product/package successfully installed on the system?

From Q5 the same MsiInstaller events give the time. The completion event (11707, “installation completed successfully”) is the one that marks a successful install, and it lands about 90 seconds after the Facebook visit. A cross-check on the MFT for new files around that minute shows the same burst.

grep MsiInstaller work/evtx/all.csv | grep 11707
Click to reveal answer 2024-03-19 04:31:33
Q8 — The malware executed a command from a file. What is name of this file?

In the MFT listing for the staging directory from Q7, one batch file stands out next to the PowerShell script: install.cmd, MFT entry 51471. It is the launcher that the installer ran.

MFTECmd -f evidence/C/$MFT --csv work/mft
Click flag to reveal install.cmd
Q9 — What are the contents of the file from question 8? Remove whitespace to avoid format issues.

A file this small is stored resident in its MFT record, so its content is inside the $DATA attribute and there is no cluster to carve. Read entry 51471 from the raw $MFT with a short Python script and strip whitespace. The result is a @echo off followed by a PowerShell call with -ExecutionPolicy Bypass and %~dp0 pointing at ru.ps1 inside a folder named nmmhkkegccagdldgiimedpic.

# read resident $DATA of MFT entry 51471 (record size 1024)
import sys; d=open(sys.argv[1],'rb').read(); r=d[51471*1024:51472*1024]
Click flag to reveal @echooffpowershell-ExecutionPolicyBypass-File"%~dp0nmmhkkegccagdldgiimedpic/ru.ps1"
Q10 — What was the command executed from this file according to the logs?

The batch file only holds a relative path (%~dp0). The logs show it resolved. Grep the parsed event CSV for install.cmd and ru.ps1: Windows PowerShell engine event 600 records the host application with the expanded command line.

grep -E 'install\.cmd|ru\.ps1' work/evtx/all.csv
Click to reveal answer powershell -ExecutionPolicy Bypass -File C:\Program Files (x86)\Google\Install\nmmhkkegccagdldgiimedpic/ru.ps1
Q13 — Upon seeing no AI Assistant app being run, alonzo tried searching it from file explorer. What keywords did he use to search?

Explorer search terms are kept per user in the WordWheelQuery key of NTUSER.DAT. The hive is dirty, so copy it with its transaction logs and run RECmd with the Kroll batch file, which replays the logs. regipy on the raw hive missed the key.

RECmd -d work/ntuser --bn tools/ez/RECmd/BatchExamples/Kroll_Batch.reb --csv work/recmd
Click flag to reveal Google Ai Gemini tool
Q14 — When did alonzo searched it?

The registry stores no per-term time, but WordWheelQuery here holds the single search from Q13, so the key’s last-write time is the time of the search. The RECmd output from Q13 gives it, about 40 seconds after the install finished.

Tip: The time is the key’s last-write time, so it dates the most recent search rather than each term.

Click to reveal answer 2024-03-19 04:32:11

Defense Evasion

Q7 — The malware used a legitimate location to stage its file on the endpoint. Can you find out the Directory path of this location?

Filter the parsed $MFT for entries created in the 04:3x window around the install from Q6. The new files cluster under a vendor-looking folder in Program Files (x86), dressed up as Google. The staging directory is the Google parent folder, which is what the task wants.

MFTECmd -f evidence/C/$MFT --csv work/mft

Gotcha: The files actually sit in the Install subfolder, and that is where the PowerShell command in Q10 points. The task wants the parent directory, Google, and the Install form was rejected.

Click flag to reveal C:\Program Files (x86)\Google
Q11 — Under malware staging Directory, a js file resides which is very small in size.What is the hex offset for this file on the filesystem?

In the Q7 directory, content.js is a few hundred bytes. Its MFT record number is 64067. Each record is 1024 bytes, so the record’s byte offset in the $MFT is 64067 × 1024, written as hex.

python3 -I -c "print(format(64067*1024,'X'))"
Click flag to reveal 3E90C00
Q12 — Recover the contents of this js file so we can forward this to our RE/MA team for further analysis and understanding of this infection chain. To sanitize the payload, remove whitespaces.

As with Q9, the file is resident in MFT record 64067, so its content is in the $DATA attribute of the raw record. The record crosses a 512-byte sector boundary, so apply the update-sequence fixup (the last two bytes of each sector are replaced with the real values from the fixup array) before reading, or the text is corrupted. The script checks a contentScriptExecuted flag in localStorage and, on first run, sends an executeFunction message through chrome.runtime, which is how a browser-extension content script wakes its background worker.

# resident $DATA of MFT entry 64067 after restoring the USA fixup bytes at 510-511 of each sector
import sys; d=open(sys.argv[1],'rb').read(); r=bytearray(d[64067*1024:64068*1024])

Gotcha: Without the fixup, two bytes at the sector boundary come out wrong and corrupt the text of the string. Restore them from the update sequence array before copying.

Click to reveal answer varisContentScriptExecuted=localStorage.getItem('contentScriptExecuted');if(!isContentScriptExecuted){chrome.runtime.sendMessage({action:'executeFunction'},function(response){localStorage.setItem('contentScriptExecuted',true);});}
Q15 — After alonzo could not find any AI tool on the system, he became suspicious, contacted the security team and deleted the downloaded file. When was the file deleted by alonzo?

Deleted files go through the Recycle Bin, and the $I metadata file records the original path, size and deletion time. Run RBCmd over the bin directory. The entry for the RAR from Q3 gives the deletion time, which falls about two minutes after the search in Q14.

RBCmd -d evidence/C/$Recycle.Bin --csv work/rb
Click flag to reveal 2024-03-19 04:34:16

Attack Summary

PhaseAction
Initial AccessSponsored Facebook post for a fake Google Gemini tool opened in Edge
Initial AccessPassword-protected RAR downloaded from a Google Drive direct link
ExecutionMSI from the RAR installed, with a product version unlike the archive name
Executioninstall.cmd runs ru.ps1 through PowerShell with the execution policy bypassed
Defense EvasionFiles staged under Program Files (x86)\Google, including a small content.js that looks like an extension content script
ExecutionUser searches Explorer for the tool and finds nothing
Defense EvasionUser deletes the RAR; it is recoverable from the Recycle Bin

IOCs

TypeValue
URL (lure)hxxps[://]www[.]facebook[.]com/AI[.]ultra[.]new/posts/pfbid0BqpxXypMtY5dWGy2GDfpRD4cQRppdNEC9SSa72FmPVKqik9iWNa2mRkpx9xziAS1l
URL (download)hxxps[://]drive[.]usercontent[.]google[.]com/download?id=1z-SGnYJCPE0HA_Faz6N7mD5qf0E-A76H&export=download
FileAI.Gemini Ultra For PC V1.0.1.rar (password 022024)
MD5 (MSI)BF17D7F8DAC7DF58B37582CEC39E609D
PathC:\Program Files (x86)\Google\Install\nmmhkkegccagdldgiimedpic\
Fileinstall.cmd, ru.ps1, content.js

MITRE ATT&CK

TechniqueIDDescription
User Execution: Malicious FileT1204.002User downloaded and installed the fake AI tool
System Binary Proxy Execution: MsiexecT1218.007Payload delivered as an MSI
Command and Scripting Interpreter: Windows Command ShellT1059.003install.cmd launcher
Command and Scripting Interpreter: PowerShellT1059.001ru.ps1 run with -ExecutionPolicy Bypass
MasqueradingT1036Files staged under a Google-named folder and a brand-themed lure

Defender Takeaways

A sponsored post is an initial-access vector. The lure was a high-reach Page with 200k+ followers, so reputation was no signal. Block or warn on downloads of archives from file-sharing hosts such as Google Drive direct links, and train users to get tools only from vendor sites.

A password-protected archive defeats content scanning. The RAR password (022024) fell to rockyou in minutes, but gateway scanners never saw the MSI. Quarantine encrypted archives on download and detonate them with the password in a sandbox.

Alert on -ExecutionPolicy Bypass launched from a batch file under Program Files. The Windows PowerShell 600 event and process creation both show the chain. A cmd to powershell -File hop from an MSI-created directory is rare in a normal estate.

Legitimate-looking vendor folders are cheap camouflage. Staging under Program Files (x86)\Google hid the files from casual review. Baseline what normally lives there, and alert on new MSI-created subfolders with unfamiliar names.

Recycle Bin and a dirty hive still carry the story. Because the user deleted the RAR normally and did not wipe it, the $I/$R pair preserved both the deletion time and the installer. Preserve the hive transaction logs with the hive when collecting, or keys such as WordWheelQuery are lost.

Conclusion

A convincing sponsored post got a sysadmin to install a trojanized MSI that staged a PowerShell launcher and a script file under a Google-named folder. The user’s own suspicion and a normal delete left the installer, the search and the deletion time all recoverable from standard Windows artifacts.