connected-phone-forensics 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- connected_phone_forensics-0.1.2/LICENSE +21 -0
- connected_phone_forensics-0.1.2/PKG-INFO +350 -0
- connected_phone_forensics-0.1.2/README.md +307 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/__init__.py +3 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/_synth/__init__.py +5 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/_synth/certs.py +41 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/_synth/phonelink.py +316 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/_synth/regf.py +201 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/cli.py +153 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/correlate.py +450 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/demo.py +291 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/engine.py +209 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/evidence.py +428 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/__init__.py +7 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/__main__.py +3 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/app.py +98 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/casedata.py +207 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/icons.py +85 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/jobs.py +142 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/models.py +187 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/__init__.py +0 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/coverage.py +98 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/devices.py +320 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/home.py +394 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/issues.py +85 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/overview.py +187 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/scan.py +248 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/pages/timeline.py +289 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/theme.py +317 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/widgets.py +941 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/gui/window.py +319 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/model.py +207 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/output/__init__.py +18 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/output/html.py +312 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/output/structured.py +152 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugin.py +282 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/__init__.py +1 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/_windows.py +95 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/apple_backups.py +197 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/apple_pairing.py +133 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/kdeconnect.py +245 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/linux_bluetooth.py +116 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_biome_sync.py +157 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_calls_airdrop.py +112 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_hotspot.py +135 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_iphone_mirroring.py +91 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_knowledgec.py +78 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_messages.py +123 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/mac_notifications.py +92 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_bluetooth.py +189 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_crossdevice.py +97 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_hotspot.py +234 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_phonelink.py +745 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_setupapi.py +123 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_usb.py +300 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/plugins/win_wpn.py +110 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/__init__.py +1 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/plist.py +107 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/regf_log.py +349 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/registry.py +160 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/sqlite.py +138 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/sqlite_wal.py +500 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/readers/x509.py +121 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/targets.py +138 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/timeutil.py +182 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/validate.py +149 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics/wintz.py +95 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics.egg-info/PKG-INFO +350 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics.egg-info/SOURCES.txt +91 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics.egg-info/dependency_links.txt +1 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics.egg-info/entry_points.txt +6 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics.egg-info/requires.txt +13 -0
- connected_phone_forensics-0.1.2/connected_phone_forensics.egg-info/top_level.txt +1 -0
- connected_phone_forensics-0.1.2/pyproject.toml +75 -0
- connected_phone_forensics-0.1.2/setup.cfg +4 -0
- connected_phone_forensics-0.1.2/tests/test_apple.py +120 -0
- connected_phone_forensics-0.1.2/tests/test_core.py +337 -0
- connected_phone_forensics-0.1.2/tests/test_gui.py +148 -0
- connected_phone_forensics-0.1.2/tests/test_kdeconnect.py +115 -0
- connected_phone_forensics-0.1.2/tests/test_linux_bluetooth.py +50 -0
- connected_phone_forensics-0.1.2/tests/test_macos.py +149 -0
- connected_phone_forensics-0.1.2/tests/test_macos_more.py +114 -0
- connected_phone_forensics-0.1.2/tests/test_phonelink.py +240 -0
- connected_phone_forensics-0.1.2/tests/test_registry_logs.py +181 -0
- connected_phone_forensics-0.1.2/tests/test_sqlite_wal.py +341 -0
- connected_phone_forensics-0.1.2/tests/test_validate.py +32 -0
- connected_phone_forensics-0.1.2/tests/test_windows_bluetooth.py +74 -0
- connected_phone_forensics-0.1.2/tests/test_windows_crossdevice.py +31 -0
- connected_phone_forensics-0.1.2/tests/test_windows_hotspot.py +83 -0
- connected_phone_forensics-0.1.2/tests/test_windows_setupapi.py +44 -0
- connected_phone_forensics-0.1.2/tests/test_windows_usb.py +130 -0
- connected_phone_forensics-0.1.2/tests/test_wintz.py +40 -0
- connected_phone_forensics-0.1.2/tests/test_wpn.py +84 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Connected Phone Forensics contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: connected-phone-forensics
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Recover smartphone evidence from the computers a phone was connected to.
|
|
5
|
+
Author: Connected Phone Forensics contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sujayadkesar/connected-phone-forensics
|
|
8
|
+
Project-URL: Documentation, https://github.com/sujayadkesar/connected-phone-forensics#readme
|
|
9
|
+
Project-URL: Releases, https://github.com/sujayadkesar/connected-phone-forensics/releases
|
|
10
|
+
Project-URL: Issues, https://github.com/sujayadkesar/connected-phone-forensics/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/sujayadkesar/connected-phone-forensics/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: dfir,digital-forensics,mobile-forensics,incident-response,iphone,android,phone-link,usb,bluetooth,kape,velociraptor,timesketch
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Information Technology
|
|
15
|
+
Classifier: Intended Audience :: Legal Industry
|
|
16
|
+
Classifier: Environment :: Console
|
|
17
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
18
|
+
Classifier: Environment :: X11 Applications :: Qt
|
|
19
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
20
|
+
Classifier: Operating System :: MacOS
|
|
21
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
28
|
+
Classifier: Topic :: Security
|
|
29
|
+
Classifier: Topic :: System :: Recovery Tools
|
|
30
|
+
Requires-Python: >=3.10
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: regipy>=4.0
|
|
34
|
+
Requires-Dist: PySide6-Essentials>=6.6
|
|
35
|
+
Requires-Dist: qtawesome>=1.3
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
39
|
+
Requires-Dist: tzdata; sys_platform == "win32" and extra == "dev"
|
|
40
|
+
Provides-Extra: build
|
|
41
|
+
Requires-Dist: pyinstaller>=6.6; extra == "build"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
<div align="center">
|
|
45
|
+
|
|
46
|
+
<img src="docs/images/logo.png" width="104" alt="Connected Phone Forensics logo">
|
|
47
|
+
|
|
48
|
+
# Connected Phone Forensics
|
|
49
|
+
|
|
50
|
+
**Find every phone that was connected to a computer, and show exactly where each fact came from.**
|
|
51
|
+
|
|
52
|
+
USB · Bluetooth · Wi-Fi hotspots · Phone Link · iPhone pairing and backups · Messages · AirDrop · KDE Connect<br>
|
|
53
|
+
from Windows, macOS and Linux disk images and triage collections.
|
|
54
|
+
|
|
55
|
+
[](https://github.com/sujayadkesar/connected-phone-forensics/releases)
|
|
56
|
+
[](https://github.com/sujayadkesar/connected-phone-forensics/actions/workflows/ci.yml)
|
|
57
|
+
[](https://pypi.org/project/connected-phone-forensics/)
|
|
58
|
+
[](#install-with-pip-windows-macos-linux)
|
|
59
|
+
[](#quick-start)
|
|
60
|
+
[](LICENSE)
|
|
61
|
+
|
|
62
|
+
[](https://github.com/sujayadkesar/connected-phone-forensics/releases/latest)
|
|
63
|
+
|
|
64
|
+
[](#quick-start)
|
|
65
|
+
|
|
66
|
+
[](docs/ARCHITECTURE.md)
|
|
67
|
+
|
|
68
|
+
<br>
|
|
69
|
+
|
|
70
|
+
<img src="docs/images/screenshots/overview.png" alt="Connected Phone Forensics: case overview with phones, computers and records by connection type" width="100%">
|
|
71
|
+
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
## Why
|
|
75
|
+
|
|
76
|
+
Seized phones are increasingly unreadable: since iOS 18.1 a locked iPhone reboots into
|
|
77
|
+
Before-First-Unlock after 72 hours without use, and full-file-system extractions depend on
|
|
78
|
+
exploits that come and go. The suspect's computer is usually easier to examine, and phones leave a
|
|
79
|
+
trail on every computer they touch: pairing records, backups, USB and Bluetooth history, hotspot
|
|
80
|
+
connections, companion apps, synced messages and calls.
|
|
81
|
+
|
|
82
|
+
Connected Phone Forensics finds that trail and answers three questions:
|
|
83
|
+
|
|
84
|
+
- **Which phones touched this computer?** Each phone is identified by its UDID, serial, IMEI,
|
|
85
|
+
Bluetooth or Wi-Fi MAC, or USB serial, and every identifier is traced to the record that holds it.
|
|
86
|
+
- **When, and over which connection?** USB, Bluetooth, hotspot, pairing, backup, Phone Link,
|
|
87
|
+
Continuity, companion apps, with first and last seen for each.
|
|
88
|
+
- **What phone data is on the computer?** Messages, calls, contacts and notifications, each tagged
|
|
89
|
+
with the phone it came from.
|
|
90
|
+
|
|
91
|
+
## Highlights
|
|
92
|
+
|
|
93
|
+
- **23 parsers** for Windows, macOS and Linux, run in parallel. Point it at a mounted image or a
|
|
94
|
+
KAPE, Velociraptor or UAC collection and every computer inside is found automatically.
|
|
95
|
+
- **One device per phone, defensibly.** Records merge only through strong identifiers named
|
|
96
|
+
together in one record, and each merge shows the record that caused it. Shared names, numbers
|
|
97
|
+
and neighbouring MAC addresses are shown as *possible* matches and never merged silently.
|
|
98
|
+
- **Provenance for every fact:** source file, SHA-256 and a locator precise enough to find the
|
|
99
|
+
record by hand (`SYSTEM:\ControlSet001\Enum\USB\...\0066`, `table=message rowid=42`).
|
|
100
|
+
- **Read-only and verifiable.** Databases and hives are read from copies, every evidence file
|
|
101
|
+
read is hashed into a manifest, and nothing is skipped silently: unknown formats are reported.
|
|
102
|
+
- **Desktop app and command line.** A fast native app for examination, and a CLI for scripting
|
|
103
|
+
and pipelines. Both write the same report, Timesketch timeline and JSON.
|
|
104
|
+
|
|
105
|
+
## Screenshots
|
|
106
|
+
|
|
107
|
+
<table>
|
|
108
|
+
<tr>
|
|
109
|
+
<td width="50%"><img src="docs/images/screenshots/new-scan.png" alt="New scan: evidence drop zone with the computers found, case details and parsers"></td>
|
|
110
|
+
<td width="50%"><img src="docs/images/screenshots/scan-progress.png" alt="Scan progress with steps, live counts and the activity log"></td>
|
|
111
|
+
</tr>
|
|
112
|
+
<tr>
|
|
113
|
+
<td align="center"><b>New scan</b>: drop the evidence; the computers inside are listed before you start</td>
|
|
114
|
+
<td align="center"><b>Live progress</b>: parsers run in parallel and can be cancelled</td>
|
|
115
|
+
</tr>
|
|
116
|
+
<tr>
|
|
117
|
+
<td><img src="docs/images/screenshots/devices.png" alt="Device detail: identifiers, connections and why records were linked"></td>
|
|
118
|
+
<td><img src="docs/images/screenshots/timeline.png" alt="Timeline with filters and the provenance of the selected record"></td>
|
|
119
|
+
</tr>
|
|
120
|
+
<tr>
|
|
121
|
+
<td align="center"><b>Devices</b>: identifiers, connections, why records were linked</td>
|
|
122
|
+
<td align="center"><b>Timeline</b>: every record with its file, locator and SHA-256</td>
|
|
123
|
+
</tr>
|
|
124
|
+
<tr>
|
|
125
|
+
<td><img src="docs/images/screenshots/coverage.png" alt="Coverage: every evidence file read and its parse status"></td>
|
|
126
|
+
<td><img src="docs/images/screenshots/devices-light.png" alt="The Devices page in the light theme"></td>
|
|
127
|
+
</tr>
|
|
128
|
+
<tr>
|
|
129
|
+
<td align="center"><b>Coverage</b>: every file a parser read, and what came of it</td>
|
|
130
|
+
<td align="center"><b>Light theme</b></td>
|
|
131
|
+
</tr>
|
|
132
|
+
</table>
|
|
133
|
+
|
|
134
|
+
<sub>Screenshots show the built-in demo case: entirely synthetic data.</sub>
|
|
135
|
+
|
|
136
|
+
## Quick start
|
|
137
|
+
|
|
138
|
+
### Windows: download and run
|
|
139
|
+
|
|
140
|
+
1. Download **`ConnectedPhoneForensics-<version>-windows-x64.exe`** from the
|
|
141
|
+
[latest release](https://github.com/sujayadkesar/connected-phone-forensics/releases/latest).
|
|
142
|
+
Nothing to install.
|
|
143
|
+
2. Run it. The executable is not code-signed yet, so SmartScreen may say *Windows protected your
|
|
144
|
+
PC*: choose **More info → Run anyway**. Check the download against `SHA256SUMS.txt` first:
|
|
145
|
+
```powershell
|
|
146
|
+
certutil -hashfile ConnectedPhoneForensics-0.1.0-windows-x64.exe SHA256
|
|
147
|
+
```
|
|
148
|
+
3. Click **Run the demo case** to see it work on synthetic data, or drop your evidence folder on
|
|
149
|
+
**New scan**.
|
|
150
|
+
|
|
151
|
+
The same release has **`cpf-<version>-windows-x64.exe`**, the command-line tool.
|
|
152
|
+
|
|
153
|
+
### Install with pip (Windows, macOS, Linux)
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pip install connected-phone-forensics
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Then run `cpf-gui` for the desktop app or `cpf --help` for the command line. Needs Python 3.10 or
|
|
160
|
+
newer.
|
|
161
|
+
|
|
162
|
+
### Try it without evidence
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
cpf demo ./demo
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
builds a synthetic case (a Windows laptop, a MacBook and a Linux desktop that one iPhone and one
|
|
169
|
+
Pixel touched), scans it and writes the report to `./demo/report`. Every byte is generated.
|
|
170
|
+
|
|
171
|
+
## Usage
|
|
172
|
+
|
|
173
|
+
### Desktop app
|
|
174
|
+
|
|
175
|
+
| Page | What it shows |
|
|
176
|
+
|---|---|
|
|
177
|
+
| **New scan** | Evidence picker (drop a folder), the computers found in it, case reference, examiner, output folder, parser selection |
|
|
178
|
+
| **Overview** | Phones, computers, records by connection type, and records that may be the same phone |
|
|
179
|
+
| **Devices** | Every device: identifiers and their strength, connections with first and last seen, why its records were linked, possible matches |
|
|
180
|
+
| **Timeline** | All records, searchable and filterable by device, connection, computer and parser; provenance of the selected record; CSV export of what is shown |
|
|
181
|
+
| **Coverage** | Every evidence file read, with status `parsed`, `empty`, `unrecognised` or `error` |
|
|
182
|
+
| **Issues** | Parser warnings and errors, with the full message |
|
|
183
|
+
|
|
184
|
+
**Open results folder** reopens any earlier scan. Keyboard: <kbd>Ctrl</kbd>+<kbd>N</kbd> new scan,
|
|
185
|
+
<kbd>Ctrl</kbd>+<kbd>O</kbd> open results, <kbd>Ctrl</kbd>+<kbd>F</kbd> search,
|
|
186
|
+
<kbd>Ctrl</kbd>+<kbd>1</kbd>…<kbd>6</kbd> switch pages.
|
|
187
|
+
|
|
188
|
+
### Command line
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
cpf scan /mnt/evidence -o case42 --case 42 --examiner "A. Examiner"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
| Command | Purpose |
|
|
195
|
+
|---|---|
|
|
196
|
+
| `cpf scan INPUT -o OUT` | Scan a mounted image, extracted drive or triage collection. Options: `--case`, `--examiner`, `--plugins`, `--workers N`, `--workdir`, `--no-export`, `--no-html`, `--assume-same` |
|
|
197
|
+
| `cpf demo OUT` | Build and scan the synthetic demo case |
|
|
198
|
+
| `cpf plugins` | List the parsers and how far each has been validated |
|
|
199
|
+
| `cpf targets --format kape\|velociraptor\|list` | Collection targets for exactly the files the parsers read |
|
|
200
|
+
| `cpf validate truth.json OUT` | Score a scan against a ground-truth file |
|
|
201
|
+
| `cpf docs -o artifacts.md` | Artifact reference generated from the parsers |
|
|
202
|
+
|
|
203
|
+
## What it finds
|
|
204
|
+
|
|
205
|
+
| Parser | Computer | Evidence of | Validation |
|
|
206
|
+
|---|---|---|---|
|
|
207
|
+
| `win_usb_phones` | Windows | Phones over USB (MTP/PTP/ADB/RNDIS, iPhone), install/arrival/removal times, serial/UDID, model | public sample |
|
|
208
|
+
| `win_setupapi_phones` | Windows | First driver install per phone, later driver installs (setupapi.dev.log) | synthetic |
|
|
209
|
+
| `win_bluetooth` | Windows | Bluetooth pairings (BTHPORT): name, class of device, last seen/connected, link keys; phone services offered to the PC (Hands-Free, MAP, PBAP, Apple Notification Center) | synthetic |
|
|
210
|
+
| `win_phone_hotspots` | Windows | Phone hotspots joined (NetworkList + DHCP; iPhone 172.20.10.0/28) | public sample |
|
|
211
|
+
| `win_phonelink` | Windows | Microsoft Phone Link caches: SMS/MMS/RCS messages and RCS file transfers, calls, contacts, notifications, photos, wallpaper, app list, the phone's own number; the phone's name, model and OS from DeviceMetadataStorage.json; deleted and edited rows recovered from the WAL | synthetic |
|
|
212
|
+
| `win_wpn_phonelink` | Windows | Phone Link toasts in the Windows notification database, including recovered expired toasts | public sample |
|
|
213
|
+
| `win_crossdevice` | Windows | Phones known to the Microsoft account (TaskFlow DeviceCache), cross-device settings | synthetic |
|
|
214
|
+
| `win_apple_pairing` / `mac_apple_pairing` | Windows / macOS | iPhone trust (lockdown) records: UDID, Wi-Fi MAC, escrow keybag, pairing time | synthetic |
|
|
215
|
+
| `win_apple_backups` / `mac_apple_backups` | Windows / macOS | iPhone backups: identity, phone number, IMEI, apps, dates, encryption | synthetic |
|
|
216
|
+
| `mac_biome_sync` | macOS | iPhones syncing with the Mac through Biome: OS build, last sync, data streams received | synthetic |
|
|
217
|
+
| `mac_messages` | macOS | SMS relayed from the iPhone (Text Message Forwarding) and iMessage; the iPhone's number | synthetic |
|
|
218
|
+
| `mac_callhistory` | macOS | Calls synced from the iPhone, with the originating device name | synthetic |
|
|
219
|
+
| `mac_airdrop` | macOS | Files received by AirDrop, with the sender's name | synthetic |
|
|
220
|
+
| `mac_phone_hotspots` | macOS | Phone hotspots joined (known networks, Personal Hotspot flag, DHCP leases) | synthetic |
|
|
221
|
+
| `mac_notifications` | macOS | Notifications forwarded from the iPhone (inferred: the app is not installed on the Mac) | synthetic |
|
|
222
|
+
| `mac_knowledgec_peers` | macOS | knowledgeC sync peers (older macOS) | synthetic |
|
|
223
|
+
| `mac_iphone_mirroring` | macOS | iPhone Mirroring pairing, the iPhone's app inventory | synthetic |
|
|
224
|
+
| `linux_bluetooth` | Linux | BlueZ pairings and discovered devices | synthetic |
|
|
225
|
+
| `*_kdeconnect` | Linux / Windows / macOS | KDE Connect paired phones; when the app on the phone created its identity, and whether that was the Android or the iOS app | synthetic |
|
|
226
|
+
|
|
227
|
+
**Validation levels are printed in every report.** `synthetic`: tested against fixtures built from
|
|
228
|
+
public documentation. `public_sample`: also tested against real public data (the DFIR Artifact
|
|
229
|
+
Museum). `ground_truth`: tested against data created on real devices with recorded actions. See
|
|
230
|
+
[docs/VALIDATION.md](docs/VALIDATION.md); ground-truth datasets are the most valuable contribution
|
|
231
|
+
the project can receive.
|
|
232
|
+
|
|
233
|
+
## How it works
|
|
234
|
+
|
|
235
|
+
```mermaid
|
|
236
|
+
flowchart LR
|
|
237
|
+
A[Evidence folder<br>image or collection] --> B[Find each<br>Windows / macOS / Linux root]
|
|
238
|
+
B --> C[23 parsers<br>in parallel]
|
|
239
|
+
C --> D[Records with provenance<br>file, locator, SHA-256]
|
|
240
|
+
D --> E[Correlate<br>strong identifiers only]
|
|
241
|
+
E --> F[Device graph<br>+ possible matches]
|
|
242
|
+
F --> G[Report, timeline,<br>JSON, manifest]
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
More in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
246
|
+
|
|
247
|
+
## How evidence is treated
|
|
248
|
+
|
|
249
|
+
- **Read-only.** SQLite databases are copied together with their `-wal` and `-shm` files and the
|
|
250
|
+
copy is opened, so the original is never modified and committed WAL records are not lost. Dirty
|
|
251
|
+
registry hives are recovered from their transaction logs on a copy, following the REGF
|
|
252
|
+
specification: only entries that continue the hive's sequence and pass their hash checks are
|
|
253
|
+
applied, and logs next to a clean hive are left alone.
|
|
254
|
+
- **Hashed.** Every evidence file read is SHA-256 hashed; hashes, tool version and command line go
|
|
255
|
+
into `manifest.json`.
|
|
256
|
+
- **Nothing skipped silently.** Every file a parser opened is in the coverage table. A file whose
|
|
257
|
+
format is not recognised is reported as `unrecognised`, not dropped, and a folder that cannot be
|
|
258
|
+
read (for example the locked registry folder on a live system) is reported as an error.
|
|
259
|
+
- **Honest time.** All times are UTC. Local-time artifacts are converted with the time zone recorded
|
|
260
|
+
in the same image. Filesystem times are labelled as such and do not set a phone's first or last
|
|
261
|
+
seen.
|
|
262
|
+
- **Long paths.** On Windows, evidence deeper than 260 characters (common for Phone Link) is read
|
|
263
|
+
with extended-length paths, so it is never mistaken for missing.
|
|
264
|
+
|
|
265
|
+
## Outputs
|
|
266
|
+
|
|
267
|
+
| File | Contents |
|
|
268
|
+
|---|---|
|
|
269
|
+
| `report.html` | Self-contained report (works offline): phones, identifiers, connections, timeline, coverage |
|
|
270
|
+
| `timeline.jsonl` / `timeline.csv` | Timestamped records; imports directly into Timesketch |
|
|
271
|
+
| `observations.jsonl` | Every record, timed or not |
|
|
272
|
+
| `devices.json` | The device graph, with merge reasons and possible matches |
|
|
273
|
+
| `coverage.csv` | Every evidence file read and its parse status |
|
|
274
|
+
| `manifest.json` | Run metadata, evidence hashes, warnings |
|
|
275
|
+
|
|
276
|
+
## Possible matches and examiner conclusions
|
|
277
|
+
|
|
278
|
+
Weak clues (the same device name, a phone number, MAC addresses that differ by one, a hotspot
|
|
279
|
+
BSSID derived from the phone's address) never merge records automatically. They are listed per pair
|
|
280
|
+
of devices with the number of independent signals. When an examiner has verified that two
|
|
281
|
+
identifiers belong to one phone, the conclusion can be recorded, and it is labelled as an examiner
|
|
282
|
+
assertion in the report and manifest:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
cpf scan /mnt/evidence -o out --assume-same udid=00008120001A2B3C4D5E801E,bt_mac=a4:c3:37:5e:10:2b
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Collecting only what it needs
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
cpf targets --format kape > CPF.tkape
|
|
292
|
+
cpf targets --format velociraptor > CPF.yaml
|
|
293
|
+
cpf targets --format list
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The targets are generated from the parsers' own path declarations, so a collection always matches
|
|
297
|
+
what the installed version can parse.
|
|
298
|
+
|
|
299
|
+
## Project status
|
|
300
|
+
|
|
301
|
+
**Early release (0.1).** The tool runs end to end on Windows, macOS and Linux, and every parser has
|
|
302
|
+
automated tests, but only three parsers have been checked against real public data and none yet
|
|
303
|
+
against ground-truth data from real phones. A code review in October 2026 found issues that are not
|
|
304
|
+
all fixed yet. Its one critical finding, recovery of *deleted* SQLite rows (Phone Link, Windows
|
|
305
|
+
notifications) reporting rows from another table as recovered messages or notifications, was fixed
|
|
306
|
+
in 0.1.2: a row is now attributed to a table only when its page belonged to that table in the
|
|
307
|
+
database state it was read from. The open issues are listed in the
|
|
308
|
+
[changelog](CHANGELOG.md#known-issues).
|
|
309
|
+
|
|
310
|
+
Treat results as leads and verify them against the source records the report points to, which is
|
|
311
|
+
good practice with any forensic tool.
|
|
312
|
+
|
|
313
|
+
### Roadmap
|
|
314
|
+
|
|
315
|
+
- Fix the open review findings
|
|
316
|
+
- Ground-truth validation with real iPhone and Android devices
|
|
317
|
+
- Code-signed Windows builds
|
|
318
|
+
- Recording examiner conclusions (same phone / not the same phone) from the desktop app
|
|
319
|
+
|
|
320
|
+
## Building from source
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
git clone https://github.com/sujayadkesar/connected-phone-forensics
|
|
324
|
+
cd connected-phone-forensics
|
|
325
|
+
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
326
|
+
pip install -e ".[dev]"
|
|
327
|
+
python -m pytest # GUI tests run headless
|
|
328
|
+
python -m ruff check connected_phone_forensics tests
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Windows executables: `pip install -e ".[build]"`, then `python packaging/build.py` and
|
|
332
|
+
`python packaging/smoke_test.py dist`. Releases are built the same way by
|
|
333
|
+
[GitHub Actions](.github/workflows/release.yml) when a version tag is pushed.
|
|
334
|
+
|
|
335
|
+
## Contributing
|
|
336
|
+
|
|
337
|
+
Parsers are small, self-registering modules. [CONTRIBUTING.md](CONTRIBUTING.md) describes the
|
|
338
|
+
plugin API and the evidence-handling rules every parser follows. Bug reports, artifact requests and
|
|
339
|
+
ground-truth datasets are welcome in the [issue tracker](https://github.com/sujayadkesar/connected-phone-forensics/issues).
|
|
340
|
+
Please report security problems privately, as described in [SECURITY.md](SECURITY.md).
|
|
341
|
+
|
|
342
|
+
## Citing
|
|
343
|
+
|
|
344
|
+
If you use Connected Phone Forensics in research or casework documentation, please cite it; GitHub
|
|
345
|
+
shows a citation from [CITATION.cff](CITATION.cff) under *Cite this repository*.
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
[MIT](LICENSE). Provided as is, without warranty: validate results before relying on them in
|
|
350
|
+
legal proceedings.
|