Synapse Consulting
Home SynapseRM / TPRM Services Pricing About BlogCareersLabsContact
EN · FR
Test access Book a demo

Forensics · SQLite · Browser history · MITRE T1070

What they deleted: recovering browser history from SQLite

Browsers keep their history in a SQLite database, and a deleted row is rarely gone. When SQLite frees a cell it does not wipe it, so the bytes linger in the file until they are reused. Read the live history, then recover the one entry the user erased on NORTHSEA-DEV.

~45 minEstimated time
sqlite3 · strings · xxdTools
T1070 · T1204 · T1552MITRE ATT&CK
★★☆☆ IntermediateSQLiteRecovery

The sample

FileHistory (SQLite 3)
SHA-256eba54746bb0e640402bc449b8b70743e57c07640368bb26b8f31a3830642f27e
ShapeChrome-style urls / visits / downloads
ContextProfile from NORTHSEA-DEV (alex)

The .zip carries the database, a README disclaimer and the Synapse logo. Everything is synthetic (.example / .invalid). Analyse in an isolated VM.

1. Scenario

Browsers store history, downloads and cookies in SQLite files. When a user clears an entry, the row is unlinked but, unless secure_delete is on or a VACUUM runs, the raw bytes stay in the database free space. That is a gift for a forensic analyst.

You get the History database from the suspect's profile. Read what is live, then recover what was deleted.

⚠️ Disclaimer: this is a fully synthetic Chrome-style History database. All URLs, titles and timestamps are fictional (.example / .invalid). No real person or browsing is involved.

2. Objectives

3. Step-by-step analysis

1

Open the database and read the schema

sqlite3

Work on a copy. Confirm it is SQLite, then list the tables. Chrome uses urls, visits and downloads.

bash
file History
sqlite3 History '.tables'
sqlite3 History '.schema urls'
output
History: SQLite 3.x database
urls  visits  downloads
CREATE TABLE urls(id INTEGER PRIMARY KEY, url, title, visit_count,
  typed_count, last_visit_time, hidden);

💡 last_visit_time is not a normal timestamp: Chrome counts microseconds since 1601-01-01 (the WebKit epoch). You will convert it in the next step.

2

Read the live history

SQL + time conversion

List the URLs with a readable time by converting the WebKit epoch, and check the downloads.

bash
sqlite3 History "SELECT datetime(last_visit_time/1000000-11644473600,'unixepoch') t,
  url, title FROM urls ORDER BY last_visit_time;"
sqlite3 History "SELECT target_path, tab_url FROM downloads;"
output
2026-06-16 08:38  https://stackoverflow.example/q/12345  reflective assembly load powershell
2026-06-16 08:39  https://duckduckgo.example/?q=how+to+clear+bash+history  how to clear bash history
...
C:\Users\alex\Downloads\orion-export.zip   https://file-share.example/u/8f2c1a9d

🔍 Behaviour already tells a story: searches for reflective assembly load powershell and how to clear bash history, plus a download of orion-export.zip via a file-sharing site. But the live history stops at 08:39, and the incident (lab #07) fired at 08:41. Something is missing.

3

Recover the deleted record

strings · xxd

The live tables and even sqlite3 .recover miss rows that were freed to the page free list. Carve the raw file instead.

bash
# .recover misses freelist rows, so carve the bytes
strings History | grep -Ei 'verify|captcha|invalid'
xxd History | grep -i verify
output
http://verify-cdn.example.invalid/captcha?ray=8f2c1a9d
Verify you are human - Cloud CDN

🔴 Recovered from free space: a visit to verify-cdn.example.invalid/captcha titled Verify you are human. That is the ClickFix lure page, and the user deleted it to cover their tracks (MITRE T1070).

4

Timeline and conclusion

synthesis

The deleted cell still carries its visit_time. Decoded, it lands at 2026-06-16 08:40, one minute before the pasted PowerShell in lab #07.

bash
# the recovered visit_time (WebKit) decodes to:
#   2026-06-16 08:40:00 UTC
# lab #07 RunMRU execution: 2026-06-16 08:41 UTC
output
08:39  search: how to clear bash history
08:40  visit:  verify-cdn.example.invalid/captcha   <- DELETED, recovered
08:41  exec:   powershell -enc ...  (lab #07)

✅ The recovered entry is the missing link: the user reached the fake-CAPTCHA page, ran the ClickFix command, then cleared that one line of history. The browser database preserved it anyway.

4. Notes and detection

5. IOC and ATT&CK summary

TypeValueATT&CK
Deleted artefactverify-cdn.example.invalid/captcha (ClickFix lure)T1070
Intent searchreflective assembly load powershellT1204
Anti-forensics searchhow to clear bash historyT1070
Downloadorion-export.zip via file-share.exampleT1567
Recovery sourceSQLite free space (no VACUUM / secure_delete)T1005

6. References

MITRE T1070, Indicator Removal

Clearing history and artefacts to hide activity.

The SQLite file format

Pages, cells and the free list, the basis of deleted-record recovery.

SQLite forensics, Belkasoft

Recovering deleted records from WAL, journal and free pages.

undark, SQLite deleted-data recovery

A tool that carves deleted rows from the free list.

Entirely fictional environment, for educational use only. All URLs and titles are synthetic.

Synapse Consulting

A Belgium-based provider of cybersecurity solutions, and the team behind SynapseRM / TPRM.

PLATFORM
SynapseRM / TPRM Pricing Test accessPresentation (PDF)
SERVICES
Governance Operational Training
COMPANY
About Contact Blog Labs Careers Privacy & cookies
Brussels, Belgium