// HackTheBox  ·  writeup

HookFlare

HackTheBox Medium debugfssqlite3tsharkPython
DFIR

Scenario

In this Sherlock challenge, players will investigate an Android data dump and reverse-engineer a malicious APK to uncover the malware’s functionality and identify what data was stolen.

Executive Summary

A phishing SMS pointed the victim at a fake banking app. Chrome downloaded the APK and the victim sideloaded it roughly 43 minutes after the message arrived. The app was granted a handful of runtime permissions, SMS among them, and used the SMS read operation within minutes of the download. Static analysis of the APK’s dex string table showed it checking a hard-coded HTTP server for liveness before posting harvested data, with a Discord webhook held as the fallback. Payloads were AES-encrypted with a key embedded in the app, so the same strings decrypted the captured traffic and exposed the stolen payment card details.

Artifacts

Timestamp note: Android stores times as epoch milliseconds and Chrome uses its own epoch. Convert everything to UTC and drop the milliseconds before answering in YYYY-MM-DD hh:mm:ss.

Initial Access

Q1 — Provide the UTC timestamp of the phishing SMS.

Extract the userdata tree from the image, then open the telephony provider database mmssms.db. The sms table holds one inbound message from 14356951192 carrying the lure link. Its date column is epoch milliseconds (1738426832000), which converts to the answer in UTC.

debugfs -R "rdump /android-9.0-r2/data work/x" evidence/HookFlare.dd
sqlite3 mmssms.db "select address, date, body from sms"

Gotcha: rdump on ext4 prints a pile of chown errors when run unprivileged. The files are still extracted.

Click flag to reveal 2025-02-01 16:20:32
Q2 — Provide the UTC timestamp marking the start of the malicious application download.

The lure led to a browser download, so the Chrome History database is the artifact. In the downloads table, the S1rBank.apk row carries a start_time that converts to the answer, about 43 minutes after the SMS from Q1.

sqlite3 History "select target_path, start_time from downloads"

Gotcha: The Android download manager’s downloads.db shows a lastmod two seconds later. The question asks when the download started, so Chrome’s start_time is the one that matches.

Click to reveal answer 2025-02-01 17:03:23

Execution

Q3 — Provide the package name of the malicious application.

A sideloaded app leaves a directory under /data/app named after its package, and the same name appears in the package manager state. That ties it to the S1rBank.apk download from Q2.

ls work/x/data/app
Click flag to reveal com.s1rx58.s1rbank
Q4 — Provide the number of runtime permissions granted to the malicious application.

Search runtime-permissions.xml for the Q3 package. The entry lists each runtime permission with a granted flag; count the ones set to true.

grep -A12 s1rbank runtime-permissions.xml
Click to reveal answer 4

Collection

Q5 — Provide the last access timestamp for the read sms permission used by the malicious application.

appops.xml records per-package app-op usage. Under the Q3 package, op 14 is the SMS read operation. Its tt attribute (last access time) is 1738429638041, which converts to the answer, about four minutes after the download started.

grep -A20 s1rbank appops.xml
Click flag to reveal 2025-02-01 17:07:18

Exfiltration

Q6 — Provide the URL used by the malware for data exfiltration.

Without a decompiler, a small Python parser over classes.dex dumps the string table, and the URLs stand out. The capture confirms the choice: the infected phone POSTs to /api/data on s1rbank.net over port 80.

python3 -I dexstr.py classes.dex | grep -i http
tshark -r HookFlare.pcap -Y http.request -T fields -e http.request.method -e http.host -e http.request.uri
Click to reveal answer http://s1rbank.net:80/api/data

Command and Control

Q7 — The malicious application checks if the server is live before sending data. Provide the HTTP method used for this check.

The same tshark listing from Q6 shows a lightweight request to the server ahead of each exfiltration POST. That request is the liveness probe.

tshark -r HookFlare.pcap -Y http.request -T fields -e frame.time -e http.request.method -e http.request.uri
Click flag to reveal HEAD
Q8 — If the primary server is unavailable, the malicious application redirects data exfiltration to an alternate URL. Identify and provide the alternate URL.

The dex string dump holds a second endpoint beside the primary one: a Discord webhook. The fallback never shows in the capture because the primary server answered the probe, so the APK is the only place it appears.

