mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2025-01-09 17:33:47 +00:00
Squashed commit of the following:
commit d991a445267a40614b2da586d36509afbec3a1a7 Author: JJTech0130 <jjtech@jjtech.dev> Date: Sun Apr 23 13:41:22 2023 -0400 should be ready for publishing! commit 398a2b3aa115b2cc62eecf46ddab0dfba998c327 Author: JJTech0130 <jjtech@jjtech.dev> Date: Sun Apr 23 12:58:33 2023 -0400 yay improvements commit 75a3b80326bd551a9b5baa7bf5e578d40c991c04 Author: JJTech0130 <jjtech@jjtech.dev> Date: Sat Apr 22 16:52:16 2023 -0400 yay we can get auth certs now commit ef445c421d6ca239be7e67380a830b4dced41afb Author: JJTech0130 <jjtech@jjtech.dev> Date: Fri Apr 21 21:55:52 2023 -0400 add back the removed things
This commit is contained in:
parent
d9feada49c
commit
97fbdae4cb
1 changed files with 116 additions and 24 deletions
140
ids.py
140
ids.py
|
@ -1,15 +1,18 @@
|
||||||
import plistlib
|
import plistlib
|
||||||
import random
|
import random
|
||||||
|
import uuid
|
||||||
import zlib
|
import zlib
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
import requests
|
||||||
from cryptography.hazmat.backends import default_backend
|
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
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
|
|
||||||
import apns
|
import apns
|
||||||
import bags
|
import bags
|
||||||
|
import gsa
|
||||||
|
|
||||||
USER_AGENT = "com.apple.madrid-lookup [macOS,13.2.1,22D68,MacBookPro18,3]"
|
USER_AGENT = "com.apple.madrid-lookup [macOS,13.2.1,22D68,MacBookPro18,3]"
|
||||||
# NOTE: The push token MUST be registered with the account for self-uri!
|
# NOTE: The push token MUST be registered with the account for self-uri!
|
||||||
|
@ -84,7 +87,7 @@ def sign_payload(
|
||||||
return sig, nonce
|
return sig, nonce
|
||||||
|
|
||||||
|
|
||||||
#global_key, global_cert = load_keys()
|
# global_key, global_cert = load_keys()
|
||||||
|
|
||||||
|
|
||||||
def _send_request(conn: apns.APNSConnection, bag_key: str, body: bytes) -> bytes:
|
def _send_request(conn: apns.APNSConnection, bag_key: str, body: bytes) -> bytes:
|
||||||
|
@ -135,32 +138,121 @@ def lookup(conn: apns.APNSConnection, query: list[str]) -> any:
|
||||||
resp = plistlib.loads(resp)
|
resp = plistlib.loads(resp)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def get_auth_token(username: str, password: str) -> str:
|
|
||||||
# Get a PET from GSA
|
|
||||||
import gsa
|
|
||||||
g = gsa.authenticate(username, password, gsa.Anisette())
|
|
||||||
#print(g['t']['com.apple.gs.idms.pet'])
|
|
||||||
pet = g['t']['com.apple.gs.idms.pet']['token']
|
|
||||||
|
|
||||||
|
def _auth_token_request(username: str, password: str) -> any:
|
||||||
# Turn the PET into an auth token
|
# Turn the PET into an auth token
|
||||||
import requests
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'apple-id': username,
|
"apple-id": username,
|
||||||
'client-id': str(uuid.uuid4()),
|
"client-id": str(uuid.uuid4()),
|
||||||
'delegates': {
|
"delegates": {"com.apple.private.ids": {"protocol-version": "4"}},
|
||||||
'com.apple.private.ids': {
|
"password": password,
|
||||||
'protocol-version': '4'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'password': pet,
|
|
||||||
}
|
}
|
||||||
data = plistlib.dumps(data)
|
data = plistlib.dumps(data)
|
||||||
headers = {'Content-Type': 'text/plist'}.update(gsa.Anisette().generate_headers())
|
|
||||||
r = requests.post("https://setup.icloud.com/setup/prefpane/loginDelegates", headers=headers, auth=(username, pet), data=data, verify=False)
|
r = requests.post(
|
||||||
|
"https://setup.icloud.com/setup/prefpane/loginDelegates",
|
||||||
|
auth=(username, password),
|
||||||
|
data=data,
|
||||||
|
verify=False,
|
||||||
|
)
|
||||||
r = plistlib.loads(r.content)
|
r = plistlib.loads(r.content)
|
||||||
service_data = r['delegates']['com.apple.private.ids']['service-data']
|
return r
|
||||||
realm_user_id = service_data['realm-user-id']
|
|
||||||
auth_token = service_data['auth-token']
|
# Gets an IDS auth token for the given username and password
|
||||||
print(f"Auth token for {realm_user_id}: {auth_token}")
|
# If use_gsa is True, GSA authentication will be used, which requires anisette
|
||||||
|
# If use_gsa is False, it will use a old style 2FA code
|
||||||
|
# If factor_gen is not None, it will be called to get the 2FA code, otherwise it will be prompted
|
||||||
|
# Returns (realm user id, auth token)
|
||||||
|
def _get_auth_token(username: str, password: str, use_gsa: bool = False, factor_gen: callable = None) -> tuple[str, str]:
|
||||||
|
if use_gsa:
|
||||||
|
g = gsa.authenticate(username, password, gsa.Anisette())
|
||||||
|
pet = g["t"]["com.apple.gs.idms.pet"]["token"]
|
||||||
|
else:
|
||||||
|
# Make the request without the 2FA code to make the prompt appear
|
||||||
|
_auth_token_request(username, password)
|
||||||
|
# Now make the request with the 2FA code
|
||||||
|
if factor_gen is None:
|
||||||
|
pet = password + input("Enter 2FA code: ")
|
||||||
|
else:
|
||||||
|
pet = password + factor_gen()
|
||||||
|
r = _auth_token_request(username, pet)
|
||||||
|
#print(r)
|
||||||
|
if 'description' in r:
|
||||||
|
raise Exception(f"Error: {r['description']}")
|
||||||
|
service_data = r["delegates"]["com.apple.private.ids"]["service-data"]
|
||||||
|
realm_user_id = service_data["realm-user-id"]
|
||||||
|
auth_token = service_data["auth-token"]
|
||||||
|
# print(f"Auth token for {realm_user_id}: {auth_token}")
|
||||||
|
return realm_user_id, auth_token
|
||||||
|
|
||||||
|
from cryptography import x509
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
||||||
|
from cryptography.x509.oid import NameOID
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_csr(private_key: rsa.RSAPrivateKey) -> str:
|
||||||
|
csr = (
|
||||||
|
x509.CertificateSigningRequestBuilder()
|
||||||
|
.subject_name(
|
||||||
|
x509.Name(
|
||||||
|
[
|
||||||
|
x509.NameAttribute(
|
||||||
|
NameOID.COMMON_NAME, random.randbytes(20).hex()
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.sign(private_key, hashes.SHA256())
|
||||||
|
)
|
||||||
|
|
||||||
|
csr = csr.public_bytes(serialization.Encoding.PEM).decode("utf-8")
|
||||||
|
return (
|
||||||
|
csr.replace("-----BEGIN CERTIFICATE REQUEST-----", "")
|
||||||
|
.replace("-----END CERTIFICATE REQUEST-----", "")
|
||||||
|
.replace("\n", "")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_auth_cert(user_id, token) -> str:
|
||||||
|
private_key = rsa.generate_private_key(
|
||||||
|
public_exponent=65537, key_size=2048, backend=default_backend()
|
||||||
|
)
|
||||||
|
body = {
|
||||||
|
"authentication-data": {"auth-token": token},
|
||||||
|
"csr": b64decode(_generate_csr(private_key)),
|
||||||
|
"realm-user-id": user_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
#print(body["csr"])
|
||||||
|
|
||||||
|
body = plistlib.dumps(body)
|
||||||
|
|
||||||
|
r = requests.post(
|
||||||
|
"https://profile.ess.apple.com/WebObjects/VCProfileService.woa/wa/authenticateDS",
|
||||||
|
data=body,
|
||||||
|
headers={"x-protocol-version": "1630"},
|
||||||
|
verify=False,
|
||||||
|
)
|
||||||
|
r = plistlib.loads(r.content)
|
||||||
|
if r["status"] != 0:
|
||||||
|
raise (Exception(f"Failed to get auth cert: {r}"))
|
||||||
|
return b64encode(r["cert"]).decode()
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
import getpass
|
||||||
|
# Prompt for username
|
||||||
|
username = input("Enter iCloud username: ")
|
||||||
|
# Prompt for password
|
||||||
|
password = getpass.getpass("Enter iCloud password: ")
|
||||||
|
def factor_gen():
|
||||||
|
return input("Enter iCloud 2FA code: ")
|
||||||
|
user_id, token = _get_auth_token(username, password, use_gsa=False, factor_gen=factor_gen)
|
||||||
|
cert = _get_auth_cert(user_id, token)
|
||||||
|
print(cert)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test()
|
||||||
|
|
Loading…
Reference in a new issue