From d3cc3b09e387e535dd614b0e640b8fa06187470d Mon Sep 17 00:00:00 2001 From: JJTech0130 Date: Sat, 21 Oct 2023 15:52:17 -0400 Subject: [PATCH] begin implementing anisette v3 --- bags.py | 33 +++++++++++++++++++------ emulated/anisette.py | 58 ++++++++++++++++++++++++++++++++++++++++++++ gsa.py | 5 +++- 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 emulated/anisette.py diff --git a/bags.py b/bags.py index 7a977d5..ae5099d 100644 --- a/bags.py +++ b/bags.py @@ -71,16 +71,35 @@ def ids_bag(): return bag +GRANDSLAM_BAG = None +def grandslam_bag(): + global GRANDSLAM_BAG + + if GRANDSLAM_BAG is not None: + return GRANDSLAM_BAG + + import gsa + + r = requests.get( + "https://gsa.apple.com/grandslam/GsService2/lookup", verify=False, + headers = { + # We have to provide client info so that the server knows which version of the bag to give us + "X-Mme-Client-Info": gsa.build_client(), + "User-Agent": gsa.USER_AGENT, + } + ) + if r.status_code != 200: + raise Exception("Failed to get Grandslam bag: " + r.status_code) + + GRANDSLAM_BAG = plistlib.loads(r.content) + + return GRANDSLAM_BAG + + if __name__ == "__main__": # config = get_config() # print(config) # print(apns_init_bag_2()) # print(apns_init_bag_2() == apns_init_bag()) - bag = ids_bag() - for key in bag: - # print(key) - # print(bag[key]) - if type(bag[key]) == str: - if "http" in bag[key]: - print(key, bag[key]) + print(grandslam_bag()) diff --git a/emulated/anisette.py b/emulated/anisette.py new file mode 100644 index 0000000..fd52d31 --- /dev/null +++ b/emulated/anisette.py @@ -0,0 +1,58 @@ +# Add parent directory to path +import sys +sys.path.append(".") +from websockets.sync.client import connect +import json +from base64 import b64encode +import random +import bags +import requests +import plistlib +import gsa + +ANISETTE_SERVER = "wss://ani.sidestore.io/v3/provisioning_session" + +START_PROVISIONING_URL = bags.grandslam_bag()["urls"]["midStartProvisioning"] +FINISH_PROVISIONING_URL = bags.grandslam_bag()["urls"]["midFinishProvisioning"] + + +def start_provisioning() -> str: # returns spim + body = { + "Header": {}, + "Request": {} + } + body = plistlib.dumps(body) + r = requests.post(START_PROVISIONING_URL, verify=False, data=body, headers= { + "X-Mme-Client-Info": gsa.build_client(), + "User-Agent": gsa.USER_AGENT, + }) + b = plistlib.loads(r.content) + return b['Response']['spim'] + +identifier = b64encode(random.randbytes(16)).decode() + +spim = "" +cpim = "" + +with connect(ANISETTE_SERVER) as websocket: + # Handle messages as the server sends them + while True: + message = json.loads(websocket.recv()) + print(f"Received: {message}") + + if message["result"] == "GiveIdentifier": + websocket.send(json.dumps({ + "identifier": identifier, + })) + elif message["result"] == "GiveStartProvisioningData": + spim = start_provisioning() + websocket.send(json.dumps({ + "spim": spim, + })) + elif message["result"] == "GiveEndProvisioningData": + + if 'cpim' in message: + cpim = message['cpim'] + + elif message["result"] == "Timeout": + break \ No newline at end of file diff --git a/gsa.py b/gsa.py index 37ba8fd..7697689 100644 --- a/gsa.py +++ b/gsa.py @@ -26,6 +26,9 @@ ANISETTE = False # Use local generation with AOSKit (macOS only) # ANISETTE = 'https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx' # ANISETTE = "http://jkcoxson.com:2052/" +#USER_AGENT = "com.apple.iCloudHelper/282 CFNetwork/1408.0.4 Darwin/22.5.0" +USER_AGENT = "akd/1.0 CFNetwork/978.0.7 Darwin/18.7.0" + # Created here so that it is consistent USER_ID = uuid.uuid4() DEVICE_ID = uuid.uuid4() @@ -175,7 +178,7 @@ def authenticated_request(parameters) -> dict: headers = { "Content-Type": "text/x-xml-plist", "Accept": "*/*", - "User-Agent": "akd/1.0 CFNetwork/978.0.7 Darwin/18.7.0", + "User-Agent": USER_AGENT, "X-MMe-Client-Info": build_client(emulated_app="Xcode"), }