
网络安全应用安全密码学CLI【免费下载链接】HackBrowserDataExtract and decrypt browser data, supporting multiple data types, runnable on various operating systems (macOS, Windows, Linux).项目地址https://gitcode.com/gh_mirrors/ha/HackBrowserData点击查看免费下载本篇技术指南以 HackBrowserData 的 RFC-008: File Acquisition Platform Quirks 为骨架深入剖析该浏览器数据提取工具如何通过先复制、后读取copy-then-read策略规避浏览器运行时文件锁定问题从filemanager会话生命周期、SQLite WAL/SHM 伴随文件复制、Windows 独占锁绕过DuplicateHandle 内存映射 I/O到 LevelDB 目录处理与 SQLite 查询辅助函数。读完你将掌握该工具的底层文件获取架构并能在自己的取证、渗透或数据迁移工具中复现这一套可跨平台运行的文件获取方案。1. 背景浏览器运行时的文件锁定困局浏览器在运行时通常保持数据文件打开且往往处于锁定状态。其中 Chromium 系浏览器在 Windows 上的表现最为激进它通过PRAGMA locking_modeEXCLUSIVE对Cookies等数据库持有排他锁导致外部进程无法以常规方式打开文件读取内容。即使在 macOS 和 Linux 上直接读取运行中的实时数据库也可能返回损坏或不一致的数据——因为 WALWrite-Ahead Log中的数据尚未 checkpoint 回主数据库文件直接读取会漏掉最近几秒写入的记录。为此RFC-008 确立了该项目的核心策略copy-then-read先复制、后读取把所有需要的文件复制到一个隔离的临时目录中再从副本中提取数据。该策略由filemanager包负责整个生命周期管理见 filemanager/session.go而 Windows 平台上的锁定文件则通过专门的底层 fallback 机制处理见 filemanager/copy_windows.go。2. Session 会话管理临时目录的创建、获取与清理Session封装了单次浏览器 profile 提取运行所对应的一个临时目录。整个生命周期只有三个步骤却覆盖了全部资源管理责任步骤方法职责1. CreateNewSession()通过os.MkdirTemp(, hbd-*)创建唯一临时目录2. AcquireAcquire(src, dst, isDir)把浏览器文件或目录复制进会话3. CleanupCleanup()递归删除整个临时目录树总是以defer调用源码中NewSession的实现filemanager/session.go十分简洁os.MkdirTemp(, hbd-*)会在系统临时目录下生成形如hbd-随机后缀的唯一目录从而避免多次运行之间的路径冲突。// NewSession creates a session with a unique temporary directory. func NewSession() (*Session, error) { dir, err : os.MkdirTemp(, hbd-*) if err ! nil { return nil, fmt.Errorf(create temp dir: %w, err) } return Session{tempDir: dir}, nil }Cleanup则调用os.RemoveAll(s.tempDir)删除整个目录树。在 HackBrowserData 的实际调用方中NewSession与defer session.Cleanup()总是成对出现例如browser/chromium/profile.go 中初始化会话并defer清理browser/firefox/profile.go 与 browser/safari/profile.go 遵循同一模式browser/archive.go 中跨主机归档流程同样基于NewSessionCleanup。这种defer 清理模式保证了即使提取过程中出错临时目录也会被回收不会在磁盘上留下敏感数据残留。3. Acquire 复制流程统一入口与分派逻辑Acquire是所有浏览器文件复制的唯一入口filemanager/session.go。它根据isDir参数分派到两条路径Acquire(src, dst, isDir) ├── isDirtrue → copyDir(src, dst, skiplock) │ └── isDirfalse → copyFile(src, dst) ├── success ──┐ └── failure Windows → copyLocked(src, dst) └── success ──┐ copy -wal 和 -shm 伴随文件若存在3.1 copyFile常规单文件复制filemanager/copy.go 中的copyFile实现非常简单os.ReadFile读取源文件内容再以0o600仅属主可读写权限os.WriteFile写入目标。权限位0o600是刻意的安全选择——临时目录中存放的是 Cookie、密码等敏感数据不应让其他用户可读。3.2 copyDir目录复制并跳过锁文件copyDir借助第三方库github.com/otiai10/copy并通过Skip回调跳过路径以lock结尾的文件大小写不敏感strings.HasSuffix(strings.ToLower(src), lock)。这正是为 LevelDB 目录专门设计的过滤逻辑详见第 6 节。3.3 失败分支仅 Windows 启用锁定文件 fallbackcopyFile失败时Acquire不会盲目重试err : copyFile(src, dst) if err ! nil { if runtime.GOOS ! windows { return fmt.Errorf(copy: %w, err) } if err2 : copyLocked(src, dst); err2 ! nil { return errors.Join( fmt.Errorf(copy: %w, err), fmt.Errorf(locked copy: %w, err2), ) } }关键点只有runtime.GOOS windows才尝试copyLocked。非 Windows 平台的copyLocked是一个永远返回错误的占位实现filemanager/copy_other.go注释明确指出文件锁定主要是 Windows 的问题——macOS/Linux 上 SQLite 使用fcntl/flock咨询锁不会阻止其他进程读取常规复制路径即可正常工作。4. SQLite 伴随文件-wal / -shm的自动复制使用WAL 模式的 SQLite 数据库会维护两个伴随文件文件全称作用-walWrite-Ahead Log预写日志暂存尚未 checkpoint 回主库的新写入-shmShared Memory共享内存索引用于 WAL 索引的进程间共享在Acquire成功复制主文件后会自动检查并复制这两个伴随文件filemanager/session.go// Copy SQLite WAL/SHM companion files if present var walErrs []error for _, suffix : range []string{-wal, -shm} { walSrc : src suffix if isFileExists(walSrc) { if err : copyFile(walSrc, dstsuffix); err ! nil { walErrs append(walErrs, fmt.Errorf(copy %s: %w, suffix, err)) } } } return errors.Join(walErrs...)RFC-008 特别强调了这一点没有 WAL 文件最近几秒写入的数据例如刚设置的 Cookie就会丢失。这是保证提取结果与浏览器实际状态一致的关键细节。注意伴随文件复制失败不会让整个Acquire失败——错误被收集后通过errors.Join合并返回由调用方决定严重程度。5. 文件去重多个类别共享同一源文件不同数据类别可能共享同一个源文件。HackBrowserData 的源文件映射表browser/chromium/source.go 与 browser/firefox/source.go清晰地体现了这一点引擎类别共享源文件ChromiumHistory DownloadHistoryFirefoxHistory Download Bookmarkplaces.sqlite每个类别在临时目录中拥有独立的目标路径因此同一个源文件可能被复制多次。RFC-008 明确说明这是有意为之每个 extract 函数期望拿到自己独立的文件路径例如extract_history.go与extract_download.go分别处理History文件的不同数据表对小体积的 SQLite 文件而言重复复制的成本可以忽略不计这也让复制到隔离目录再提取的架构保持简单提取逻辑无需处理路径共享与并发冲突。从实现看Chromium 的类别映射还展示了另一层细节Password与Cookie各自带有备选路径如Network/Cookies与Cookies两个候选按优先级顺序第一个存在的路径胜出为不同版本/厂商的浏览器布局差异留出了兼容空间。6. Windows 独占锁文件处理DuplicateHandle 内存映射6.1 问题根源Chromium 在 Windows 上对部分数据库尤其Cookies持有排他锁。Chrome 1142023 年起通过 Lock profile cookie files on disk 特性对 cookies 数据库启用PRAGMA locking_modeEXCLUSIVE配合dwShareMode0不允许任何共享的文件打开方式完全阻止外部进程在浏览器运行时读取 cookie 数据。这是Windows 特有的问题macOS 和 Linux 上的fcntl/flock是咨询锁不阻止其他进程读取常规复制路径在这些平台畅通无阻。6.2 绕过方案RFC-008 指向 RFC-009: Windows Locked File Bypass 获取完整技术细节。核心思路是使用 Windows 内核 API 完成借鸡生蛋NtQuerySystemInformation枚举系统句柄 → 找到 Chrome 持有目标文件的句柄 → DuplicateHandle 复制进本进程 → CreateFileMappingW MapViewOfFile从内核文件缓存读取 → 写入临时目标实现位于 filemanager/copy_windows.go完整链路为copyLocked→findFileHandle→readFileContentfindFileHandleL43-L104通过winapi.QuerySystemHandles()底层为NtQuerySystemInformation枚举系统内所有打开句柄对每个句柄OpenProcess(PROCESS_DUP_HANDLE)打开属主进程并DuplicateHandle复制到当前进程随后用GetFileType过滤出FileTypeDisk磁盘文件再以GetFinalPathName获取完整路径做匹配。整个过程只需要普通用户权限不需要管理员权限。路径匹配的稳定性extractStableSuffixL152-L166从路径中提取AppData\Local\或AppData\Roaming\之后的部分做后缀匹配规避了短路径名如RUNNER~1与runneradmin导致的路径不一致问题——例如Google\Chrome\User Data\Default\Network\Cookies这样的稳定后缀能唯一定位目标文件。readFileContentL111-L139优先使用CreateFileMappingMapViewOfFile内存映射读取——从操作系统内核文件缓存读取能包含 Chrome 已写入但尚未 checkpoint 的 WAL 数据若 FileMapping 失败则回退到ReadFile先Seek到文件开头因为复制来的句柄文件指针可能位于任意位置。copyLocked失败时Acquire使用errors.Join把原始复制错误与锁定复制错误合并返回为排查问题保留完整的错误链。7. LevelDB 目录处理复制整目录、跳过 LOCK 文件Chromium 将 localStorage 与 sessionStorage 存储为LevelDB 目录而非单文件类别路径类型LocalStorageLocal Storage/leveldb/directorySessionStorageSession Storage/directory在 browser/chromium/source.go 中这两个类别以dir(...)标记isDirtrue从而让Acquire走copyDir分支。copyDir复制整个目录时跳过LOCK文件见 filemanager/copy.go。原因在 RFC-008 中说明得很清楚LevelDB 用LOCK文件做单进程访问控制若把它复制出来可能与正在运行的浏览器发生冲突。跳过该文件后提取工具拿到的是无锁的完整快照可以安全地逐个读取其中的.ldb/.log数据文件。8. SQLite 查询辅助函数统一提取模式提取阶段的核心是三个查询辅助函数全部集中在 utils/sqliteutil 包中。8.1 QuerySQLite标准提取模式封装QuerySQLiteutils/sqliteutil/sqlite.go封装了所有 SQLite 提取共用的固定套路校验文件存在——os.Stat(dbPath)防止sql.Open悄悄创建一个空数据库sql.Open(sqlite, dbPath)打开数据库驱动为modernc.org/sqlite纯 Go 实现可选PRAGMA journal_modeoff见 8.3执行查询迭代行并调用容错的 scan 回调。错误处理策略是它的核心设计行级 scan 错误仅记日志并跳过对损坏记录的优雅降级数据库级错误则中止查询for rows.Next() { if err : scanFn(rows); err ! nil { log.Debugf(scan row error: %v, err) continue } } return rows.Err()这意味着个别字段类型异常、个别记录损坏不会让整个提取崩溃——一个浏览器数据库里若有几条脏数据其余几百条仍能被完整提取。8.2 QueryRows[T]泛型样板消除器QueryRows[T]utils/sqliteutil/query.go是 Go 1.18 泛型封装把结果收集进类型化切片消除样板代码。每个 extract 函数只需提供扫描函数即可func QueryRowsT any (T, error)) ([]T, error) { var items []T err : QuerySQLite(dbPath, journalOff, query, func(rows *sql.Rows) error { item, err : scanRow(rows) if err ! nil { return err } items append(items, item) return nil }) return items, err }实际用法可见 browser/chromium/extract_cookie.goextract 函数传入types.CookieEntry类型参数、false不关 journal、SQL 查询与一个从*sql.Rows扫描出CookieEntry的闭包返回值即为已排序的完整 Cookie 切片。同包还有配套的CountRowsutils/sqliteutil/query.go用QueryRow做计数查询采取快速失败语义scan 失败直接返回错误。8.3 Firefox 强制 journal_modeoffChromium 不关RFC-008 记录了一个重要的平台差异决策Firefox 的所有提取调用都使用journal_modeoff。Firefox 数据库在生产环境中使用 WAL 模式而modernc.org/sqlite驱动在打开临时副本时可能尝试WAL 回放replay。关闭 journal 后驱动把数据库当作只读快照处理杜绝回放带来的副作用。这一行为在源码中得到证实Firefox 侧全部提取与计数调用都传入true例如 browser/firefox/extract_bookmark.go、browser/firefox/extract_cookie.go、browser/firefox/extract_download.go。Chromium 的提取调用不关闭 journal因为Acquire已经复制了 WAL/SHM 伴随文件SQLite 拥有干净 WAL 回放所需的全部材料。同样在源码中得到证实Chromium 各 extract 函数统一传false如 browser/chromium/extract_cookie.go、browser/chromium/extract_history.go。PRAGMA journal_modeoff的具体执行位置在QuerySQLite/CountRows中utils/sqliteutil/sqlite.go与文档描述完全一致。9. 文件工具CompressDir 与 --zip 输出RFC-008 的最后一个主题是CompressDirutils/fileutil/fileutil.go把输出目录中的所有文件压缩进一个.zip文件归档后删除原始文件。该工具服务于 CLI 的--zip标志在 cmd/hack-browser-data/dump.go 中通过cmd.Flags().BoolVar(compress, zip, false, compress output to zip)注册。实现细节值得注意使用archive/zip写入内存 buffer再把 zip 写入目录内名为目录名.zip的文件filepath.Base(dir).zip每个文件通过addFileToZip以filepath.Base扁平化命名写入随后os.Remove删除原始文件空目录会直接报错no files to compress in: ...fileutil.go。同文件还提供了面向跨主机传输的ZipDirutils/fileutil/fileutil.go保留相对目录结构、不删除源文件与防 Zip-Slip 的UnzipL138-L167它们是 browser/archive.go 中WriteArchive归档/恢复流程的配套实现——该流程同样先经过Session.Acquire暂存以规避 Windows 的排他锁。10. 小结与相关 RFC 索引RFC-008 描述的文件获取与平台特性是 HackBrowserData 全项目可靠性的地基filemanager.Session用三层生命周期Create/Acquire/Cleanup实现隔离复制Acquire统一处理单文件、目录跳过 LOCK、WAL/SHM 伴随文件Windows 上通过句柄复制 内存映射绕过 Chrome 的排他锁提取阶段则靠QuerySQLite/QueryRows[T]与journal_modeoff的差异化策略保证读到的是一致、干净的快照。想继续深入相关主题可以阅读仓库中同一系列的其他 RFCRFC主题RFC-002: Chromium Data StorageChromium 数据文件位置RFC-004: Firefox Data StorageFirefox 数据文件位置RFC-009: Windows Locked File BypassWindows 锁定文件绕过技术细节核心实现文件索引filemanager/session.go、filemanager/copy.go、filemanager/copy_windows.go、utils/sqliteutil/sqlite.go、utils/sqliteutil/query.go、utils/fileutil/fileutil.go。赞分享网络安全应用安全密码学CLI【免费下载链接】HackBrowserDataExtract and decrypt browser data, supporting multiple data types, runnable on various operating systems (macOS, Windows, Linux).项目地址https://gitcode.com/gh_mirrors/ha/HackBrowserData点击查看免费下载相关推荐解锁Python EXE逆向工程终极工具python-exe-unpacker完全指南解锁Python EXE逆向工程终极工具python exe unpacker完全指南 你是否曾经面对一个神秘的Python可执行文件想要了解其内部工作原理逆向工程网络安全RustDesk 会话与文件传输权限 PoC 深度解析中继降级与会话授权范围绕过RustDesk 会话与文件传输权限 PoC 深度解析中继降级与会话授权范围绕过 导读 本文基于 exploitarium 仓库中的 rustdesk ses网络安全渗透测试示例工程Bokeh 3.8.0 新特性全解析HoverTool 过滤排序、SizeBar 尺寸标注与会话重连机制Bokeh 3.8.0 新特性全解析HoverTool 过滤排序、SizeBar 尺寸标注与会话重连机制 本文以 Bokeh 官方 3.8.0 版本发布说明数据可视化图表库上一篇GroundingDINO深度解析开放集目标检测的架构设计与性能优化指南下一篇Masonry终极指南如何用优雅语法彻底告别AutoLayout的繁琐代码创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考