dfindexeddb 20240301__py3-none-any.whl → 20240324__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dfindexeddb
3
- Version: 20240301
3
+ Version: 20240324
4
4
  Summary: dfindexeddb is an experimental Python tool for performing digital forensic analysis of IndexedDB and leveldb files.
5
5
  Author-email: Syd Pleno <sydp@google.com>
6
6
  Maintainer-email: dfIndexeddb Developers <dfindexeddb-dev@googlegroups.com>
@@ -226,7 +226,9 @@ dfindexeddb is an experimental Python tool for performing digital forensic
226
226
  analysis of IndexedDB and leveldb files.
227
227
 
228
228
  It parses leveldb, IndexedDB and javascript structures from these files without
229
- requiring native libraries.
229
+ requiring native libraries. (Note: only a subset of IndexedDB key types and
230
+ Javascript types for Chromium-based browsers are currently supported. Safari
231
+ and Firefox are under development).
230
232
 
231
233
  The content of IndexedDB files is dependent on what a web application stores
232
234
  locally/offline using the web browser's
@@ -236,25 +238,34 @@ include:
236
238
  * emails and contact information from an e-mail application,
237
239
  * images and metadata from a photo gallery application
238
240
 
241
+
239
242
  ## Installation
240
243
 
244
+ 1. [Linux] Install the snappy compression development package
245
+
241
246
  ```
242
- $ pip install dfindexeddb
247
+ $ sudo apt install libsnappy-dev
243
248
  ```
244
249
 
245
- ## Installation from source
250
+ 2. Create a virtual environment and install the package
246
251
 
247
- ### Linux
252
+ ```
253
+ $ python3 -m venv .venv
254
+ $ source .venv/bin/activate
255
+ $ pip install dfindexeddb
256
+ ```
248
257
 
249
- 1. Install the snappy compression development package
258
+ ## Installation from source
259
+
260
+ 1. [Linux] Install the snappy compression development package
250
261
 
251
262
  ```
252
263
  $ sudo apt install libsnappy-dev
253
264
  ```
254
265
 
255
- 2. Clone or download the repository to your local machine.
266
+ 2. Clone or download/unzip the repository to your local machine.
256
267
 
257
- 3. Create a virutal environemnt and install the package
268
+ 3. Create a virtual environment and install the package
258
269
 
259
270
  ```
260
271
  $ python3 -m venv .venv
@@ -264,55 +275,58 @@ $ pip install dfindexeddb
264
275
 
265
276
  ## Usage
266
277
 
267
- A CLI tool is available after installation:
278
+ Two CLI tools for parsing IndexedDB/leveldb files are available after
279
+ installation:
280
+
281
+
282
+ ### IndexedDB
268
283
 
269
284
  ```
270
285
  $ dfindexeddb -h
271
- usage: dfindexeddb [-h] -s SOURCE [--json] {log,ldb,indexeddb} ...
272
-
273
- A cli tool for the dfindexeddb package
286
+ usage: dfindexeddb [-h] -s SOURCE [--json]
274
287
 
275
- positional arguments:
276
- {log,ldb,indexeddb}
288
+ A cli tool for parsing indexeddb files
277
289
 
278
290
  options:
291
+ -h, --help show this help message and exit
279
292
  -s SOURCE, --source SOURCE
280
- The source leveldb file
293
+ The source leveldb folder
281
294
  --json Output as JSON
282
295
  ```
283
296
 
284
- To parse a LevelDB .log file:
297
+ ### LevelDB
285
298
 
286
299
  ```
287
- $ dfindexeddb -s <SOURCE> log -h
288
- usage: dfindexeddb log [-h] {blocks,physical_records,write_batches,parsed_internal_key,records}
300
+ $ dfleveldb -h
301
+ usage: dfleveldb [-h] {db,log,ldb,descriptor} ...
302
+
303
+ A cli tool for parsing leveldb files
289
304
 
290
305
  positional arguments:
291
- {blocks,physical_records,write_batches,parsed_internal_key,records}
306
+ {db,log,ldb,descriptor}
307
+ db Parse a directory as leveldb.
308
+ log Parse a leveldb log file.
309
+ ldb Parse a leveldb table (.ldb) file.
310
+ descriptor Parse a leveldb descriptor (MANIFEST) file.
292
311
 
293
312
  options:
294
313
  -h, --help show this help message and exit
295
314
  ```
296
315
 
297
- To parse a LevelDB .ldb file:
316
+ To parse records from a LevelDB log (.log) file, use the following command:
298
317
 
299
318
  ```
