-
Notifications
You must be signed in to change notification settings - Fork 0
/
luks2_patcher.py
executable file
·74 lines (61 loc) · 2.55 KB
/
luks2_patcher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python
import argparse
import hashlib
import json
LUKS2_BINARY_HEADER_SIZE = 0x1000
LUKS2_CSUM_OFFSET = 0x1c0
LUKS2_CSUM_LENGTH = 32
def patch_client_pin(json_area):
d = json.loads(json_area)
d["tokens"]["0"]["fido2-clientPin-required"] = False
return json.dumps(d).encode()
def dump_json(json_area):
d = json.loads(json_area)
with open("header.json", "w") as json_header:
json.dump(d, json_header)
print("JSON Area saved in header.json.")
def patch_header(filename):
with open("header.json", "r") as json_header:
d = json.load(json_header)
print("JSON Area loaded from header.json.")
json_area = json.dumps(d).encode()
with open(filename, "r+b") as bin:
header = bin.read(LUKS2_CSUM_OFFSET)
header_size = int.from_bytes(header[8:16])
header += b"\x00" * LUKS2_CSUM_LENGTH
bin.seek(LUKS2_CSUM_OFFSET + LUKS2_CSUM_LENGTH)
header += bin.read(LUKS2_BINARY_HEADER_SIZE-LUKS2_CSUM_OFFSET-LUKS2_CSUM_LENGTH)
# Patch JSON area
bin.write(json_area)
header += json_area + b"\x00" * (header_size-LUKS2_BINARY_HEADER_SIZE-len(json_area))
# Compute hash
h = hashlib.sha256()
h.update(header)
new_csum = h.digest()
bin.seek(LUKS2_CSUM_OFFSET)
bin.write(new_csum)
print(f"Patched checksum: {new_csum.hex()}")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='LUKS2 JSON manipulation tool')
parser.add_argument('filename')
parser.add_argument('-d', '--dump', action='store_true', help="dump the JSON area")
parser.add_argument('-p', '--patch', action='store_true', help="patch the JSON area")
args = parser.parse_args()
with open(args.filename, "rb") as bin:
# Reader binary header
binary_header = bin.read(LUKS2_BINARY_HEADER_SIZE)
if binary_header[0:8] != b"LUKS\xba\xbe\x00\x02":
print(f"Not a valid LUKS2 header: {binary_header[0:8]}")
exit()
else:
header_size = int.from_bytes(binary_header[8:16])
print(f"Found LUKS2 header of size {hex(header_size)} bytes.")
# Read current hash value
csum = binary_header[LUKS2_CSUM_OFFSET:LUKS2_CSUM_OFFSET+LUKS2_CSUM_LENGTH]
print(f"Current checksum: {csum.hex()}")
# Read first json area
json_area = bin.read(header_size-LUKS2_BINARY_HEADER_SIZE).split(b"\x00")[0]
if args.dump:
dump_json(json_area)
elif args.patch:
patch_header(args.filename)