python3 -I dexstr.py classes.dex | grep -i discord
Click to reveal answer https://discord.com/api/webhooks/1334648260610097303/-Lkxr0eZRO_fb_SaumBbBMZyANM3lyeCkR-E1NXXRASPbtRdNksQSzx4pY1ZGQkFR2H8
Q9 — The malicious application encrypts data before sending it to the server. Provide the encryption key used.

The POST bodies in the capture are opaque, but the dex strings contain a 32-character key-like string, the right length for AES-256. That reasoning is the evidence here: the key was picked by length and then proven by use, not read from a labelled field. Trying it as an AES-256-ECB key against the POST bodies (base64-decoded, then hex-decoded) produced readable text on the first attempt, which confirms both the key and the scheme.

python3 -I dexstr.py classes.dex | awk 'length($0)==32'

Tip: The answer’s format mask is 32 characters wide. Next to an app that encrypts its traffic, that points straight at AES-256.

Click flag to reveal 0x_S1r_x58!@#53cuReK371337!$%^&*
Q10 — Credit card information was stolen. What was the second line in the exfiltrated payment information?

Pull the first captured POST body and decrypt it with the Q9 key. The plaintext is a multi-line block of payment details, and its second line is the card number line.

tshark -r HookFlare.pcap -Y 'http.request.method==POST' -T fields -e http.file_data
Click to reveal answer Card Number: 5453004085527987

Attack Summary

PhaseAction
Initial AccessPhishing SMS delivers a link to a fake banking app
Initial AccessChrome downloads S1rBank.apk
ExecutionApp installed as com.s1rx58.s1rbank and granted four runtime permissions
CollectionApp performs an SMS read about four minutes after the download starts
Command and ControlApp probes s1rbank.net with HEAD before sending data
ExfiltrationAES-encrypted payloads POSTed to /api/data; Discord webhook held as fallback
CollectionPayment card details harvested and sent

IOCs

TypeValue
Packagecom.s1rx58.s1rbank
FileS1rBank.apk
Phishing sender14356951192
URL (primary)hxxp[://]s1rbank[.]net:80/api/data
URL (fallback)hxxps[://]discord[.]com/api/webhooks/1334648260610097303/-Lkxr0eZRO_fb_SaumBbBMZyANM3lyeCkR-E1NXXRASPbtRdNksQSzx4pY1ZGQkFR2H8
AES key0x_S1r_x58!@#53cuReK371337!$%^&*

MITRE ATT&CK

TechniqueIDDescription
PhishingT1660Smishing message with a link to the fake banking app
Protected User Data: SMS MessagesT1636.004App uses the SMS read operation after install
Application Layer Protocol: Web ProtocolsT1437.001HEAD and POST to the C2 over HTTP
Fallback ChannelsT1008Discord webhook used when the primary server is down
Encrypted Channel: Symmetric CryptographyT1521.001AES-256-ECB with a hard-coded key
Exfiltration Over C2 ChannelT1646Stolen data POSTed to /api/data
Exfiltration Over WebhookT1567.004Discord webhook as the alternate exfiltration path

Defender Takeaways

Sideloading from a browser download should be blocked or flagged. The app arrived as an APK fetched by Chrome from an SMS link. Blocking installs from unknown sources, or alerting on them through mobile device management, removes the whole delivery path.

An SMS read by a freshly installed banking app is a red flag. The app used the SMS read operation within minutes of the download. Review permission grants on apps from outside the official store, and watch app-op usage for SMS access.

Cleartext HTTP exfiltration is visible even when the payload is encrypted. The HEAD-then-POST pattern to an unknown host on port 80 stands out in network logs. Egress filtering and DNS reputation would have flagged it.

Hard-coded keys make the encryption worthless against the responder. The AES key sat in the dex strings, so the whole stolen payload was recoverable from a packet capture. The same strings expose fallback infrastructure such as the Discord webhook, which can be reported for takedown.

Conclusion

A single smishing link put a fake banking app on the phone, and payment card data left it within minutes. Because the app’s key and both exfiltration endpoints sat in its strings, the APK plus a packet capture were enough to reconstruct exactly what was stolen.