mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2025-01-09 17:33:47 +00:00
run formatter
This commit is contained in:
parent
0a52b2c12a
commit
618342a39f
9 changed files with 165 additions and 132 deletions
|
@ -79,7 +79,8 @@ def generate_push_cert() -> tuple[str, str]:
|
||||||
|
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
"https://albert.apple.com/WebObjects/ALUnbrick.woa/wa/deviceActivation?device=Windows",
|
"https://albert.apple.com/WebObjects/ALUnbrick.woa/wa/deviceActivation?device=Windows",
|
||||||
data={"activation-info": plistlib.dumps(body)}, verify=False,
|
data={"activation-info": plistlib.dumps(body)},
|
||||||
|
verify=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
protocol = re.search("<Protocol>(.*)</Protocol>", resp.text).group(1)
|
protocol = re.search("<Protocol>(.*)</Protocol>", resp.text).group(1)
|
||||||
|
|
28
apns.py
28
apns.py
|
@ -29,6 +29,7 @@ def _connect(private_key: str, cert: str) -> tlslite.TLSConnection:
|
||||||
|
|
||||||
return sock
|
return sock
|
||||||
|
|
||||||
|
|
||||||
class IncomingQueue:
|
class IncomingQueue:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.queue = []
|
self.queue = []
|
||||||
|
@ -70,6 +71,7 @@ class IncomingQueue:
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
return found
|
return found
|
||||||
|
|
||||||
|
|
||||||
class APNSConnection:
|
class APNSConnection:
|
||||||
incoming_queue = IncomingQueue()
|
incoming_queue = IncomingQueue()
|
||||||
|
|
||||||
|
@ -87,8 +89,8 @@ class APNSConnection:
|
||||||
# print("QUEUE: Got payload?")
|
# print("QUEUE: Got payload?")
|
||||||
|
|
||||||
if payload is not None:
|
if payload is not None:
|
||||||
#print("QUEUE: Received payload: " + str(payload))
|
# print("QUEUE: Received payload: " + str(payload))
|
||||||
#print("QUEUE: Received payload type: " + hex(payload[0]))
|
# print("QUEUE: Received payload type: " + hex(payload[0]))
|
||||||
self.incoming_queue.append(payload)
|
self.incoming_queue.append(payload)
|
||||||
# print("QUEUE: Thread ended")
|
# print("QUEUE: Thread ended")
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ class APNSConnection:
|
||||||
|
|
||||||
# def find_packet(self, finder) ->
|
# def find_packet(self, finder) ->
|
||||||
|
|
||||||
#def replace_packet(self, payload: tuple[int, list[tuple[int, bytes]]]):
|
# def replace_packet(self, payload: tuple[int, list[tuple[int, bytes]]]):
|
||||||
# self.incoming_queue.append(payload)
|
# self.incoming_queue.append(payload)
|
||||||
|
|
||||||
def __init__(self, private_key=None, cert=None):
|
def __init__(self, private_key=None, cert=None):
|
||||||
|
@ -137,11 +139,16 @@ class APNSConnection:
|
||||||
|
|
||||||
if token is None:
|
if token is None:
|
||||||
payload = _serialize_payload(
|
payload = _serialize_payload(
|
||||||
7, [(2, 0x01.to_bytes(1, 'big')), (5, flags.to_bytes(4, 'big'))]
|
7, [(2, 0x01.to_bytes(1, "big")), (5, flags.to_bytes(4, "big"))]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
payload = _serialize_payload(
|
payload = _serialize_payload(
|
||||||
7, [(1, token), (2, 0x01.to_bytes(1, 'big')), (5, flags.to_bytes(4, 'big'))]
|
7,
|
||||||
|
[
|
||||||
|
(1, token),
|
||||||
|
(2, 0x01.to_bytes(1, "big")),
|
||||||
|
(5, flags.to_bytes(4, "big")),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.sock.write(payload)
|
self.sock.write(payload)
|
||||||
|
@ -151,7 +158,7 @@ class APNSConnection:
|
||||||
if (
|
if (
|
||||||
payload == None
|
payload == None
|
||||||
or payload[0] != 8
|
or payload[0] != 8
|
||||||
or _get_field(payload[1], 1) != 0x00.to_bytes(1, 'big')
|
or _get_field(payload[1], 1) != 0x00.to_bytes(1, "big")
|
||||||
):
|
):
|
||||||
raise Exception("Failed to connect")
|
raise Exception("Failed to connect")
|
||||||
|
|
||||||
|
@ -194,13 +201,14 @@ class APNSConnection:
|
||||||
# Wait for ACK
|
# Wait for ACK
|
||||||
payload = self.incoming_queue.wait_pop_find(lambda i: i[0] == 0x0B)
|
payload = self.incoming_queue.wait_pop_find(lambda i: i[0] == 0x0B)
|
||||||
|
|
||||||
if payload[1][0][1] != 0x00.to_bytes(1, 'big'):
|
if payload[1][0][1] != 0x00.to_bytes(1, "big"):
|
||||||
raise Exception("Failed to send message")
|
raise Exception("Failed to send message")
|
||||||
|
|
||||||
def set_state(self, state: int):
|
def set_state(self, state: int):
|
||||||
self.sock.write(
|
self.sock.write(
|
||||||
_serialize_payload(
|
_serialize_payload(
|
||||||
0x14, [(1, state.to_bytes(1, 'big')), (2, 0x7FFFFFFF.to_bytes(4, 'big'))]
|
0x14,
|
||||||
|
[(1, state.to_bytes(1, "big")), (2, 0x7FFFFFFF.to_bytes(4, "big"))],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -226,7 +234,7 @@ class APNSConnection:
|
||||||
|
|
||||||
|
|
||||||
def _serialize_field(id: int, value: bytes) -> bytes:
|
def _serialize_field(id: int, value: bytes) -> bytes:
|
||||||
return id.to_bytes(1, 'big') + len(value).to_bytes(2, "big") + value
|
return id.to_bytes(1, "big") + len(value).to_bytes(2, "big") + value
|
||||||
|
|
||||||
|
|
||||||
def _serialize_payload(id: int, fields: list[(int, bytes)]) -> bytes:
|
def _serialize_payload(id: int, fields: list[(int, bytes)]) -> bytes:
|
||||||
|
@ -236,7 +244,7 @@ def _serialize_payload(id: int, fields: list[(int, bytes)]) -> bytes:
|
||||||
if fid is not None:
|
if fid is not None:
|
||||||
payload += _serialize_field(fid, value)
|
payload += _serialize_field(fid, value)
|
||||||
|
|
||||||
return id.to_bytes(1, 'big') + len(payload).to_bytes(4, "big") + payload
|
return id.to_bytes(1, "big") + len(payload).to_bytes(4, "big") + payload
|
||||||
|
|
||||||
|
|
||||||
def _deserialize_field(stream: bytes) -> tuple[int, bytes]:
|
def _deserialize_field(stream: bytes) -> tuple[int, bytes]:
|
||||||
|
|
8
bags.py
8
bags.py
|
@ -45,11 +45,11 @@ if __name__ == "__main__":
|
||||||
# config = get_config()
|
# config = get_config()
|
||||||
# print(config)
|
# print(config)
|
||||||
# print(apns_init_bag_2())
|
# print(apns_init_bag_2())
|
||||||
#print(apns_init_bag_2() == apns_init_bag())
|
# print(apns_init_bag_2() == apns_init_bag())
|
||||||
bag = ids_bag()
|
bag = ids_bag()
|
||||||
for key in bag:
|
for key in bag:
|
||||||
#print(key)
|
# print(key)
|
||||||
#print(bag[key])
|
# print(bag[key])
|
||||||
if type(bag[key]) == str:
|
if type(bag[key]) == str:
|
||||||
if 'http' in bag[key]:
|
if "http" in bag[key]:
|
||||||
print(key, bag[key])
|
print(key, bag[key])
|
||||||
|
|
97
demo.py
97
demo.py
|
@ -1,8 +1,9 @@
|
||||||
from ids import *
|
|
||||||
import ids
|
|
||||||
import getpass
|
import getpass
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import ids
|
||||||
|
from ids import *
|
||||||
|
|
||||||
# Open config
|
# Open config
|
||||||
try:
|
try:
|
||||||
with open("config.json", "r") as f:
|
with open("config.json", "r") as f:
|
||||||
|
@ -10,6 +11,7 @@ try:
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
CONFIG = {}
|
CONFIG = {}
|
||||||
|
|
||||||
|
|
||||||
def input_multiline(prompt):
|
def input_multiline(prompt):
|
||||||
print(prompt)
|
print(prompt)
|
||||||
lines = []
|
lines = []
|
||||||
|
@ -20,6 +22,7 @@ def input_multiline(prompt):
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
def refresh_token():
|
def refresh_token():
|
||||||
# If no username is set, prompt for it
|
# If no username is set, prompt for it
|
||||||
if "username" not in CONFIG:
|
if "username" not in CONFIG:
|
||||||
|
@ -38,44 +41,48 @@ def refresh_token():
|
||||||
CONFIG["username"], CONFIG["password"], CONFIG["use_gsa"], factor_gen=factor_gen
|
CONFIG["username"], CONFIG["password"], CONFIG["use_gsa"], factor_gen=factor_gen
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def refresh_cert():
|
def refresh_cert():
|
||||||
CONFIG["key"], CONFIG["auth_cert"] = ids._get_auth_cert(
|
CONFIG["key"], CONFIG["auth_cert"] = ids._get_auth_cert(
|
||||||
CONFIG["user_id"], CONFIG["token"]
|
CONFIG["user_id"], CONFIG["token"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_connection():
|
def create_connection():
|
||||||
conn = apns.APNSConnection()
|
conn = apns.APNSConnection()
|
||||||
token = conn.connect()
|
token = conn.connect()
|
||||||
#conn.filter(['com.apple.madrid'])
|
# conn.filter(['com.apple.madrid'])
|
||||||
CONFIG['push'] = {
|
CONFIG["push"] = {
|
||||||
'token': b64encode(token).decode(),
|
"token": b64encode(token).decode(),
|
||||||
'cert': conn.cert,
|
"cert": conn.cert,
|
||||||
'key': conn.private_key
|
"key": conn.private_key,
|
||||||
}
|
}
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
|
||||||
def restore_connection():
|
def restore_connection():
|
||||||
conn = apns.APNSConnection(CONFIG['push']['key'], CONFIG['push']['cert'])
|
conn = apns.APNSConnection(CONFIG["push"]["key"], CONFIG["push"]["cert"])
|
||||||
conn.connect(True, b64decode(CONFIG['push']['token']))
|
conn.connect(True, b64decode(CONFIG["push"]["token"]))
|
||||||
#conn.filter(['com.apple.madrid', 'com.apple.private.alloy.facetime.multi'])
|
# conn.filter(['com.apple.madrid', 'com.apple.private.alloy.facetime.multi'])
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
|
||||||
def refresh_ids_cert():
|
def refresh_ids_cert():
|
||||||
info = {
|
info = {
|
||||||
"uri": "mailto:" + CONFIG["username"],
|
"uri": "mailto:" + CONFIG["username"],
|
||||||
"user_id": CONFIG['user_id'],
|
"user_id": CONFIG["user_id"],
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = None
|
resp = None
|
||||||
try:
|
try:
|
||||||
if "validation_data" in CONFIG:
|
if "validation_data" in CONFIG:
|
||||||
resp = ids._register_request(
|
resp = ids._register_request(
|
||||||
CONFIG['push']['token'],
|
CONFIG["push"]["token"],
|
||||||
info,
|
info,
|
||||||
CONFIG['auth_cert'],
|
CONFIG["auth_cert"],
|
||||||
CONFIG['key'],
|
CONFIG["key"],
|
||||||
CONFIG['push']['cert'],
|
CONFIG["push"]["cert"],
|
||||||
CONFIG['push']['key'],
|
CONFIG["push"]["key"],
|
||||||
CONFIG["validation_data"],
|
CONFIG["validation_data"],
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -92,40 +99,36 @@ def refresh_ids_cert():
|
||||||
.replace(" ", "")
|
.replace(" ", "")
|
||||||
)
|
)
|
||||||
resp = ids._register_request(
|
resp = ids._register_request(
|
||||||
CONFIG['push']['token'],
|
CONFIG["push"]["token"],
|
||||||
info,
|
info,
|
||||||
CONFIG['auth_cert'],
|
CONFIG["auth_cert"],
|
||||||
CONFIG['key'],
|
CONFIG["key"],
|
||||||
CONFIG['push']['cert'],
|
CONFIG["push"]["cert"],
|
||||||
CONFIG['push']['key'],
|
CONFIG["push"]["key"],
|
||||||
validation_data,
|
validation_data,
|
||||||
)
|
)
|
||||||
CONFIG["validation_data"] = validation_data
|
CONFIG["validation_data"] = validation_data
|
||||||
|
|
||||||
ids_cert = x509.load_der_x509_certificate(
|
ids_cert = x509.load_der_x509_certificate(resp["services"][0]["users"][0]["cert"])
|
||||||
resp["services"][0]["users"][0]["cert"]
|
ids_cert = ids_cert.public_bytes(serialization.Encoding.PEM).decode("utf-8").strip()
|
||||||
)
|
|
||||||
ids_cert = (
|
|
||||||
ids_cert.public_bytes(serialization.Encoding.PEM).decode("utf-8").strip()
|
|
||||||
)
|
|
||||||
|
|
||||||
CONFIG["ids_cert"] = ids_cert
|
CONFIG["ids_cert"] = ids_cert
|
||||||
|
|
||||||
|
|
||||||
if not 'push' in CONFIG:
|
if not "push" in CONFIG:
|
||||||
print("No existing APNs credentials, creating new ones...")
|
print("No existing APNs credentials, creating new ones...")
|
||||||
#print("No push conn")
|
# print("No push conn")
|
||||||
conn = create_connection()
|
conn = create_connection()
|
||||||
else:
|
else:
|
||||||
print("Restoring APNs credentials...")
|
print("Restoring APNs credentials...")
|
||||||
conn = restore_connection()
|
conn = restore_connection()
|
||||||
print("Connected to APNs!")
|
print("Connected to APNs!")
|
||||||
|
|
||||||
if not 'ids_cert' in CONFIG:
|
if not "ids_cert" in CONFIG:
|
||||||
print("No existing IDS certificate, creating new one...")
|
print("No existing IDS certificate, creating new one...")
|
||||||
if not 'key' in CONFIG:
|
if not "key" in CONFIG:
|
||||||
print("No existing authentication certificate, creating new one...")
|
print("No existing authentication certificate, creating new one...")
|
||||||
if not 'token' in CONFIG:
|
if not "token" in CONFIG:
|
||||||
print("No existing authentication token, creating new one...")
|
print("No existing authentication token, creating new one...")
|
||||||
refresh_token()
|
refresh_token()
|
||||||
print("Got authentication token!")
|
print("Got authentication token!")
|
||||||
|
@ -134,34 +137,36 @@ if not 'ids_cert' in CONFIG:
|
||||||
refresh_ids_cert()
|
refresh_ids_cert()
|
||||||
print("Got IDS certificate!")
|
print("Got IDS certificate!")
|
||||||
|
|
||||||
ids_keypair = ids.KeyPair(CONFIG['key'], CONFIG['ids_cert'])
|
ids_keypair = ids.KeyPair(CONFIG["key"], CONFIG["ids_cert"])
|
||||||
|
|
||||||
def lookup(topic:str, users: list[str]):
|
|
||||||
|
def lookup(topic: str, users: list[str]):
|
||||||
print(f"Looking up users {users} for topic {topic}...")
|
print(f"Looking up users {users} for topic {topic}...")
|
||||||
resp = ids.lookup(conn, CONFIG['username'], ids_keypair, topic, users)
|
resp = ids.lookup(conn, CONFIG["username"], ids_keypair, topic, users)
|
||||||
|
|
||||||
#print(resp)
|
# print(resp)
|
||||||
#r = list(resp['results'].values())[0]
|
# r = list(resp['results'].values())[0]
|
||||||
for k, v in resp['results'].items():
|
for k, v in resp["results"].items():
|
||||||
print(f"Result for user {k} topic {topic}:")
|
print(f"Result for user {k} topic {topic}:")
|
||||||
i = v['identities']
|
i = v["identities"]
|
||||||
print(f"IDENTITIES: {len(i)}")
|
print(f"IDENTITIES: {len(i)}")
|
||||||
for iden in i:
|
for iden in i:
|
||||||
print("IDENTITY", end=" ")
|
print("IDENTITY", end=" ")
|
||||||
print(f"Push Token: {b64encode(iden['push-token']).decode()}", end=" ")
|
print(f"Push Token: {b64encode(iden['push-token']).decode()}", end=" ")
|
||||||
if 'client-data' in iden:
|
if "client-data" in iden:
|
||||||
print(f"Client Data: {len(iden['client-data'])}")
|
print(f"Client Data: {len(iden['client-data'])}")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("No client data")
|
print("No client data")
|
||||||
|
|
||||||
|
|
||||||
# Hack to make sure that the requests and responses match up
|
# Hack to make sure that the requests and responses match up
|
||||||
# This filter MUST contain all the topics you are looking up
|
# This filter MUST contain all the topics you are looking up
|
||||||
#conn.filter(['com.apple.madrid', 'com.apple.private.alloy.facetime.multi', 'com.apple.private.alloy.multiplex1', 'com.apple.private.alloy.screensharing'])
|
# conn.filter(['com.apple.madrid', 'com.apple.private.alloy.facetime.multi', 'com.apple.private.alloy.multiplex1', 'com.apple.private.alloy.screensharing'])
|
||||||
#import time
|
# import time
|
||||||
#print("...waiting for queued messages... (this is a hack)")
|
# print("...waiting for queued messages... (this is a hack)")
|
||||||
#time.sleep(5) # Let the server send us any messages it was holding
|
# time.sleep(5) # Let the server send us any messages it was holding
|
||||||
#conn.sink() # Dump the messages
|
# conn.sink() # Dump the messages
|
||||||
|
|
||||||
lookup("com.apple.madrid", ["mailto:jjtech@jjtech.dev"])
|
lookup("com.apple.madrid", ["mailto:jjtech@jjtech.dev"])
|
||||||
lookup("com.apple.private.alloy.facetime.multi", ["mailto:jjtech@jjtech.dev"])
|
lookup("com.apple.private.alloy.facetime.multi", ["mailto:jjtech@jjtech.dev"])
|
||||||
|
@ -173,7 +178,7 @@ lookup("com.apple.private.alloy.multiplex1", ["mailto:user_test2@icloud.com"])
|
||||||
|
|
||||||
lookup("com.apple.private.alloy.screensharing", ["mailto:user_test2@icloud.com"])
|
lookup("com.apple.private.alloy.screensharing", ["mailto:user_test2@icloud.com"])
|
||||||
|
|
||||||
#time.sleep(4)
|
# time.sleep(4)
|
||||||
# Save config
|
# Save config
|
||||||
with open("config.json", "w") as f:
|
with open("config.json", "w") as f:
|
||||||
json.dump(CONFIG, f, indent=4)
|
json.dump(CONFIG, f, indent=4)
|
|
@ -12,6 +12,6 @@ conn1.connect()
|
||||||
|
|
||||||
conn1.filter(["com.apple.madrid"])
|
conn1.filter(["com.apple.madrid"])
|
||||||
|
|
||||||
#print(ids.lookup(conn1, ["mailto:jjtech@jjtech.dev"]))
|
# print(ids.lookup(conn1, ["mailto:jjtech@jjtech.dev"]))
|
||||||
|
|
||||||
print(ids.register(conn1, "user_test2@icloud.com", "wowSecure1"))
|
print(ids.register(conn1, "user_test2@icloud.com", "wowSecure1"))
|
||||||
|
|
|
@ -47,9 +47,10 @@ cert: str = None
|
||||||
key: str = None
|
key: str = None
|
||||||
|
|
||||||
|
|
||||||
import apns
|
|
||||||
import printer
|
import printer
|
||||||
|
|
||||||
|
import apns
|
||||||
|
|
||||||
outgoing_list = []
|
outgoing_list = []
|
||||||
incoming_list = []
|
incoming_list = []
|
||||||
# last_outgoing = b""
|
# last_outgoing = b""
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import ids
|
|
||||||
import hashlib
|
import hashlib
|
||||||
from base64 import b64decode
|
|
||||||
import zlib
|
|
||||||
import plistlib
|
import plistlib
|
||||||
|
import zlib
|
||||||
|
from base64 import b64decode
|
||||||
|
|
||||||
with open('body.txt', 'r') as f:
|
import ids
|
||||||
|
|
||||||
|
with open("body.txt", "r") as f:
|
||||||
BODY = f.read()
|
BODY = f.read()
|
||||||
|
|
||||||
CERT = "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"
|
CERT = "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"
|
||||||
|
@ -12,19 +13,21 @@ SIG = "AQEZs/u9Ptb8AmFpCv5XgzUsskvcleZDBxYTe5JOoshFCxpnByTwFA0mxplklHqT2rTEeF+Bu
|
||||||
TOKEN = "5V7AY+ikHr4DiSfq1W2UBa71G3FLGkpUSKTrOLg81yk="
|
TOKEN = "5V7AY+ikHr4DiSfq1W2UBa71G3FLGkpUSKTrOLg81yk="
|
||||||
NONCE = "AQAAAYeBb0XwKDMBW5PfAPM="
|
NONCE = "AQAAAYeBb0XwKDMBW5PfAPM="
|
||||||
|
|
||||||
|
|
||||||
def extract_hash(sig: bytes, cert: str) -> str:
|
def extract_hash(sig: bytes, cert: str) -> str:
|
||||||
#sig = b64decode(SIG)[2:]
|
# sig = b64decode(SIG)[2:]
|
||||||
sig = int.from_bytes(sig)
|
sig = int.from_bytes(sig)
|
||||||
|
|
||||||
# Get the correct hash
|
# Get the correct hash
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.x509 import load_pem_x509_certificate
|
from cryptography.x509 import load_pem_x509_certificate
|
||||||
#key, cert = load_keys()
|
|
||||||
|
# key, cert = load_keys()
|
||||||
cert = "-----BEGIN CERTIFICATE-----\n" + cert + "\n-----END CERTIFICATE-----"
|
cert = "-----BEGIN CERTIFICATE-----\n" + cert + "\n-----END CERTIFICATE-----"
|
||||||
cert = load_pem_x509_certificate(cert.encode(), default_backend())
|
cert = load_pem_x509_certificate(cert.encode(), default_backend())
|
||||||
modulus = cert.public_key().public_numbers().n
|
modulus = cert.public_key().public_numbers().n
|
||||||
power = cert.public_key().public_numbers().e
|
power = cert.public_key().public_numbers().e
|
||||||
#print(hex(pow(sig, power, modulus)))
|
# print(hex(pow(sig, power, modulus)))
|
||||||
|
|
||||||
return pow(sig, power, modulus)
|
return pow(sig, power, modulus)
|
||||||
# from cryptography import x509
|
# from cryptography import x509
|
||||||
|
@ -45,13 +48,14 @@ def extract_hash(sig: bytes, cert: str) -> str:
|
||||||
|
|
||||||
# return hash
|
# return hash
|
||||||
|
|
||||||
body = plistlib.dumps(plistlib.loads(BODY.encode()))
|
|
||||||
body = zlib.compress(BODY.encode(), wbits=16+zlib.MAX_WBITS)
|
|
||||||
|
|
||||||
p = ids._create_payload('id-register', '', TOKEN, body, b64decode(NONCE))[0]
|
body = plistlib.dumps(plistlib.loads(BODY.encode()))
|
||||||
|
body = zlib.compress(BODY.encode(), wbits=16 + zlib.MAX_WBITS)
|
||||||
|
|
||||||
|
p = ids._create_payload("id-register", "", TOKEN, body, b64decode(NONCE))[0]
|
||||||
s = hashlib.sha1(p).digest()
|
s = hashlib.sha1(p).digest()
|
||||||
print(s.hex())
|
print(s.hex())
|
||||||
#extract_hash(SIG, CERT)
|
# extract_hash(SIG, CERT)
|
||||||
|
|
||||||
# Loop through all POSSIBLE ranges
|
# Loop through all POSSIBLE ranges
|
||||||
# sig = b64decode(SIG)
|
# sig = b64decode(SIG)
|
||||||
|
@ -71,12 +75,11 @@ print(s.hex())
|
||||||
|
|
||||||
# #print(hex(extract_hash(SIG, CERT)))
|
# #print(hex(extract_hash(SIG, CERT)))
|
||||||
|
|
||||||
#CERT2 = "MIICnjCCAgegAwIBAgIKBAr40/DyW42YxjANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEVMBMGA1UECxMMQXBwbGUgaVBob25lMR8wHQYDVQQDExZBcHBsZSBpUGhvbmUgRGV2aWNlIENBMB4XDTIzMDQwNzE0MTUwNVoXDTI0MDQwNzE0MjAwNVowLzEtMCsGA1UEAxYkOUNCOTkzMTYtNkJERi00REYzLUFCRjUtNzcxNDU5MjFFQkY1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwsLiv8cifPdQZJQZtWvoD0WoTekSGwRj7KhxOi+AC1EUTdByWna8l7DDnixqww01FyA9pCBwottv0Xk9lOsrJrK05RXS+A7IieycejnUMdmRkgS7AsHIXOUSjtlkg2sfz5eYV9cqemTJnhdOvKtbqb9lYVN/8EehXD5JuogN+vwIDAQABo4GVMIGSMB8GA1UdIwQYMBaAFLL+ISNEhpVqedWBJo5zENinTI50MB0GA1UdDgQWBBQCl798/NQ3s5KywbJjoCjfjvWvmDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEAYKKoZIhvdjZAYKBAQCBQAwDQYJKoZIhvcNAQEFBQADgYEAfBwkujrswCn+wtu0eKCa39Cv58YC3AhK24Aj2iwXbddHaj9B9ye6HDy1BHPG21LKNGqm4X/XEtJQ3ZY/hGr4eenmtYjOI4a/oi127mrSt7uZmoib9x5S6w68eCCKkO+DD2JqDbMr2ATUhVNUxMegrzYdju8LofYqXBKzkoZ0/nk="
|
# CERT2 = "MIICnjCCAgegAwIBAgIKBAr40/DyW42YxjANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEVMBMGA1UECxMMQXBwbGUgaVBob25lMR8wHQYDVQQDExZBcHBsZSBpUGhvbmUgRGV2aWNlIENBMB4XDTIzMDQwNzE0MTUwNVoXDTI0MDQwNzE0MjAwNVowLzEtMCsGA1UEAxYkOUNCOTkzMTYtNkJERi00REYzLUFCRjUtNzcxNDU5MjFFQkY1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwsLiv8cifPdQZJQZtWvoD0WoTekSGwRj7KhxOi+AC1EUTdByWna8l7DDnixqww01FyA9pCBwottv0Xk9lOsrJrK05RXS+A7IieycejnUMdmRkgS7AsHIXOUSjtlkg2sfz5eYV9cqemTJnhdOvKtbqb9lYVN/8EehXD5JuogN+vwIDAQABo4GVMIGSMB8GA1UdIwQYMBaAFLL+ISNEhpVqedWBJo5zENinTI50MB0GA1UdDgQWBBQCl798/NQ3s5KywbJjoCjfjvWvmDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEAYKKoZIhvdjZAYKBAQCBQAwDQYJKoZIhvcNAQEFBQADgYEAfBwkujrswCn+wtu0eKCa39Cv58YC3AhK24Aj2iwXbddHaj9B9ye6HDy1BHPG21LKNGqm4X/XEtJQ3ZY/hGr4eenmtYjOI4a/oi127mrSt7uZmoib9x5S6w68eCCKkO+DD2JqDbMr2ATUhVNUxMegrzYdju8LofYqXBKzkoZ0/nk="
|
||||||
#SIG2 = "AQGOTyyRBWMxoGWqEUl5bZJXssL6bkK4acxIDOCJTUy0MMavNEwtFThZkqVpQFqjB7eXNBM6PxwPtmwHmf/5IWgIkBUthIwhGJV3pLUkhDHTVX5YjbUSF7Z4y+Y39BQ2hhYjfcz1bw2KH40MByt+bnk28Xv2XaKWYuBinH9PVajp3g=="
|
# SIG2 = "AQGOTyyRBWMxoGWqEUl5bZJXssL6bkK4acxIDOCJTUy0MMavNEwtFThZkqVpQFqjB7eXNBM6PxwPtmwHmf/5IWgIkBUthIwhGJV3pLUkhDHTVX5YjbUSF7Z4y+Y39BQ2hhYjfcz1bw2KH40MByt+bnk28Xv2XaKWYuBinH9PVajp3g=="
|
||||||
|
|
||||||
|
|
||||||
SIG3 = "AQEZs/u9Ptb8AmFpCv5XgzUsskvcleZDBxYTe5JOoshFCxpnByTwFA0mxplklHqT2rTEeF+Bu0Bo0vEPlh9KslmIoQLo6ej25bbtFN07dnHNwd84xzQzWBa4VHLQE1gNjSpcorppxpAUon/eFRu5yRxmwQVmqo+XmmxSuFCzxUaAZAPFPDna+8tvRwd0q3kuK9b0w/kuT16X1SL166fFNzmsQGcBqob9C9xX0VlYGqSd4K975gWdYsPo/kiY0ni4Q130oc6oAANr8ATN0bEeAO6/AfVM2aqHJTGlYlekBFWf8Tp8AJLUc4cm676346IEBST+l4rYGxYYStV2PEmp9cZ+"
|
SIG3 = "AQEZs/u9Ptb8AmFpCv5XgzUsskvcleZDBxYTe5JOoshFCxpnByTwFA0mxplklHqT2rTEeF+Bu0Bo0vEPlh9KslmIoQLo6ej25bbtFN07dnHNwd84xzQzWBa4VHLQE1gNjSpcorppxpAUon/eFRu5yRxmwQVmqo+XmmxSuFCzxUaAZAPFPDna+8tvRwd0q3kuK9b0w/kuT16X1SL166fFNzmsQGcBqob9C9xX0VlYGqSd4K975gWdYsPo/kiY0ni4Q130oc6oAANr8ATN0bEeAO6/AfVM2aqHJTGlYlekBFWf8Tp8AJLUc4cm676346IEBST+l4rYGxYYStV2PEmp9cZ+"
|
||||||
CERT3 = "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"
|
CERT3 = "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"
|
||||||
|
|
||||||
print(hex(extract_hash(b64decode(SIG)[2:], CERT)))
|
print(hex(extract_hash(b64decode(SIG)[2:], CERT)))
|
||||||
|
|
||||||
|
|
53
gsa.py
53
gsa.py
|
@ -1,24 +1,25 @@
|
||||||
from base64 import b64encode, b64decode
|
import getpass
|
||||||
from datetime import datetime
|
|
||||||
from random import randbytes
|
|
||||||
import uuid
|
|
||||||
import locale
|
|
||||||
import plistlib as plist
|
|
||||||
import json
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
|
import json
|
||||||
|
import locale
|
||||||
|
import plistlib as plist
|
||||||
|
import uuid
|
||||||
|
from base64 import b64decode, b64encode
|
||||||
|
from datetime import datetime
|
||||||
|
from random import randbytes
|
||||||
|
|
||||||
|
import pbkdf2
|
||||||
import requests
|
import requests
|
||||||
import srp._pysrp as srp
|
import srp._pysrp as srp
|
||||||
import pbkdf2
|
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
||||||
from cryptography.hazmat.primitives import padding
|
from cryptography.hazmat.primitives import padding
|
||||||
import getpass
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
|
|
||||||
# Constants
|
# Constants
|
||||||
DEBUG = True # Allows using a proxy for debugging (disables SSL verification)
|
DEBUG = True # Allows using a proxy for debugging (disables SSL verification)
|
||||||
# Server to use for anisette generation
|
# Server to use for anisette generation
|
||||||
#ANISETTE = "https://sign.rheaa.xyz/"
|
# ANISETTE = "https://sign.rheaa.xyz/"
|
||||||
#ANISETTE = 'http://45.132.246.138:6969/'
|
# ANISETTE = 'http://45.132.246.138:6969/'
|
||||||
ANISETTE = False
|
ANISETTE = False
|
||||||
# ANISETTE = 'https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx'
|
# ANISETTE = 'https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx'
|
||||||
# ANISETTE = "http://jkcoxson.com:2052/"
|
# ANISETTE = "http://jkcoxson.com:2052/"
|
||||||
|
@ -35,11 +36,13 @@ urllib3.disable_warnings()
|
||||||
|
|
||||||
def generate_anisette() -> dict:
|
def generate_anisette() -> dict:
|
||||||
import objc
|
import objc
|
||||||
from Foundation import NSBundle, NSClassFromString #type: ignore
|
from Foundation import NSBundle, NSClassFromString # type: ignore
|
||||||
|
|
||||||
AOSKitBundle = NSBundle.bundleWithPath_('/System/Library/PrivateFrameworks/AOSKit.framework')
|
AOSKitBundle = NSBundle.bundleWithPath_(
|
||||||
objc.loadBundleFunctions(AOSKitBundle, globals(), [("retrieveOTPHeadersForDSID", b'')]) #type: ignore
|
"/System/Library/PrivateFrameworks/AOSKit.framework"
|
||||||
util = NSClassFromString('AOSUtilities')
|
)
|
||||||
|
objc.loadBundleFunctions(AOSKitBundle, globals(), [("retrieveOTPHeadersForDSID", b"")]) # type: ignore
|
||||||
|
util = NSClassFromString("AOSUtilities")
|
||||||
|
|
||||||
h = util.retrieveOTPHeadersForDSID_("-2")
|
h = util.retrieveOTPHeadersForDSID_("-2")
|
||||||
|
|
||||||
|
@ -47,13 +50,13 @@ def generate_anisette() -> dict:
|
||||||
"X-Apple-I-MD": str(h["X-Apple-MD"]),
|
"X-Apple-I-MD": str(h["X-Apple-MD"]),
|
||||||
"X-Apple-I-MD-M": str(h["X-Apple-MD-M"]),
|
"X-Apple-I-MD-M": str(h["X-Apple-MD-M"]),
|
||||||
}
|
}
|
||||||
#h["X-Apple-I-MD"] = str(h["X-Apple-MD"])
|
# h["X-Apple-I-MD"] = str(h["X-Apple-MD"])
|
||||||
#h["X-Apple-I-MD-M"] = str(h["X-Apple-MD-M"])
|
# h["X-Apple-I-MD-M"] = str(h["X-Apple-MD-M"])
|
||||||
#print(o)
|
# print(o)
|
||||||
return o
|
return o
|
||||||
#r = requests.get(ANISETTE, verify=False if DEBUG else True, timeout=5)
|
# r = requests.get(ANISETTE, verify=False if DEBUG else True, timeout=5)
|
||||||
#r = json.loads(r.text)
|
# r = json.loads(r.text)
|
||||||
#return r
|
# return r
|
||||||
|
|
||||||
|
|
||||||
class Anisette:
|
class Anisette:
|
||||||
|
@ -304,7 +307,7 @@ def authenticated_request(parameters, anisette: Anisette) -> dict:
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
#"https://17.32.194.2/grandslam/GsService2",
|
# "https://17.32.194.2/grandslam/GsService2",
|
||||||
"https://gsa.apple.com/grandslam/GsService2",
|
"https://gsa.apple.com/grandslam/GsService2",
|
||||||
headers=headers,
|
headers=headers,
|
||||||
data=plist.dumps(body),
|
data=plist.dumps(body),
|
||||||
|
@ -460,7 +463,7 @@ def authenticate(username, password, anisette: Anisette):
|
||||||
{
|
{
|
||||||
"A2k": A,
|
"A2k": A,
|
||||||
"ps": ["s2k", "s2k_fo"],
|
"ps": ["s2k", "s2k_fo"],
|
||||||
#"ps": ["s2k"],
|
# "ps": ["s2k"],
|
||||||
"u": username,
|
"u": username,
|
||||||
"o": "init",
|
"o": "init",
|
||||||
},
|
},
|
||||||
|
@ -527,5 +530,5 @@ def authenticate(username, password, anisette: Anisette):
|
||||||
print(f"Unknown auth value {r['Status']['au']}")
|
print(f"Unknown auth value {r['Status']['au']}")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
#print("Assuming 2FA is not required")
|
# print("Assuming 2FA is not required")
|
||||||
return spd
|
return spd
|
||||||
|
|
44
ids.py
44
ids.py
|
@ -1,8 +1,9 @@
|
||||||
|
import gzip
|
||||||
import plistlib
|
import plistlib
|
||||||
import random
|
import random
|
||||||
import uuid
|
import uuid
|
||||||
import gzip
|
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
|
from collections import namedtuple
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
@ -11,7 +12,6 @@ from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes, serialization
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
||||||
from cryptography.x509.oid import NameOID
|
from cryptography.x509.oid import NameOID
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
import apns
|
import apns
|
||||||
import bags
|
import bags
|
||||||
|
@ -21,6 +21,7 @@ USER_AGENT = "com.apple.madrid-lookup [macOS,13.2.1,22D68,MacBookPro18,3]"
|
||||||
|
|
||||||
KeyPair = namedtuple("KeyPair", ["key", "cert"])
|
KeyPair = namedtuple("KeyPair", ["key", "cert"])
|
||||||
|
|
||||||
|
|
||||||
# Nonce Format:
|
# Nonce Format:
|
||||||
# 01000001876bd0a2c0e571093967fce3d7
|
# 01000001876bd0a2c0e571093967fce3d7
|
||||||
# 01 # version
|
# 01 # version
|
||||||
|
@ -33,6 +34,7 @@ def generate_nonce() -> bytes:
|
||||||
+ random.randbytes(8)
|
+ random.randbytes(8)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _create_payload(
|
def _create_payload(
|
||||||
bag_key: str,
|
bag_key: str,
|
||||||
query_string: str,
|
query_string: str,
|
||||||
|
@ -47,13 +49,13 @@ def _create_payload(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
nonce
|
nonce
|
||||||
+ len(bag_key).to_bytes(4, 'big')
|
+ len(bag_key).to_bytes(4, "big")
|
||||||
+ bag_key.encode()
|
+ bag_key.encode()
|
||||||
+ len(query_string).to_bytes(4, 'big')
|
+ len(query_string).to_bytes(4, "big")
|
||||||
+ query_string.encode()
|
+ query_string.encode()
|
||||||
+ len(payload).to_bytes(4, 'big')
|
+ len(payload).to_bytes(4, "big")
|
||||||
+ payload
|
+ payload
|
||||||
+ len(push_token).to_bytes(4, 'big')
|
+ len(push_token).to_bytes(4, "big")
|
||||||
+ push_token,
|
+ push_token,
|
||||||
nonce,
|
nonce,
|
||||||
)
|
)
|
||||||
|
@ -78,7 +80,15 @@ def sign_payload(
|
||||||
|
|
||||||
# global_key, global_cert = load_keys()
|
# global_key, global_cert = load_keys()
|
||||||
|
|
||||||
def _send_request(conn: apns.APNSConnection, bag_key: str, topic: str, body: bytes, keypair: KeyPair, username: str) -> bytes:
|
|
||||||
|
def _send_request(
|
||||||
|
conn: apns.APNSConnection,
|
||||||
|
bag_key: str,
|
||||||
|
topic: str,
|
||||||
|
body: bytes,
|
||||||
|
keypair: KeyPair,
|
||||||
|
username: str,
|
||||||
|
) -> bytes:
|
||||||
body = gzip.compress(body, mtime=0)
|
body = gzip.compress(body, mtime=0)
|
||||||
|
|
||||||
push_token = b64encode(conn.token).decode()
|
push_token = b64encode(conn.token).decode()
|
||||||
|
@ -93,12 +103,12 @@ def _send_request(conn: apns.APNSConnection, bag_key: str, topic: str, body: byt
|
||||||
"x-id-nonce": b64encode(nonce).decode(),
|
"x-id-nonce": b64encode(nonce).decode(),
|
||||||
"x-id-sig": signature,
|
"x-id-sig": signature,
|
||||||
"x-push-token": push_token,
|
"x-push-token": push_token,
|
||||||
"x-id-self-uri": 'mailto:' + username,
|
"x-id-self-uri": "mailto:" + username,
|
||||||
"User-Agent": USER_AGENT,
|
"User-Agent": USER_AGENT,
|
||||||
"x-protocol-version": "1630",
|
"x-protocol-version": "1630",
|
||||||
}
|
}
|
||||||
|
|
||||||
#print(headers)
|
# print(headers)
|
||||||
|
|
||||||
msg_id = random.randbytes(16)
|
msg_id = random.randbytes(16)
|
||||||
|
|
||||||
|
@ -114,7 +124,7 @@ def _send_request(conn: apns.APNSConnection, bag_key: str, topic: str, body: byt
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.send_message(topic, plistlib.dumps(req, fmt=plistlib.FMT_BINARY))
|
conn.send_message(topic, plistlib.dumps(req, fmt=plistlib.FMT_BINARY))
|
||||||
#resp = conn.wait_for_packet(0x0A)
|
# resp = conn.wait_for_packet(0x0A)
|
||||||
|
|
||||||
def check_response(x):
|
def check_response(x):
|
||||||
if x[0] != 0x0A:
|
if x[0] != 0x0A:
|
||||||
|
@ -123,12 +133,12 @@ def _send_request(conn: apns.APNSConnection, bag_key: str, topic: str, body: byt
|
||||||
if resp_body is None:
|
if resp_body is None:
|
||||||
return False
|
return False
|
||||||
resp_body = plistlib.loads(resp_body)
|
resp_body = plistlib.loads(resp_body)
|
||||||
return resp_body['U'] == msg_id
|
return resp_body["U"] == msg_id
|
||||||
|
|
||||||
# Lambda to check if the response is the one we want
|
# Lambda to check if the response is the one we want
|
||||||
#conn.incoming_queue.find(check_response)
|
# conn.incoming_queue.find(check_response)
|
||||||
payload = conn.incoming_queue.wait_pop_find(check_response)
|
payload = conn.incoming_queue.wait_pop_find(check_response)
|
||||||
#conn._send_ack(apns._get_field(payload[1], 4))
|
# conn._send_ack(apns._get_field(payload[1], 4))
|
||||||
resp = apns._get_field(payload[1], 3)
|
resp = apns._get_field(payload[1], 3)
|
||||||
return plistlib.loads(resp)
|
return plistlib.loads(resp)
|
||||||
|
|
||||||
|
@ -139,12 +149,14 @@ def _send_request(conn: apns.APNSConnection, bag_key: str, topic: str, body: byt
|
||||||
# keypair: a KeyPair object containing the user's private key and certificate
|
# keypair: a KeyPair object containing the user's private key and certificate
|
||||||
# topic: the IDS topic to query
|
# topic: the IDS topic to query
|
||||||
# query: a list of URIs to query
|
# query: a list of URIs to query
|
||||||
def lookup(conn: apns.APNSConnection, self: str, keypair: KeyPair, topic: str, query: list[str]) -> any:
|
def lookup(
|
||||||
|
conn: apns.APNSConnection, self: str, keypair: KeyPair, topic: str, query: list[str]
|
||||||
|
) -> any:
|
||||||
conn.filter([topic])
|
conn.filter([topic])
|
||||||
query = {"uris": query}
|
query = {"uris": query}
|
||||||
resp = _send_request(conn, "id-query", topic, plistlib.dumps(query), keypair, self)
|
resp = _send_request(conn, "id-query", topic, plistlib.dumps(query), keypair, self)
|
||||||
#resp = plistlib.loads(resp)
|
# resp = plistlib.loads(resp)
|
||||||
#print(resp)
|
# print(resp)
|
||||||
resp = gzip.decompress(resp["b"])
|
resp = gzip.decompress(resp["b"])
|
||||||
resp = plistlib.loads(resp)
|
resp = plistlib.loads(resp)
|
||||||
return resp
|
return resp
|
||||||
|
|
Loading…
Reference in a new issue