-
Notifications
You must be signed in to change notification settings - Fork 3
/
get_xbs_bookmarks.py
91 lines (77 loc) · 3.12 KB
/
get_xbs_bookmarks.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/python3
import sys
import argparse
import urllib.request
import json
import base64
import hashlib
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad
from lzutf8 import Decompressor
# Setup arguments
parser = argparse.ArgumentParser(
description='Get bookmarks from an XBrowserSync api')
parser.add_argument('-u', '--url',
default='https://api.xbrowsersync.org',
help='url of the xbrowsersync api service, defaults to https://api.xbrowsersync.org',
)
required = parser.add_argument_group('required arguments')
required.add_argument('-s', '--sync-id',
required=True,
help='sync ID to get bookmarks from',
)
required.add_argument('-p', '--password',
required=True,
help='decryption password',
)
required.add_argument('-o', '--output',
required=True,
help='output file with json',
)
#Get args
args = parser.parse_args()
base_url = args.url.strip().rstrip('/')
password = args.password
sync_id = args.sync_id
#Check sync service url
try:
if urllib.request.urlopen(base_url).getcode() != 200:
raise BadURL("URL cannot be reached or is not working correctly")
except:
print("ERROR: URL cannot be reached or is not working correctly. URl: " + base_url)
sys.exit()
sync_id_url = base_url + "/bookmarks/" + sync_id
#check and download data from sync service
try:
sync_id_url_response = urllib.request.urlopen(sync_id_url)
if sync_id_url_response.getcode() != 200:
raise BadURL("URL cannot be reached or is not working correctly")
sync_data_encrypted_raw = sync_id_url_response.read().decode('utf-8')
sync_id_url_response.close()
except:
print("ERROR: URL cannot be reached or is not working correctly.")
print("Check that your sync ID is correct.")
print("URl: " + base_url)
sys.exit()
#Get encrypted bookmark data from json response from api query
sync_data_encrypted = json.loads(sync_data_encrypted_raw)
all_bookmarks_encrypted = base64.b64decode(sync_data_encrypted["bookmarks"])
#Setup decryption key and parameters
key = hashlib.pbkdf2_hmac('sha256', password.encode(
'utf-8'), sync_id.encode('utf-8'), 250000, 32)
nonce_iv = all_bookmarks_encrypted[:16]
ciphertext = all_bookmarks_encrypted[16:-16]
tag = all_bookmarks_encrypted[-16:]
#Decrypt bookmark data
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce_iv)
all_bookmarks_decrypted = cipher.decrypt_and_verify(ciphertext, tag)
#Decompress bookmark data with lzutf8
decompressor = Decompressor()
all_bookmarks_decompressed = decompressor.decompressBlockToString(
all_bookmarks_decrypted)
#Prettify decrypted bookmark data
all_bookmarks_json = json.loads(all_bookmarks_decompressed)
all_bookmarks_decompressed = json.dumps(all_bookmarks_json, indent=4)
#Write bookmark data to file
with open(args.output, "w") as outputFile:
outputFile.write(all_bookmarks_decompressed)