From 46b8aba33e169bf2fa57981d9ade1287fc923165 Mon Sep 17 00:00:00 2001 From: JJTech0130 Date: Fri, 7 Apr 2023 01:48:14 -0400 Subject: [PATCH] create proxy --- proxy/generate.sh | 32 +++++++++++ proxy/hosts.py | 5 ++ proxy/proxy.py | 98 ++++++++++++++++++++++++++++++++ proxy/push_certificate_chain.pem | 69 ++++++++++++++++++++++ proxy/push_key.pem | 28 +++++++++ 5 files changed, 232 insertions(+) create mode 100755 proxy/generate.sh create mode 100644 proxy/hosts.py create mode 100644 proxy/proxy.py create mode 100644 proxy/push_certificate_chain.pem create mode 100644 proxy/push_key.pem diff --git a/proxy/generate.sh b/proxy/generate.sh new file mode 100755 index 0000000..c06eb7a --- /dev/null +++ b/proxy/generate.sh @@ -0,0 +1,32 @@ +set -e +# Use brew's openssl +export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH" + +openssl req -newkey rsa:2048 -nodes -keyout root_key.pem -x509 -days 3650 -out root_certificate.pem \ + -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA" \ + -addext "basicConstraints=critical, CA:true" -addext "keyUsage=critical, digitalSignature, keyCertSign, cRLSign" + +openssl req -newkey rsa:2048 -nodes -keyout intermediate_key.pem -out intermediate_certificate.csr \ + -subj "/CN=Apple Server Authentication CA/OU=Certification Authority/O=Apple Inc./C=US" \ + -addext "basicConstraints=critical, CA:true" -addext "keyUsage=critical, keyCertSign, cRLSign" + # Need 1.2.840.113635.100.6.2.12? + +openssl x509 -req -CAkey root_key.pem -CA root_certificate.pem -days 3650 \ + -in intermediate_certificate.csr -out intermediate_certificate.pem -CAcreateserial -copy_extensions copyall + +openssl req -newkey rsa:2048 -nodes -keyout push_key.pem -out push_certificate.csr \ + -subj "/CN=courier.push.apple.com/O=Apple Inc./ST=California/C=US" \ + -addext "basicConstraints=critical, CA:false" \ + -addext "subjectAltName = DNS:courier.push.apple.com, DNS:courier2.push.apple.com" \ + -addext "keyUsage = critical, digitalSignature, keyEncipherment" \ + -addext "extendedKeyUsage = serverAuth" + +openssl x509 -req -CAkey intermediate_key.pem -CA intermediate_certificate.pem -days 365 \ + -in push_certificate.csr -out push_certificate.pem -CAcreateserial -copy_extensions copyall + +cat push_certificate.pem intermediate_certificate.pem root_certificate.pem > push_certificate_chain.pem + +# Remove the leftover files +rm intermediate_certificate.csr intermediate_certificate.pem intermediate_key.pem intermediate_certificate.srl +rm push_certificate.csr push_certificate.pem +rm root_certificate.pem root_key.pem root_certificate.srl \ No newline at end of file diff --git a/proxy/hosts.py b/proxy/hosts.py new file mode 100644 index 0000000..1d7985e --- /dev/null +++ b/proxy/hosts.py @@ -0,0 +1,5 @@ +# Print out the additions to /etc/hosts for the proxy + +for i in range(1, 50): + print(f"127.0.0.1 {i}-courier.push.apple.com") + print(f"127.0.0.1 {i}.courier.push.apple.com") \ No newline at end of file diff --git a/proxy/proxy.py b/proxy/proxy.py new file mode 100644 index 0000000..156e045 --- /dev/null +++ b/proxy/proxy.py @@ -0,0 +1,98 @@ +# TLS server to proxy APNs traffic + +import socket +import tlslite +import threading + +# APNs server to proxy traffic to +APNS_HOST = "1-courier.push.apple.com" +APNS_PORT = 5223 +ALPN = b"apns-security-v3" +#ALPN = b"apns-pack-v1" + +# Connect to the APNs server +def connect() -> tlslite.TLSConnection: + # Connect to the APNs server + sock = socket.create_connection((APNS_HOST, APNS_PORT)) + # Wrap the socket in TLS + ssock = tlslite.TLSConnection(sock) + print("Handshaking with APNs") + # Handshake with the server + ssock.handshakeClientCert(alpn=[b"apns-security-v3"]) + print("Handshaked with APNs") + + return ssock + +cert:str = None +key:str = None + +def proxy(conn1: tlslite.TLSConnection, conn2: tlslite.TLSConnection, prefix: str = ""): + while True: + # Read data from the first connection + data = conn1.read() + # If there is no data, the connection has closed + if not data: + break + + print(prefix, data) + # Write the data to the second connection + conn2.write(data) + print("Connection closed") + # Close the connections + conn1.close() + conn2.close() + +def handle(conn: socket.socket): + # Wrap the socket in TLS + s_conn = tlslite.TLSConnection(conn) + global cert, key + chain = tlslite.X509CertChain() + chain.parsePemList(cert) + print(chain) + #cert = tlslite.X509CertChain([tlslite.X509().parse(cert)]) + key_parsed = tlslite.parsePEMKey(key, private=True) + print(key_parsed) + s_conn.handshakeServer(certChain=chain, privateKey=key_parsed, reqCert=False, alpn=[ALPN]) + + print("Handling connection") + # Connect to the APNs server + apns = connect() + print("Connected to APNs") + # Proxy data between the connections + # Create a thread to proxy data from the APNs server to the client + threading.Thread(target=proxy, args=(s_conn, apns, "apsd -> APNs")).start() + # Just proxy data from the client to the APNs server in this thread + proxy(apns, s_conn, "APNs -> apsd") + +def serve(): + + # Create a socket to listen for connections + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.bind(("localhost", 5223)) + sock.listen() + + print("Listening for connections...") + + # Handshake with the client + # Read the certificate and private key from the config + with open("push_certificate_chain.pem", "r") as f: + global cert + cert = f.read() + + + # NEED TO USE OPENSSL, SEE CORETRUST CMD, MIMIC ENTRUST? OR AT LEAST SEE PUSHPROXY FOR EXTRACTION & REPLACEMENT + with open("push_key.pem", "r") as f: + global key + key = f.read() + + # Accept connections + while True: + # Accept a connection + conn, addr = sock.accept() + # Create a thread to handle the connection + #handle(conn) + thread = threading.Thread(target=handle, args=(conn,)) + thread.start() + +if __name__ == "__main__": + serve() diff --git a/proxy/push_certificate_chain.pem b/proxy/push_certificate_chain.pem new file mode 100644 index 0000000..1ddfc2c --- /dev/null +++ b/proxy/push_certificate_chain.pem @@ -0,0 +1,69 @@ +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIULoswBSnhsTUwq4AYoAdnf46gKa0wDQYJKoZIhvcNAQEL +BQAwbTEnMCUGA1UEAwweQXBwbGUgU2VydmVyIEF1dGhlbnRpY2F0aW9uIENBMSAw +HgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUg +SW5jLjELMAkGA1UEBhMCVVMwHhcNMjMwNDA3MDU0NjUwWhcNMjQwNDA2MDU0NjUw +WjBYMR8wHQYDVQQDDBZjb3VyaWVyLnB1c2guYXBwbGUuY29tMRMwEQYDVQQKDApB +cHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALMnRj3/NBqeFDE+ZYALffJRcNtn +Z0vMZLbFwAv5k9ybXKUY5OMHM74urjHgbvSz1VU73dqI0x1yTwDp+5v4bySb7TCY +jhXznMNfw6mpbSTHfucheNgtYQcFZlcgzMeDjrjFBphiuV8IekvzhwUhye5XtCC4 +9n0cNU3xPqYTwBSjmYD9Dabfn175RSJWnSiS+NzbBEopZQNB5exoWG/G+LvdIwXv +6p3xWYZsTEqYKi1F/AXkwmzKOPiCeP6Nxa7GkzWE0BjfB2YLqOxPojm6ldI1a2Je +Hi/OkzElsNVV4OmJlVa5c5B9ahfDREPsjUug9zskjIs5mowBVGUoxwt+Kn8CAwEA +AaOBsjCBrzAMBgNVHRMBAf8EAjAAMDoGA1UdEQQzMDGCFmNvdXJpZXIucHVzaC5h +cHBsZS5jb22CF2NvdXJpZXIyLnB1c2guYXBwbGUuY29tMA4GA1UdDwEB/wQEAwIF +oDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUscg6bogx1eW0qxjpHvXd +QtCE+HgwHwYDVR0jBBgwFoAULCD7ZnF0OUO5w+TLs+dO1H+LnOwwDQYJKoZIhvcN +AQELBQADggEBAH3R+ErzeiRqp57hMzIw4FUntvt4JbN4PBnLekbaD582QJb6rccn +21ZaTvVRw0rlwfWXxEZXG4iSqVe5ZUI55DqqnI5P5WU9q1h58nwJv1vBVp0a5/AQ +FczbMfG+d3Fdh88Oic47WRHSg6gghrY2Vi326FOeKPyy+DnoY1Qx1zSyF9Zh7/Gz +EA/V7hczn8io8Qyr5xapFuCtH+z5W0IvX3ConBfogbozHM/z1ZF0R4vmCl/YbWPY +qF87w6w2Ov0tfjipOYLZhssRaf4U7Ppq2K8KRCmJ7ha73otsqJDZ2on9dMnVq6b+ +I5JFOB5GYNhivmmH+pkpP7WjAhyAZu1byuo= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDwDCCAqigAwIBAgIUZZzOEefzPPJIshhkspF84IGOf60wDQYJKoZIhvcNAQEL +BQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoMCkFwcGxlIEluYy4xJjAkBgNVBAsM +HUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDDA1BcHBsZSBS +b290IENBMB4XDTIzMDQwNzA1NDY1MFoXDTMzMDQwNDA1NDY1MFowbTEnMCUGA1UE +AwweQXBwbGUgU2VydmVyIEF1dGhlbnRpY2F0aW9uIENBMSAwHgYDVQQLDBdDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UE +BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC34BqN3F/RUi2x +XFKBTbYj+6z1mqifV+j4+PpXUawAb8/jiVomDKACOz+dtoUmKtZrGfKQT/8jmA90 +atZwG/l7UD+BV4R5CTFODgJ5w1qisf+fNU1XAEiakLVRTUGO2IEGCUx3BrX+OLbV +8H1t9jqp/+bCE9mpkgiAfJHhs3/90JdKwx8Rw9rR0mvR8gpygicBw4yaKSSjgQaz +rVW4Li++Mk3dLipIAkSNf/3zne3Rjurxz87GsQ17M4zZ8AkzyvYptUoQhNkzhlo6 +iBWw0yrYIce1XLKo+2ykvT56WG0hqcupNskHXD0/KfHfoGiJPSrZrU67eTBfIYFr +X98+K/JXAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQsIPtmcXQ5Q7nD5Muz507Uf4uc7DAfBgNVHSMEGDAWgBSlIMsP +LlzUQiFAbd4WdR9DQmaSYjANBgkqhkiG9w0BAQsFAAOCAQEAduyTbo18KSykgxH0 +433x/UKxp88AvQpweG6VNrXhFkCAKwrxRPPY9/m5OasHpJuL6/hZF5LMMzKXPNlX +sFitEAoFmCkSDGCK/mItu43E2XPyfyVBg7vIi74lypmmVJEExqk4W0SSi6KSz6k4 +8H28ezyS7K2x0ESnm8H9raE4mNdwq3wLERO4dQCv+qBXdRVBf2gmjLB1t1zIOwzF +GNGl+zkZ0cXN9XOpJwoQQBlsP8J6fyMFGXCcWtTRTJQKsTtebx2rY1ydDhWPmnhX +tkSV1N1ktfbjqv8KuUaw15seHXkWjKqszXl6BbqFsdPqB13fBmigB+51PPSWhCPF +Ocu/tg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIUM/+kpUeTCAkr5w84cRYALQ7XXt0wDQYJKoZIhvcNAQEL +BQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoMCkFwcGxlIEluYy4xJjAkBgNVBAsM +HUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDDA1BcHBsZSBS +b290IENBMB4XDTIzMDQwNzA1NDY1MFoXDTMzMDQwNDA1NDY1MFowYjELMAkGA1UE +BhMCVVMxEzARBgNVBAoMCkFwcGxlIEluYy4xJjAkBgNVBAsMHUFwcGxlIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDDA1BcHBsZSBSb290IENBMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlCcyUv6XI39lXHzAkI03l7QDzVFl +Jhw7FrG6eyjh1YXUEQcDzp0v5m5BamM0gazXYfYRIpzXbg5vV9bdZrTUF2DOMh0N +xCCMuEUYy3PWOPILj3SvWiL+v3ReXgX1RT97UzOrZwSthacNGTbEUHnWAoSMbOrG +r8nX/mfpYqMNcNjwzKrooLetSOD6RobM5BdRHqFu7H/UKLDhPK/qftSsgesroT1N +l+rzgxkrNjiiYgB8KLTxYTQHMmFKDpjD0YteTtSZfZvkn03p5pnLAr33sewFuOiQ ++pCDJh0J4zJhmpH3m67LzN6MSUpX6Bgqr2TOa+7vnFocU6slg9aKN0PkhwIDAQAB +o2MwYTAdBgNVHQ4EFgQUpSDLDy5c1EIhQG3eFnUfQ0JmkmIwHwYDVR0jBBgwFoAU +pSDLDy5c1EIhQG3eFnUfQ0JmkmIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQELBQADggEBAFXtllENQx2qu3LvYkJzzKyTA+DKzjOk +j6vvqTnEPcjJRd01Iluy+EIvj5jFdJYTIeEoERRa0e0/kXY+SKMrhCe64w6U3SnO +xIagSfTXR5eBmQqL05dDOcx7Us7JBPG+QHxN8bIqVYD5lqJDUcjYCGE6svGD02Tv +VViG+ATDqPRuJcviuIjBLPlySW8L6uuU398aLZs9s/TuvRslPUASul8kxHdjjQk+ +ruwRE4vi1zGaORl9Mk7jeAEaYUHoF4v4aP9lQU/H1L0R/JIRFVBNJpoT+NY58Wah +tpfvVem4xGMi0gsi71mvLFJF+M44iAeN2NqTidVJvuvUPha/tJCNd3s= +-----END CERTIFICATE----- diff --git a/proxy/push_key.pem b/proxy/push_key.pem new file mode 100644 index 0000000..dca74cb --- /dev/null +++ b/proxy/push_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzJ0Y9/zQanhQx +PmWAC33yUXDbZ2dLzGS2xcAL+ZPcm1ylGOTjBzO+Lq4x4G70s9VVO93aiNMdck8A +6fub+G8km+0wmI4V85zDX8OpqW0kx37nIXjYLWEHBWZXIMzHg464xQaYYrlfCHpL +84cFIcnuV7QguPZ9HDVN8T6mE8AUo5mA/Q2m359e+UUiVp0okvjc2wRKKWUDQeXs +aFhvxvi73SMF7+qd8VmGbExKmCotRfwF5MJsyjj4gnj+jcWuxpM1hNAY3wdmC6js +T6I5upXSNWtiXh4vzpMxJbDVVeDpiZVWuXOQfWoXw0RD7I1LoPc7JIyLOZqMAVRl +KMcLfip/AgMBAAECggEAHygN5btLzvM99MByu32EJk+2jlmh08NUopqqhwqdBek5 +B/dX2wnGHGWW4tKyyTi7OasDLr3L5VubVL/cg6gFgDrj2ac2Uqf+09WEPC3cbuCI +995Q21us+6EbRrzMEEiXWhfdyUOmFFpvlmTgTuqs6Rf0mhpAt8pflNIHQK+/oHb1 +tHxdHTkfaRhuePZkkXSXhXQBL7CBnbTzH1y55v6k78lyuY0mppHApPnZMk3r2R8z +Q7ujt40XNAPwJwtkgIpaqoO5ltyNGY7V8RB//o3mrWCHHDG4barzEnhWF5wBqOVx +Rn/P2NYfxZ06IY6IuAxYTZj9/iCYb7oWu+ia9UJ5lQKBgQC1PqIgOXT+GahmS/EJ +WZsAroLfPVw9KgIrtNg8xtqy7lY5+WqBsgV2LIWYCLagz+rOrQgGdej0rv3EVjAH +CC9f74e301QS/CCL32wVVNrTFnm9o+W8YcT7DYGhlShkrvH1yV4hdRRFmWE0OQn/ +uDHR3w1ezkVgFEeVbpul8uXYWwKBgQD9C9RTx9EmhwG/9LYFYAHi9E3pG7jx7/HB +9YfhoHFeBHVHNKlu0AnHamvk9fLfg1v0YEmr6WKaY6jufs0Mq7cIwe5nJyk6PiSr +gwvvHXSx3rvtEWlaU+teFySxVLoyoyswSAdXnjDgCcmlyLjhrfWRSVQ0Dua3dM4Y +t7KWCurvrQKBgBREwdq6sjOsaOGvwm/aPnRQD8CpWwRYC1AZ9EivsEtsTeZD1z5T +yzqQ9guvhcTsG4UrYodebkPWwfhP7yUKLEodPl83WeKZoYYi4TJtf981Vz328z0i +7eVpeEK6rH699b8X2tgBANhbs7wkWNLpJWEkAZnFlYqOGgdDDFL9m+ibAoGBANIJ +hZ5dFy/BlCQ+/O8NN8OoQRsilarMHYF/SeBwCmmdjbMi9Rgzuko5/YC43XXFVQhM +/BmjyOKZolkECzNfPLgaMMaSbNgZSNrMFZXOf1Q8qwQmFaqSSaV51E0VJNBvO6QB +xYZmme78cNIY/8zjVhfYI/pp+/t/Cqrdn3CHc2apAoGANPGDJNbmux4EQCszW8fB +Zjv1K1wm0XRXo7UGTe56sTDyW+d6TUj2q5Jmk2+VegstpofoQKGBJJeM9+ssn6Xw +f284Ug1e+90QG9luiRIirFYGagTEHCmxZZknio4EcduPbqxl+G+5xHJLSgvZReYp +aeio1XrlmyIdivwT7bj6QqM= +-----END PRIVATE KEY-----