$npx -y skills add killvxk/cybersecurity-skills-zh --skill analyzing-browser-forensics-with-hindsight使用 Hindsight 分析基于 Chromium 的浏览器痕迹,从 Chrome、Edge、Brave 和 Opera 中提取浏览历史、下载记录、Cookie、缓存内容、自动填充数据、已保存密码和浏览器扩展,用于取证调查。
| 1 | # 使用 Hindsight 分析浏览器取证 |
| 2 | |
| 3 | ## 概述 |
| 4 | |
| 5 | Hindsight 是一款开源浏览器取证(Browser Forensics)工具,专为解析 Google Chrome 和其他基于 Chromium 的浏览器(Microsoft Edge、Brave、Opera、Vivaldi)的痕迹而设计。它从多个浏览器数据库文件中提取和关联数据,创建统一的网络活动时间线。Hindsight 可以解析 URL、下载历史、缓存记录、书签、自动填充记录、已保存密码、浏览器偏好设置、浏览器扩展、HTTP Cookie、本地存储(HTML5 Cookie)、登录数据以及会话/标签信息。该工具以多种输出格式(XLSX、JSON、SQLite)生成按时间顺序排列的时间线,使调查人员能够重建用户网络活动,适用于事件响应(Incident Response)、内部威胁调查和刑事案件。 |
| 6 | |
| 7 | ## 前置条件 |
| 8 | |
| 9 | - Python 3.8+ 并安装 Hindsight(`pip install pyhindsight`) |
| 10 | - 可访问取证镜像中的浏览器配置文件目录 |
| 11 | - 浏览器配置文件数据(未使用操作系统级加密) |
| 12 | - 用于分析的 Timeline Explorer 或电子表格应用程序 |
| 13 | |
| 14 | ## 浏览器配置文件位置 |
| 15 | |
| 16 | | 浏览器 | Windows 配置文件路径 | |
| 17 | |--------|---------------------| |
| 18 | | Chrome | %LOCALAPPDATA%\Google\Chrome\User Data\Default\ | |
| 19 | | Edge | %LOCALAPPDATA%\Microsoft\Edge\User Data\Default\ | |
| 20 | | Brave | %LOCALAPPDATA%\BraveSoftware\Brave-Browser\User Data\Default\ | |
| 21 | | Opera | %APPDATA%\Opera Software\Opera Stable\ | |
| 22 | | Vivaldi | %LOCALAPPDATA%\Vivaldi\User Data\Default\ | |
| 23 | | Chrome (macOS) | ~/Library/Application Support/Google/Chrome/Default/ | |
| 24 | | Chrome (Linux) | ~/.config/google-chrome/Default/ | |
| 25 | |
| 26 | ## 关键痕迹文件 |
| 27 | |
| 28 | | 文件 | 内容 | |
| 29 | |------|------| |
| 30 | | History | URL 访问记录、下载记录、关键词搜索 | |
| 31 | | Cookies | 带域名、过期时间和值的 HTTP Cookie | |
| 32 | | Web Data | 自动填充条目、已保存的信用卡 | |
| 33 | | Login Data | 已保存的用户名/密码(已加密) | |
| 34 | | Bookmarks | JSON 格式的书签树 | |
| 35 | | Preferences | 浏览器配置和扩展 | |
| 36 | | Local Storage/ | 每个域名的 HTML5 本地存储 | |
| 37 | | Session Storage/ | 每个域名的会话专属存储 | |
| 38 | | Network Action Predictor | 之前输入过的 URL | |
| 39 | | Shortcuts | 地址栏快捷方式和预测 | |
| 40 | | Top Sites | 常访问的网站 | |
| 41 | |
| 42 | ## 运行 Hindsight |
| 43 | |
| 44 | ### 命令行 |
| 45 | |
| 46 | ```bash |
| 47 | # 基本的 Chrome 配置文件分析 |
| 48 | hindsight.exe -i "C:\Evidence\Users\suspect\AppData\Local\Google\Chrome\User Data\Default" -o C:\Output\chrome_analysis |
| 49 | |
| 50 | # 指定浏览器类型 |
| 51 | hindsight.exe -i "/path/to/profile" -o /output/analysis -b Chrome |
| 52 | |
| 53 | # JSON 输出格式 |
| 54 | hindsight.exe -i "C:\Evidence\Chrome\Default" -o C:\Output\chrome --format jsonl |
| 55 | |
| 56 | # 带缓存解析(较慢但更完整) |
| 57 | hindsight.exe -i "C:\Evidence\Chrome\Default" -o C:\Output\chrome --cache |
| 58 | ``` |
| 59 | |
| 60 | ### Web 界面 |
| 61 | |
| 62 | ```bash |
| 63 | # 启动 Hindsight Web 界面 |
| 64 | hindsight_gui.exe |
| 65 | # 访问 http://localhost:8080 |
| 66 | # 上传或指向浏览器配置文件目录 |
| 67 | # 配置输出格式和分析选项 |
| 68 | # 生成并下载报告 |
| 69 | ``` |
| 70 | |
| 71 | ## 痕迹分析详情 |
| 72 | |
| 73 | ### URL 历史与访问记录 |
| 74 | |
| 75 | ```sql |
| 76 | -- Chrome History 数据库结构(关键表) |
| 77 | -- urls 表: id, url, title, visit_count, typed_count, last_visit_time |
| 78 | -- visits 表: id, url, visit_time, from_visit, transition, segment_id |
| 79 | |
| 80 | -- 时间戳为 Chrome/WebKit 格式:自 1601-01-01 起的微秒数 |
| 81 | -- 转换: datetime((visit_time/1000000)-11644473600, 'unixepoch') |
| 82 | ``` |
| 83 | |
| 84 | ### 下载历史 |
| 85 | |
| 86 | ```sql |
| 87 | -- downloads 表: id, current_path, target_path, start_time, end_time, |
| 88 | -- received_bytes, total_bytes, state, danger_type, interrupt_reason, |
| 89 | -- url, referrer, tab_url, mime_type, original_mime_type |
| 90 | ``` |
| 91 | |
| 92 | ### Cookie 分析 |
| 93 | |
| 94 | ```sql |
| 95 | -- cookies 表: creation_utc, host_key, name, value, encrypted_value, |
| 96 | -- path, expires_utc, is_secure, is_httponly, last_access_utc, |
| 97 | -- has_expires, is_persistent, priority, samesite |
| 98 | ``` |
| 99 | |
| 100 | ## Python 分析脚本 |
| 101 | |
| 102 | ```python |
| 103 | import sqlite3 |
| 104 | import os |
| 105 | import json |
| 106 | import sys |
| 107 | from datetime import datetime, timedelta |
| 108 | |
| 109 | |
| 110 | CHROME_EPOCH = datetime(1601, 1, 1) |
| 111 | |
| 112 | |
| 113 | def chrome_time_to_datetime(chrome_ts: int): |
| 114 | """Convert Chrome timestamp to datetime.""" |
| 115 | if chrome_ts == 0: |
| 116 | return None |
| 117 | try: |
| 118 | return CHROME_EPOCH + timedelta(microseconds=chrome_ts) |
| 119 | except (OverflowError, OSError): |
| 120 | return None |
| 121 | |
| 122 | |
| 123 | def analyze_chrome_history(profile_path: str, output_dir: str) -> dict: |
| 124 | """Analyze Chrome History database for forensic evidence.""" |
| 125 | history_db = os.path.join(profile_path, "History") |
| 126 | if not os.path.exists(history_db): |
| 127 | return {"error": "History database not found"} |
| 128 | |
| 129 | os.makedirs(output_dir, exist_ok=True) |
| 130 | conn = sqlite3.connect(f"file:{history_db}?mode=ro", uri=True) |
| 131 | |
| 132 | # URL visits with timestamps |
| 133 | cursor = conn.cursor() |
| 134 | cursor.execute(""" |
| 135 | SELECT u.url, u.title, v.visit_time, u.visit_count, |
| 136 | v.transition & 0xFF as transition_type |
| 137 | FROM visits v JOIN urls u ON v.url = u.id |
| 138 | ORDER BY v.visit_time DESC LIMIT 5000 |
| 139 | """) |
| 140 | visits = [{ |
| 141 | "url": r[0], "title": r[1], |
| 142 | "visit_time": str(chrome_time_to_datetime(r[2])), |
| 143 | "total_visits": r[3], "transition": r[4] |
| 144 | } for r in cursor.fetchall()] |
| 145 | |
| 146 | # Downloads |
| 147 | cursor.execute(""" |
| 148 | SELECT target_path, tab_url, start_time, end_time, |
| 149 | received_bytes, total_bytes, mime_type, state |
| 150 | FROM downloads ORDER BY start_time DESC LIMIT 1000 |
| 151 | """) |
| 152 | downloads = [{ |
| 153 | "path": r[0], "source_url": r[1], |
| 154 | "start_time": str(chrome_time_to_datetime(r[2])), |
| 155 | "end_time": str(chrome_time_to_datetime(r[3])), |
| 156 | "received_bytes": r[4], "total_bytes": r[5], |
| 157 | "mime_type": r[6], "state": r[7] |
| 158 | } for r |