300
- $ dfindexeddb -s <SOURCE> ldb -h
301
- usage: dfindexeddb ldb [-h] {blocks,records}
319
+ $ dfleveldb log -s <SOURCE> [--json]
320
+ ```
302
321
 
303
- positional arguments:
304
- {blocks,records}
322
+ To parse records from a LevelDB table (.ldb) file, use the following command:
305
323
 
306
- options:
307
- -h, --help show this help message and exit
324
+ ```
325
+ $ dfleveldb ldb -s <SOURCE> [--json]
308
326
  ```
309
327
 
310
- To parse a LevelDB .ldb or .log file as IndexedDB:
328
+ To parse version edit records from a Descriptor (MANIFEST) file:
311
329
 
312
330
  ```
313
- $ dfindexeddb -s <SOURCE> indexeddb -h
314
- usage: dfindexeddb indexeddb [-h]
315
-
316
- options:
317
- -h, --help show this help message and exit
331
+ $ dfleveldb descriptor -s <SOURCE> [--json]
318
332
  ```
@@ -0,0 +1,26 @@
1
+ dfindexeddb/__init__.py,sha256=KPYL9__l8od6_OyDfGRTgaJ6iy_fqIgZ-dS2S-e3Rac,599
2
+ dfindexeddb/errors.py,sha256=PNpwyf_lrPc4TE77oAakX3mu5D_YcP3f80wq8Y1LkvY,749
3
+ dfindexeddb/utils.py,sha256=pV2blFnMxDwk3kBRK6UVji66ctkYpm6wfH9p0jCC7Nk,8797
4
+ dfindexeddb/version.py,sha256=EVJT5s12vbz8xf-Q1XokuIHYzjSFiD4qJS1qBmpWjdc,750
5
+ dfindexeddb/indexeddb/__init__.py,sha256=kExXSVBCTKCD5BZJkdMfUMqGksH-DMJxP2_lI0gq-BE,575
6
+ dfindexeddb/indexeddb/blink.py,sha256=voC5P33MkyF9gMYJL6XVu2jDk68auTj3qxsCZw_x9rs,3548
7
+ dfindexeddb/indexeddb/chromium.py,sha256=wczfAYSVVWwfzrSf3O_DxZmjVy4b6fzBom6mr9nKZHA,44713
8
+ dfindexeddb/indexeddb/cli.py,sha256=drTSV2Eu-DKQev8xRqgifX68vTAjW0Nt_kUqT79-ZWo,3235
9
+ dfindexeddb/indexeddb/definitions.py,sha256=yline3y3gmZx6s-dwjpPDNs5HO4zT6KZqPWQfEsHDoM,7413
10
+ dfindexeddb/indexeddb/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ dfindexeddb/indexeddb/v8.py,sha256=ldqpc9T1kG7BOdjnHjQ5hNO9OCXZ3_Zd6vRSpC-NrEA,21893
12
+ dfindexeddb/leveldb/__init__.py,sha256=KPYL9__l8od6_OyDfGRTgaJ6iy_fqIgZ-dS2S-e3Rac,599
13
+ dfindexeddb/leveldb/cli.py,sha256=tqu8Vpw45d38zVGLvTNDiNtppHoakj_4IrzURzQsEv8,6702
14
+ dfindexeddb/leveldb/definitions.py,sha256=wwm0uySOeI0-2fG9KvrY-StE0NP3iW5mCEuKYQL4ahg,1436
15
+ dfindexeddb/leveldb/descriptor.py,sha256=cw7A_KDiKf3ZyYThPbvC-LtnPM7Jvn3zr2jPswRBTq4,10426
16
+ dfindexeddb/leveldb/ldb.py,sha256=mN-M7PLtE_VLZCbCbzRgjkSezbMUhgDjgWgPgIxJ1jM,8087
17
+ dfindexeddb/leveldb/log.py,sha256=QeH8oESOPEZUjANGiDRSmXZa2SuoKlPFBJY7SxTV1lg,9209
18
+ dfindexeddb/leveldb/record.py,sha256=AnM4kQb81igmJla5q3rQUYvlzPwZaEHTvauxOC_dtM8,3217
19
+ dfindexeddb/leveldb/utils.py,sha256=RgEEZ7Z35m3CcOUypAiViQSzKjBgSXZ3aeJhQjY3H9w,3748
20
+ dfindexeddb-20240324.dist-info/AUTHORS,sha256=QbvjbAom57fpEkekkCVFUj0B9KUMGraR510aUMBC-PE,286
21
+ dfindexeddb-20240324.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
22
+ dfindexeddb-20240324.dist-info/METADATA,sha256=YT7g3UbA5SXyZZLKSYwwL8Yra8Vi40xh4eJ_G7rD1M4,16473
23
+ dfindexeddb-20240324.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
24
+ dfindexeddb-20240324.dist-info/entry_points.txt,sha256=WG9YNLZ9lBx4Q9QF6wS4dZdZfADT3Zs4_-MV5TcA0ls,102
25
+ dfindexeddb-20240324.dist-info/top_level.txt,sha256=X9OTaub1c8S_JJ7g-f8JdkhhdiZ4x1j4eni1hdUCwE4,12
26
+ dfindexeddb-20240324.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ dfindexeddb = dfindexeddb.indexeddb.cli:App
3
+ dfleveldb = dfindexeddb.leveldb.cli:App
dfindexeddb/cli.py DELETED
@@ -1,155 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright 2024 Google LLC
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # https://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- """A CLI tool for dfindexeddb."""
16
- import argparse
17
- import dataclasses
18
- from datetime import datetime
19
- import json
20
- import pathlib
21
- import sys
22
- import traceback
23
-
24
- from dfindexeddb.leveldb import log
25
- from dfindexeddb.leveldb import ldb
26
- from dfindexeddb.indexeddb import chromium
27
- from dfindexeddb import errors
28
- from dfindexeddb.indexeddb import v8
29
-
30
-
31
- class Encoder(json.JSONEncoder):
32
- """A JSON encoder class for dfindexeddb fields."""
33
- def default(self, o):
34
- if isinstance(o, bytes):
35
- return o.decode(encoding='ascii', errors='backslashreplace')
36
- if isinstance(o, datetime):
37
- return o.isoformat()
38
- if isinstance(o, v8.Undefined):
39
- return "<undefined>"
40
- if isinstance(o, v8.Null):
41
- return "<null>"
42
- if isinstance(o, set):
43
- return list(o)
44
- if isinstance(o, v8.RegExp):
45
- return str(o)
46
- return json.JSONEncoder.default(self, o)
47
-
48
-
49
- def _Output(structure, to_json=False):
50
- """Helper method to output parsed structure to stdout."""
51
- if to_json:
52
- structure_dict = dataclasses.asdict(structure)
53
- print(json.dumps(structure_dict, indent=2, cls=Encoder))
54
- else:
55
- print(structure)
56
-
57
-
58
- def IndexeddbCommand(args):
59
- """The CLI for processing a log/ldb file as indexeddb."""
60
- if args.source.name.endswith('.log'):
61
- records = list(
62
- log.LogFileReader(args.source).GetKeyValueRecords())
63
- elif args.source.name.endswith('.ldb'):
64
- records = list(
65
- ldb.LdbFileReader(args.source).GetKeyValueRecords())
66
- else:
67
- print('Unsupported file type.', file=sys.stderr)
68
- return
69
-
70
- for record in records:
71
- try:
72
- record = chromium.IndexedDBRecord.FromLevelDBRecord(record)
73
- except (errors.ParserError, errors.DecoderError) as err:
74
- print(
75
- (f'Error parsing blink value: {err} for {record.__class__.__name__} '
76
- f'at offset {record.offset}'), file=sys.stderr)
77
- print(f'Traceback: {traceback.format_exc()}', file=sys.stderr)
78
- _Output(record, to_json=args.json)
79
-
80
-
81
- def LdbCommand(args):
82
- """The CLI for processing ldb files."""
83
- ldb_file = ldb.LdbFileReader(args.source)
84
-
85
- if args.structure_type == 'blocks':
86
- # Prints block information.
87
- for block in ldb_file.GetBlocks():
88
- _Output(block, to_json=args.json)
89
-
90
- elif args.structure_type == 'records':
91
- # Prints key value record information.
92
- for record in ldb_file.GetKeyValueRecords():
93
- _Output(record, to_json=args.json)
94
-
95
-
96
- def LogCommand(args):
97
- """The CLI for processing log files."""
98
- log_file = log.LogFileReader(args.source)
99
-
100
- if args.structure_type == 'blocks':
101
- # Prints block information.
102
- for block in log_file.GetBlocks():
103
- _Output(block, to_json=args.json)
104
-
105
- elif args.structure_type == 'physical_records':
106
- # Prints log file physical record information.
107
- for log_file_record in log_file.GetPhysicalRecords():
108
- _Output(log_file_record, to_json=args.json)
109
-
110
- elif args.structure_type == 'write_batches':
111
- # Prints log file batch information.
112
- for batch in log_file.GetWriteBatches():
113
- _Output(batch, to_json=args.json)
114
-
115
- elif args.structure_type in ('parsed_internal_key', 'records'):
116
- # Prints key value record information.
117
- for record in log_file.GetKeyValueRecords():
118
- _Output(record, to_json=args.json)
119
-
120
-
121
- def App():
122
- """The CLI app entrypoint."""
123
- parser = argparse.ArgumentParser(
124
- prog='dfindexeddb',
125
- description='A cli tool for the dfindexeddb package')
126
-
127
- parser.add_argument(
128
- '-s', '--source', required=True, type=pathlib.Path,
129
- help='The source leveldb file')
130
- parser.add_argument('--json', action='store_true', help='Output as JSON')
131
- subparsers = parser.add_subparsers(required=True)
132
-
133
- parser_log = subparsers.add_parser('log')
134
- parser_log.add_argument(
135
- 'structure_type', choices=[
136
- 'blocks',
137
- 'physical_records',
138
- 'write_batches',
139
- 'parsed_internal_key',
140
- 'records'])
141
- parser_log.set_defaults(func=LogCommand)
142
-
143
- parser_log = subparsers.add_parser('ldb')
144
- parser_log.add_argument(
145
- 'structure_type', choices=[
146
- 'blocks',
147
- 'records'])
148
- parser_log.set_defaults(func=LdbCommand)
149
-
150
- parser_log = subparsers.add_parser('indexeddb')
151
- parser_log.set_defaults(func=IndexeddbCommand)
152
-
153
- args = parser.parse_args()
154
-
155
- args.func(args)
@@ -1,20 +0,0 @@
1
- dfindexeddb/__init__.py,sha256=KPYL9__l8od6_OyDfGRTgaJ6iy_fqIgZ-dS2S-e3Rac,599
2
- dfindexeddb/cli.py,sha256=QsFPC_B_PW6E42kBPUO0Ny3oRspYJsXlDCQDHmKuDHQ,4866
3
- dfindexeddb/errors.py,sha256=PNpwyf_lrPc4TE77oAakX3mu5D_YcP3f80wq8Y1LkvY,749
4
- dfindexeddb/utils.py,sha256=g9iiGRX4DB1wFBSBHa6b9lg7JzAdE0SN0DrdB2aS_Co,10091
5
- dfindexeddb/version.py,sha256=d2fDd3V2U_CkGi3PawWMR77qU0DzHEC3_bk7Ywh3xlM,750
6
- dfindexeddb/indexeddb/__init__.py,sha256=kExXSVBCTKCD5BZJkdMfUMqGksH-DMJxP2_lI0gq-BE,575
7
- dfindexeddb/indexeddb/blink.py,sha256=MblpYfv-ByG7n_fjYKu2EUhpfVJdUveoW4oSAg5T4tY,3534
8
- dfindexeddb/indexeddb/chromium.py,sha256=oHHyGuy7BanRWRoJu4zqXo5QvxO2j_qLk2KMHBBwZvs,44692
9
- dfindexeddb/indexeddb/definitions.py,sha256=yline3y3gmZx6s-dwjpPDNs5HO4zT6KZqPWQfEsHDoM,7413
10
- dfindexeddb/indexeddb/v8.py,sha256=ldqpc9T1kG7BOdjnHjQ5hNO9OCXZ3_Zd6vRSpC-NrEA,21893
11
- dfindexeddb/leveldb/__init__.py,sha256=KPYL9__l8od6_OyDfGRTgaJ6iy_fqIgZ-dS2S-e3Rac,599
12
- dfindexeddb/leveldb/ldb.py,sha256=uShhXjQe4Sz3dn54IXbGxRtE6D8RNpu1NDy5Zb0P9LA,7927
13
- dfindexeddb/leveldb/log.py,sha256=cyMfjDz5a6gfGb5NonxC1Y72OmHYBWzYK8UMVzP_umw,8532
14
- dfindexeddb-20240301.dist-info/AUTHORS,sha256=QbvjbAom57fpEkekkCVFUj0B9KUMGraR510aUMBC-PE,286
15
- dfindexeddb-20240301.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
16
- dfindexeddb-20240301.dist-info/METADATA,sha256=AYggbgjQv3dNPwO-f3e7tK3EPvKsnlNTKM2nPTbAQYg,15933
17
- dfindexeddb-20240301.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
18
- dfindexeddb-20240301.dist-info/entry_points.txt,sha256=UsfPLLhTiVAAtZ8Rq3ZR7JNFGMuHqJy-tugGWonQWtc,52
19
- dfindexeddb-20240301.dist-info/top_level.txt,sha256=X9OTaub1c8S_JJ7g-f8JdkhhdiZ4x1j4eni1hdUCwE4,12
20
- dfindexeddb-20240301.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- dfindexeddb = dfindexeddb.cli:App