|
|
@@ -0,0 +1,486 @@ |
|
|
#!/usr/bin/python3 |
|
|
|
|
|
from base64 import b64decode, b64encode |
|
|
from hashlib import md5 |
|
|
from secrets import choice |
|
|
from string import printable, digits |
|
|
import requests |
|
|
from xml.dom.minidom import parseString |
|
|
|
|
|
#import logging |
|
|
|
|
|
#import http.client as http_client |
|
|
#http_client.HTTPConnection.debuglevel = 1 |
|
|
|
|
|
#logging.basicConfig() |
|
|
#logging.getLogger().setLevel(logging.DEBUG) |
|
|
#requests_log = logging.getLogger('requests.packages.urllib3') |
|
|
#requests_log.setLevel(logging.DEBUG) |
|
|
#requests_log.propagate = True |
|
|
|
|
|
# MF286D |
|
|
#model = 'MF286D' |
|
|
#TELIA |
|
|
#firmware = 'TELIA_MF286DV1.0.0B10' |
|
|
#ELISA |
|
|
#firmware = 'ELISA_FI_MF286DV1.0.0B03' |
|
|
#TIM |
|
|
#firmware = 'TIM_IT_MF286DV1.0.0B07' |
|
|
#PLAY |
|
|
#firmware = 'NTT_PL_MF286DV1.0.0B02' |
|
|
#imei_start = '86675404' |
|
|
#URI = 'https://dmeu.ztems.com/zxmdmp/dm' |
|
|
|
|
|
# MF286A |
|
|
|
|
|
#model = 'MF286' |
|
|
# Tele2 LT |
|
|
#firmware = 'TELE2_LT_QMF286AV1.0.0B01' |
|
|
#imei_start = '86821902' |
|
|
#URI = 'https://dmeu.ztems.com/zxmdmp/dm' |
|
|
|
|
|
# MF286 |
|
|
|
|
|
#model = 'MF286' |
|
|
# EN_EEU (Orange PL) |
|
|
#firmware = 'EN_EEU_MF286V1.0.1B01' |
|
|
#imei_start = '86821902' |
|
|
#URI = 'http://dms.ztems.com/zxmdmp/dm' |
|
|
|
|
|
# MF283+ |
|
|
|
|
|
model = 'MF283PLUS' |
|
|
firmware = 'EN_ORA_PL_MF283+V1.0.0B12' |
|
|
#firmware = 'EN_ORA_PL_MF283+V1.0.0B06' |
|
|
#firmware = 'EN_PL_MF283PLUSV1.0.0B02' |
|
|
imei_start = '864780021' |
|
|
URI = 'http://dms.ztems.com/zxmdmp/dm' |
|
|
|
|
|
#request_type = 'devicerequest' |
|
|
request_type = 'userrequest' |
|
|
|
|
|
username = 'ZTEDM' |
|
|
password = 'ZTEDM' |
|
|
|
|
|
def imei_get(number): |
|
|
while len(number) < 14: |
|
|
number += choice(digits) |
|
|
alphabet='0123456789' |
|
|
imei = number + alphabet[0] |
|
|
n = len(alphabet) |
|
|
imei = tuple(alphabet.index(i) |
|
|
for i in reversed(str(imei))) |
|
|
check_digit = (sum(imei[::2]) + |
|
|
sum(sum(divmod(i * 2, n)) |
|
|
for i in imei[1::2])) % n |
|
|
number += alphabet[-check_digit] |
|
|
return number |
|
|
|
|
|
def nonce_get(): |
|
|
nonce = ''.join((choice(printable) for x in range(16))) |
|
|
return b64encode(nonce.encode('utf-8')).decode('utf-8') |
|
|
|
|
|
def hmac_get(nonce, body, username, password, mark=':'): |
|
|
auth = username + mark + password |
|
|
mark_enc = mark.encode('utf-8') |
|
|
auth_b64 = b64encode(md5(auth.encode('utf-8')).digest()) |
|
|
nonce_md5 = b64decode(nonce) |
|
|
body_b64 = b64encode(md5(body.encode('utf-8')).digest()) |
|
|
hmac = auth_b64 + mark_enc + nonce_md5 + mark_enc + body_b64 |
|
|
return b64encode(md5(hmac).digest()).decode('utf-8') |
|
|
|
|
|
def body_get(body): |
|
|
xml = '' |
|
|
for line in body.splitlines(): |
|
|
xml += line.strip() |
|
|
return xml |
|
|
|
|
|
imei = imei_get(imei_start) |
|
|
|
|
|
print(f'Model: {model}') |
|
|
print(f'Firmware: {firmware}') |
|
|
print(f'IMEI: {imei}') |
|
|
|
|
|
try: |
|
|
body1 = f'''<?xml version="1.0" encoding="UTF-8"?> |
|
|
<SyncML xmlns='SYNCML:SYNCML1.2'> |
|
|
<SyncHdr> |
|
|
<VerDTD>1.2</VerDTD> |
|
|
<VerProto>DM/1.2</VerProto> |
|
|
<SessionID>3E8</SessionID> |
|
|
<MsgID>1</MsgID> |
|
|
<Target> |
|
|
<LocURI>{URI}</LocURI> |
|
|
</Target> |
|
|
<Source> |
|
|
<LocURI>IMEI:{imei}</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<MaxMsgSize xmlns='syncml:metinf'>5000</MaxMsgSize> |
|
|
</Meta> |
|
|
</SyncHdr> |
|
|
<SyncBody> |
|
|
<Alert> |
|
|
<CmdID>1</CmdID> |
|
|
<Data>1226</Data> |
|
|
<Item> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>int</Format> |
|
|
<Type xmlns='syncml:metinf'>org.openmobilealliance.dm.firmwareupdate.{request_type}</Type> |
|
|
<Mark xmlns='syncml:metinf'>indeterminate</Mark> |
|
|
</Meta> |
|
|
<Data>0</Data> |
|
|
</Item> |
|
|
</Alert> |
|
|
<Alert> |
|
|
<CmdID>2</CmdID> |
|
|
<Data>1201</Data> |
|
|
</Alert> |
|
|
<Replace> |
|
|
<CmdID>3</CmdID> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/Correlator</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>0</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/ErrCode</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>int</Format> |
|
|
</Meta> |
|
|
<Data>0</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/InnerV</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data></Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/CompileT</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data></Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>node</Format> |
|
|
</Meta> |
|
|
<Data>CompileT/InnerV/ErrCode/Correlator</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/DmV</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>1.2</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Lang</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>en</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/DevId</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>IMEI:{imei}</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Man</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>ZTE</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Mod</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>{model}</Data> |
|
|
</Item> |
|
|
</Replace> |
|
|
<Final/> |
|
|
</SyncBody> |
|
|
</SyncML>''' |
|
|
body = body_get(body1) |
|
|
hmac = hmac_get(nonce_get(), body, username, password) |
|
|
headers = {'Accept-Charset': 'utf-8', |
|
|
'Accept-Language': 'en', |
|
|
'Connection': 'close', |
|
|
'Cache-Control': 'no-cache', |
|
|
'Content-Type': 'application/vnd.syncml.dm+xml', |
|
|
'x-syncml-hmac': f'algorithm=MD5, username="{username}", mac={hmac}', |
|
|
'User-Agent': None, |
|
|
'Accept-Encoding': None} |
|
|
response = requests.post(URI, data=body, headers=headers) |
|
|
response.raise_for_status() |
|
|
resp = parseString(response.text) |
|
|
resp_uri = resp.getElementsByTagName('RespURI')[0].firstChild.nodeValue.replace('&', '&') |
|
|
nonce = resp.getElementsByTagName('NextNonce')[0].firstChild.nodeValue |
|
|
|
|
|
body2 = f'''<?xml version="1.0" encoding="UTF-8"?> |
|
|
<SyncML xmlns='SYNCML:SYNCML1.2'> |
|
|
<SyncHdr> |
|
|
<VerDTD>1.2</VerDTD> |
|
|
<VerProto>DM/1.2</VerProto> |
|
|
<SessionID>3E8</SessionID> |
|
|
<MsgID>2</MsgID> |
|
|
<Target> |
|
|
<LocURI><![CDATA[{resp_uri}]]></LocURI> |
|
|
</Target> |
|
|
<Source> |
|
|
<LocURI>IMEI:{imei}</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<MaxMsgSize xmlns='syncml:metinf'>5000</MaxMsgSize> |
|
|
</Meta> |
|
|
</SyncHdr> |
|
|
<SyncBody> |
|
|
<Status> |
|
|
<CmdID>1</CmdID> |
|
|
<MsgRef>1</MsgRef> |
|
|
<CmdRef>0</CmdRef> |
|
|
<Cmd>SyncHdr</Cmd> |
|
|
<TargetRef>IMEI:{imei}</TargetRef> |
|
|
<SourceRef>{URI}</SourceRef> |
|
|
<Chal> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>b64</Format> |
|
|
<Type xmlns='syncml:metinf'>syncml:auth-MAC</Type> |
|
|
<NextNonce xmlns='syncml:metinf'>{nonce_get()}</NextNonce> |
|
|
</Meta> |
|
|
</Chal> |
|
|
<Data>401</Data> |
|
|
</Status> |
|
|
<Alert> |
|
|
<CmdID>2</CmdID> |
|
|
<Data>1226</Data> |
|
|
<Item> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>int</Format> |
|
|
<Type xmlns='syncml:metinf'>org.openmobilealliance.dm.firmwareupdate.{request_type}</Type> |
|
|
<Mark xmlns='syncml:metinf'>indeterminate</Mark> |
|
|
</Meta> |
|
|
<Data>0</Data> |
|
|
</Item> |
|
|
</Alert> |
|
|
<Alert> |
|
|
<CmdID>3</CmdID> |
|
|
<Data>1201</Data> |
|
|
</Alert> |
|
|
<Replace> |
|
|
<CmdID>4</CmdID> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/Correlator</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>0</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/ErrCode</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>int</Format> |
|
|
</Meta> |
|
|
<Data>0</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/InnerV</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data></Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext/CompileT</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data></Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Ext</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>node</Format> |
|
|
</Meta> |
|
|
<Data>CompileT/InnerV/ErrCode/Correlator</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/DmV</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>1.2</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Lang</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>en</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/DevId</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>IMEI:{imei}</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Man</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>ZTE</Data> |
|
|
</Item> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevInfo/Mod</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>{model}</Data> |
|
|
</Item> |
|
|
</Replace> |
|
|
<Final/> |
|
|
</SyncBody> |
|
|
</SyncML>''' |
|
|
body = body_get(body2) |
|
|
hmac = hmac_get(nonce, body, username, password) |
|
|
headers['x-syncml-hmac'] = f'algorithm=MD5, username="{username}", mac={hmac}' |
|
|
response = requests.post(resp_uri, data=body, headers=headers) |
|
|
response.raise_for_status() |
|
|
resp = parseString(response.text) |
|
|
nonce = resp.getElementsByTagName('NextNonce')[0].firstChild.nodeValue |
|
|
|
|
|
body3 = f'''<?xml version="1.0" encoding="UTF-8"?> |
|
|
<SyncML xmlns='SYNCML:SYNCML1.2'> |
|
|
<SyncHdr> |
|
|
<VerDTD>1.2</VerDTD> |
|
|
<VerProto>DM/1.2</VerProto> |
|
|
<SessionID>3E8</SessionID> |
|
|
<MsgID>3</MsgID> |
|
|
<Target> |
|
|
<LocURI><![CDATA[{resp_uri}]]></LocURI> |
|
|
</Target> |
|
|
<Source> |
|
|
<LocURI>IMEI:{imei}</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<MaxMsgSize xmlns='syncml:metinf'>5000</MaxMsgSize> |
|
|
</Meta> |
|
|
</SyncHdr> |
|
|
<SyncBody> |
|
|
<Status> |
|
|
<CmdID>1</CmdID> |
|
|
<MsgRef>2</MsgRef> |
|
|
<CmdRef>0</CmdRef> |
|
|
<Cmd>SyncHdr</Cmd> |
|
|
<TargetRef>IMEI:{imei}</TargetRef> |
|
|
<SourceRef><![CDATA[{resp_uri}]]></SourceRef> |
|
|
<Chal> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>b64</Format> |
|
|
<Type xmlns='syncml:metinf'>syncml:auth-MAC</Type> |
|
|
<NextNonce xmlns='syncml:metinf'>{nonce_get()}</NextNonce> |
|
|
</Meta> |
|
|
</Chal> |
|
|
<Data>200</Data> |
|
|
</Status> |
|
|
<Status> |
|
|
<CmdID>2</CmdID> |
|
|
<MsgRef>2</MsgRef> |
|
|
<CmdRef>5</CmdRef> |
|
|
<Cmd>Get</Cmd> |
|
|
<TargetRef>./DevDetail/SwV</TargetRef> |
|
|
<Data>200</Data> |
|
|
</Status> |
|
|
<Results> |
|
|
<CmdID>3</CmdID> |
|
|
<MsgRef>2</MsgRef> |
|
|
<CmdRef>5</CmdRef> |
|
|
<Item> |
|
|
<Source> |
|
|
<LocURI>./DevDetail/SwV</LocURI> |
|
|
</Source> |
|
|
<Meta> |
|
|
<Format xmlns='syncml:metinf'>chr</Format> |
|
|
</Meta> |
|
|
<Data>{firmware}</Data> |
|
|
</Item> |
|
|
</Results> |
|
|
<Final/> |
|
|
</SyncBody> |
|
|
</SyncML>''' |
|
|
body = body_get(body3) |
|
|
hmac = hmac_get(nonce, body, username, password) |
|
|
headers['x-syncml-hmac'] = f'algorithm=MD5, username="{username}", mac={hmac}' |
|
|
response = requests.post(resp_uri, data=body, headers=headers) |
|
|
response.raise_for_status() |
|
|
resp = parseString(response.text) |
|
|
resp_replace = resp.getElementsByTagName('Replace') |
|
|
|
|
|
if resp_replace: |
|
|
data_uri = resp_replace[0].getElementsByTagName('Data')[1].firstChild.nodeValue.replace('&', '&') |
|
|
response = requests.get(data_uri, headers=headers) |
|
|
response.raise_for_status() |
|
|
resp = parseString(response.text) |
|
|
firm_desc = resp.getElementsByTagName('description')[0].firstChild.nodeValue |
|
|
firm_uri = resp.getElementsByTagName('objectURI')[0].firstChild.nodeValue.replace('&', '&') |
|
|
print(f'\nDescription: {firm_desc}') |
|
|
print(f'URI: {firm_uri}') |
|
|
else: |
|
|
print('\nNothing found') |
|
|
except requests.exceptions.HTTPError as http_error: |
|
|
print(f'HTTP error: {http_error}') |
|
|
except Exception as error: |
|
|
print(f'Error: {error}') |