· 6 years ago · Nov 01, 2019, 03:28 PM
1import requests
2import json
3import copy
4import random
5import bs4
6import re
7import des
8import base64
9import time
10import random
11import datetime
12from Crypto.Cipher import AES
13from hashlib import pbkdf2_hmac
14from os import urandom
15from padding import pad
16from connection_handler import base_headers, cookies_coffee, post_data_coffee
17
18
19HEX_LIST = list(range(97, 103)) + list(range(48, 58))
20
21DES_KEY = "co.vmob.sdk.android.encrypt.key";
22MASTER_KEY = "d4eee068-272a-4aec-9681-5e16dcef6fbd";
23
24
25#Get the account token ID named: bearer <ACCOUNT KEY>
26def get_registration_token(content, headers = base_headers):
27
28 # Used to create an account every time
29 url = "https://con-West-Europe-GMA.vmobapps.com/v3/emailRegistrations"
30
31 #Check if content are ok
32 if not content:
33 return None
34
35 #Create a new device id to bypass the checking of devide
36 fake_device_id = make_fake_device_uid().decode('ascii')[:-1].replace("/", "_").replace("+", "-") + "_"
37 #Create a new plexure for bypass the control of the endpoint
38 plexure_api = encryptAES(f'{MASTER_KEY}|{getModifiedDate()}', fake_device_id)
39
40 #Create temp headers for this request using the base_headers as base
41 tmp_headers = copy.deepcopy(headers)
42
43 #Change the device id to avoid recognizing
44 tmp_headers["x-vmob-uid"] = fake_device_id
45 #Change the plexure key for this vmob
46 tmp_headers["x-plexure-api-key"] = plexure_api
47 #Space allocated to request the offer
48 tmp_headers["Content-Length"] = str(len(content))
49
50 #make post request to create the account
51 response = requests.post(url, content, headers=tmp_headers).text
52
53 #Content lenght if all go Correct
54 if "bearer" in response:
55 return 'bearer ' + json.loads(response)['access_token']
56
57 #The response is not correct...
58 return None
59
60
61#Get a right date to be used for the encryption of the plexure
62def getModifiedDate():
63
64 now = datetime.datetime.utcnow()
65 return str((now - datetime.timedelta(seconds=600)).isoformat(timespec="microseconds")) + '0Z'
66
67
68#Make a fake device uid using DES encryption
69def make_fake_device_uid(password=DES_KEY):
70
71 salt = ''.join([chr(random.choice(HEX_LIST)) for _ in range(16)])
72 cipher = des.DesKey(password[:8].encode('ascii'))
73 value = cipher.encrypt(f'co.vmob.android.sdk.{salt}'.encode('ascii'), padding=True)
74
75 return base64.encodebytes(value)
76
77
78#Make the inverse operation
79def decryptDES(text, password=DES_KEY):
80 text = text[:-1].replace("_", "/").replace("-", "+")
81 text = base64.decodebytes(text.encode('utf-8'))
82
83 cipher = des.DesKey(password[:8].encode('utf-8'))
84 value = cipher.decrypt(text)
85
86 return value.decode('utf-8')
87
88
89def encryptAES(text, password):
90
91 salt = urandom(8)
92 block = pbkdf2_hmac('sha1', password.encode('utf-8'), salt, 100, 48)
93
94 key = block[:32]
95 iv = block[32:48]
96
97 cipher = AES.new(key, AES.MODE_CBC, iv)
98 text = pad(text.encode('utf-8'), AES.block_size, style="pkcs7")
99
100 encrypted = cipher.encrypt(text) + salt
101
102 return base64.encodebytes(encrypted).decode('utf-8').replace("\n", "").replace(" ", "")
103
104
105#Get all the content of json response using token and the productID(offer code)
106def get_offer(token, offerID, headers = base_headers):
107
108 #Used to call the reedemOffers API
109 url = "https://con-West-Europe-GMA.vmobapps.com/v3/consumers/redeemedOffers"
110
111 #Create a new device id to bypass the checking of devide
112 fake_device_id = make_fake_device_uid().decode('ascii')[:-1].replace("/", "_").replace("+", "-") + "_"
113 #Create a new plexure for bypass the control of the endpoint
114 plexure_api = encryptAES(f'{MASTER_KEY}|{getModifiedDate()}', fake_device_id)
115
116 #Create temp headers for this request using the base_headers as base
117 tmp_headers = copy.deepcopy(headers)
118
119 #Change the device id to avoid recognizing
120 tmp_headers["x-vmob-uid"] = fake_device_id
121 #Change the plexure key for this vmob
122 tmp_headers["x-plexure-api-key"] = plexure_api
123 #Change the token with the last account's registration_token
124 tmp_headers["Authorization"] = token
125 #Used by default on the call of API
126 tmp_headers["x-vmob-location_accuracy"] = "3.0"
127 #Space allocated to request the offer
128 tmp_headers["Content-Lenght"] = "17"
129
130 #Create a JSON file which send the offerID
131 content = json.dumps({"offerId":int(offerID),"offerInstanceUniqueId":str(offerID)})
132
133 response = requests.post(url, content, headers=tmp_headers).text
134
135 #Check for some error
136 if "error" in response:
137 return None
138
139 #All go right so it will return the data as a dict
140 return json.loads(response)