浏览器历史存在哪
主流浏览器的历史记录都是 SQLite 数据库:Chromium 系(Chrome、Edge、国内多数双核浏览器)在用户数据目录的 Default\History 里存 urls、visits 与 downloads 等表;Firefox 用 places.sqlite 存访问记录。这些库记录访问时间、URL、标题与下载目标,是还原“这台机器访问过什么”的高价值来源。时间戳需要用各自纪元换算:Chromium 是自 1601-01-01 起的微秒数,Firefox 是自 1970-01-01 起的微秒数。
基本信息
| 适用平台 | Windows / macOS / Linux 上的 Chrome、Edge、Firefox 等 |
|---|---|
| Chromium 路径 | %LOCALAPPDATA%\Google\Chrome\User Data\Default\History(Edge 为 Microsoft\Edge\User Data\Default\History) |
| Firefox 路径 | %APPDATA%\Mozilla\Firefox\Profiles\<随机>.default-release\places.sqlite |
| 辅助文件 | 同目录的 -journal / -wal 文件包含尚未合并的最近事务 |
| 时间换算 | Chromium:datetime((last_visit_time/1000000)-11644473600,'unixepoch');Firefox:datetime(visit_date/1000000,'unixepoch') |
典型使用场景
- 确认用户或攻击者访问过哪些站点,尤其是与恶意投递相关的下载页与网盘页
- 还原下载行为:下载表记录目标路径与源 URL,可与落地文件哈希对应
- 判断访问是人工操作还是脚本发起:时间间隔与访问序列有明显差异
- 为钓鱼事件提供链路证据:从邮件链接到浏览器访问到文件落地的完整顺序
- 跨浏览器补全:同时存在多个浏览器与多个用户配置目录,逐个解析才完整
只读查询
只读查询
# 复制副本再查,同时带走 journal/wal,避免锁库影响运行中的浏览器
cp History History-journal /case/out/ 2>/dev/null
# 最近访问的 URL 与时间(Chromium 时间戳换算)
sqlite3 -readonly /case/out/History "select url, title, datetime((last_visit_time/1000000)-11644473600,'unixepoch') as t from urls order by last_visit_time desc limit 20;"
# 下载记录:源 URL 与目标路径
sqlite3 -readonly /case/out/History "select target_path, start_time from downloads;"
# Firefox 最近访问
sqlite3 -readonly places.sqlite "select url, datetime(visit_date/1000000,'unixepoch') from moz_places, moz_historyvisits where moz_places.id=moz_historyvisits.place_id order by visit_date desc limit 20;"常用表与列
| 表 / 列 | 含义 | 判读要点 |
|---|---|---|
| urls.url / last_visit_time | 访问过的 URL 与最后访问时间 | 时间需换算,直接读数字会得到 1601 年附近的错误结果 |
| visits.visit_time | 每一次访问事件 | 用于统计访问次数与间隔,判断是否人工操作 |
| downloads.target_path | 下载文件的落盘路径 | 与文件系统时间、哈希比对可确认落地物 |
| downloads_url_chains | 下载源 URL 链 | 含跳转链时可还原投递基础设施 |
| places.sqlite(moz_places) | Firefox 访问记录 | 表结构稳定,配合 moz_historyvisits 看逐次访问 |
分析的浏览器若仍在运行,数据库会处于加锁与脏页状态,直接打开可能读到不完整数据;先复制主库与 journal/wal 文件,再在副本上查询。
无痕模式、隐私清理与同步账号会把访问记录留在别处或不留痕,历史为空不代表没有访问,需结合 DNS 缓存、代理日志与网关记录补证。