#include "appleauth/iauth.h" #include "tier2/fileformats/plist.h" #include "http/http.h" #include "openssl/srp.h" #include "openssl/sha.h" #include "tier0/rand.h" IHTTPClientManager *g_pHttpClientMgr = NULL; // autogenerated #define APPLE_LOCAL_USER "e2e70285da39596ef06153b9c4e1e5dc8d2f983bc5cd63f5b1e292207060d931" #define APPLE_HTTP_HEADER \ { \ {"X-Apple-I-Client-Time", "2026-1-9T12:00:00"}, \ {"X-Apple-Locale", "en_US"}, \ {"X-Apple-I-TimeZone", "Europe/Kyiv"}, \ {"X-Mme-Client-Info", " "}, \ {"User-Agent", "akd/1.0 CFNetwork/808.1.4"}, \ {"X-Apple-I-MD-LU", APPLE_LOCAL_USER}, \ {"X-Apple-I-MD-M", "0"}, \ {"X-Apple-I-SRL-NO", "0"}, \ {"X-Mme-Device-Id", "0"}, \ {"Content-Type", "text/x-xml-plist"}, \ {"Accept", "*/*"}, \ }; #define N2048 "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73" #define G2048 "2" class CAppleAuth: public IAppleAuth { public: virtual void Init() override; virtual void Shutdown() override; virtual void LaunchLoginDaemon() override; virtual EAppleAuthDaemonStatus GetStatus() override; virtual EAppleAuthStatus SubmitLoginData( const char *szEmail, const char *szPassword ) override; virtual EAppleAuthStatus Submit2FA( const char *szCode ) override; CUtlString FetchADIPB(); void FetchHeaders( CUtlString szAdiPb ); IHTTPClient *m_pANIClient; IHTTPClient *m_pGrandSlamClient; CUtlString m_szProvisionStart = "/grandslam/MidService/startMachineProvisioning"; CUtlString m_szProvisionFinish = "/grandslam/MidService/finishMachineProvisioning"; IJSONObject *pHeader; CUtlString m_szAppleIMD; CUtlString m_szAppleIMDM; CUtlString m_szAppleIMDRINFO; }; CUtlString CAppleAuth::FetchADIPB() { CUtlString szProvisionExpectedInputRaw = NULL; IJSONObject *pObject = NULL; IJSONObject *pPlistObject = NULL; CUtlString szProvisionExpectedInput = NULL; CUtlString szAdiPb = NULL; m_pANIClient = g_pHttpClientMgr->Connect("ani.sidestore.io", true, NULL); { HTTPHeaderParam_t params[] = APPLE_HTTP_HEADER; HTTPHeader_t header = { sizeof(params)/sizeof(HTTPHeaderParam_t), params, }; m_pGrandSlamClient->Get("/grandslam/GsService2/lookup", &header); HTTPResponse_t r = m_pGrandSlamClient->GetResponse(); if ( r.m_uCode != 200 ) { g_pHttpClientMgr->Disconnect(m_pANIClient); return NULL; } } if ( !m_pANIClient->WebSocket_Connect("/v3/provisioning_session") ) Plat_FatalErrorFunc("Failed to init AppleAuth websocket\n"); // Getting adipb while ( ( szProvisionExpectedInputRaw = m_pANIClient->WebSocket_RecvText() ) != NULL ) { pObject = JSONManager()->ReadString(szProvisionExpectedInputRaw); szProvisionExpectedInput = pObject->GetValue("result")->GetStringValue(); V_printf("%s\n",szProvisionExpectedInput.GetString()); if ( szProvisionExpectedInput == "GiveIdentifier" ) { m_pANIClient->WebSocket_SendText("{\"identifier\": \"" APPLE_LOCAL_USER "\"}"); continue; } if ( szProvisionExpectedInput == "GiveStartProvisioningData" ) { const char *plist = "\n" "\n" "\n" "\n" "\tHeader\n" "\t\n" "\tRequest\n" "\t\n" "\n" "\n"; HTTPHeaderParam_t params[] = APPLE_HTTP_HEADER; HTTPHeader_t header = { sizeof(params)/sizeof(HTTPHeaderParam_t), params, }; m_pGrandSlamClient->Post(m_szProvisionStart, &header, V_strlen(plist), plist); HTTPResponse_t r = m_pGrandSlamClient->GetResponse(); if ( r.m_uCode != 200 ) { g_pHttpClientMgr->Disconnect(m_pANIClient); return NULL; } IJSONObject *pObject = PropertyListManager()->ReadString(r.m_message); CUtlString spim = pObject->GetValue("Response")->GetObject()->GetValue("spim")->GetStringValue(); m_pANIClient->WebSocket_SendText(CUtlString("{\"spim\": \"%s\"}", spim.GetString())); continue; } if ( szProvisionExpectedInput == "GiveEndProvisioningData" ) { CUtlString cpim = pObject->GetValue("cpim")->GetStringValue(); CUtlString plist = CUtlString( "\n" "\n" "\n" "\n" "\tHeader\n" "\t\n" "\tRequest\n" "\t\n" "\tcpim\n" "\t%s\n" "\t\n" "\n" "\n", cpim.GetString()); HTTPHeaderParam_t params[] = APPLE_HTTP_HEADER; HTTPHeader_t header = { sizeof(params)/sizeof(HTTPHeaderParam_t), params, }; m_pGrandSlamClient->Post(m_szProvisionFinish, &header, V_strlen(plist), plist); HTTPResponse_t r = m_pGrandSlamClient->GetResponse(); if ( r.m_uCode != 200 ) { g_pHttpClientMgr->Disconnect(m_pANIClient); return NULL; } IJSONObject *pObject = PropertyListManager()->ReadString(r.m_message); CUtlString tk = pObject->GetValue("Response")->GetObject()->GetValue("tk")->GetStringValue(); CUtlString ptm = pObject->GetValue("Response")->GetObject()->GetValue("ptm")->GetStringValue(); V_printf("%s\n",CUtlString("{\"tk\": \"%s\", \"ptm\": \"%s\"}", tk.GetString(), ptm.GetString()).GetString()); m_pANIClient->WebSocket_SendText(CUtlString("{\"tk\": \"%s\", \"ptm\": \"%s\"}", tk.GetString(), ptm.GetString())); continue; } if ( szProvisionExpectedInput == "ProvisioningSuccess" ) { szAdiPb = pObject->GetValue("adi_pb")->GetStringValue(); g_pHttpClientMgr->Disconnect(m_pANIClient); break; } if ( szProvisionExpectedInput == "Timeout" ) { break; } g_pHttpClientMgr->Disconnect(m_pANIClient); return NULL; } g_pHttpClientMgr->Disconnect(m_pANIClient); return szAdiPb; } void CAppleAuth::FetchHeaders( CUtlString szAdiPb ) { // Get header HTTPHeaderParam_t params[] = { "Content-Type", "application/json", }; HTTPHeader_t header = { sizeof(params)/sizeof(HTTPHeaderParam_t), params, }; m_pANIClient = g_pHttpClientMgr->Connect("ani.sidestore.io", true, NULL); CUtlString szPostData = CUtlString("{\"identifier\": \"" APPLE_LOCAL_USER "\", \"adi_pb\": \"%s\"}", szAdiPb.GetString()); V_printf("%s\n",szPostData.GetString()); m_pANIClient->Post("/v3/get_headers", &header, V_strlen(szPostData), szPostData); HTTPResponse_t r = m_pANIClient->GetResponse(); V_printf("%i\n",r.m_uCode); if ( r.m_uCode == 200 ) { V_printf("%s\n",r.m_message.GetMemory()); pHeader = JSONManager()->ReadString(r.m_message); m_szAppleIMD = pHeader->GetValue("X-Apple-I-MD")->GetStringValue(); m_szAppleIMDM = pHeader->GetValue("X-Apple-I-MD-M")->GetStringValue(); m_szAppleIMDRINFO = pHeader->GetValue("X-Apple-I-MD-RINFO")->GetStringValue(); JSONManager()->FreeObject(pHeader); } g_pHttpClientMgr->Disconnect(m_pANIClient); } void CAppleAuth::Init() { CreateInterfaceFn fnHttpFactory = Sys_GetFactory("funnyhttp"); g_pHttpClientMgr = (IHTTPClientManager*)fnHttpFactory(HTTP_CLIENT_INTERFACE_VERSION, NULL); m_pGrandSlamClient = g_pHttpClientMgr->Connect("gsa.apple.com", true, NULL); CUtlString szAdiPb = FetchADIPB(); FetchHeaders(szAdiPb); } void CAppleAuth::Shutdown() { } void CAppleAuth::LaunchLoginDaemon() { } EAppleAuthDaemonStatus CAppleAuth::GetStatus() { return APPLE_AUTH_DAEMON_NOT_LOGGED_IN; } EAppleAuthStatus CAppleAuth::SubmitLoginData( const char *szEmail, const char *szPassword ) { const char *pszUser = szEmail; const char *pszPass = szPassword; BIGNUM* pN = BN_new(); BIGNUM* pG = BN_new(); BIGNUM* pa = BN_new(); BIGNUM* pA = BN_new(); BN_CTX *pbnCtx = BN_CTX_new(); /* CUtlBuffer bN; CUtlBuffer bG; */ SHA256_CTX pSha; unsigned char szHash[SHA256_DIGEST_LENGTH]; BN_hex2bn(&pN, N2048); BN_hex2bn(&pG, G2048); /* bN = CUtlBuffer(BN_num_bytes(pN)); bG = CUtlBuffer(BN_num_bytes(pG)); BN_bn2bin(pN, bN.GetMemory()); SHA256_Init(&pSha); SHA256_Update(&pSha, bN.GetMemory(), bN.GetSize()); SHA256_Update(&pSha, bG.GetMemory(), bG.GetSize()); SHA256_Final(szHash, &pSha); */ BN_rand(pa, 256, 0, 0); BN_set_flags(pa, BN_FLG_CONSTTIME); BN_mod_exp(pA, pG, pa, pN, pbnCtx); char *pszA = BN_bn2hex(pA); CUtlString plist = CUtlString( "\n" "\n" "\n" "\n" "\tHeader\n" "\t\n" "\tVersion\n" "\t1.0.1\n" "\t\n" "\tRequest\n" "\t\n" "\tA2k\n" "\t%s\n" "\tps\n" "\ts2ks2k_fo\n" "\tu\n" "\t%s\n" "\to\n" "\tinit\n" "\tcpd\n" "\t\n" "\tX-Apple-I-Client-Time\n" "\t2026-1-9T12:00:00Z\n" "\tX-Apple-I-MD\n" "\t%s\n" "\tX-Apple-I-MD_LU\n" "\t" APPLE_LOCAL_USER "\n" "\tX-Apple-I-MD-M\n" "\t%s\n" "\tX-Apple-I-MD-RINFO\n" "\t%s\n" "\tX-Mme-Client-Info\n" "\t<MacBookPro13,2> <macOS;13.1;22C65> <com.apple.AuthKit/1 (com.apple.dt.Xcode/3594.4.19)>\n" "\tX-Apple-I-SRL-NO\n" "\t0\n" "\tbootstrap\n" "\t\n" "\tcapp\n" "\tXcode\n" "\tdc\n" "\t#9d9da0\n" "\ticscrec\n" "\t\n" "\tloc\n" "\ten_US\n" "\tpbe\n" "\t\n" "\tprkgen\n" "\t\n" "\tsvct\n" "\tiCloud\n" "\t\n" "\t\n" "\n" "\n", pszA, szEmail, m_szAppleIMD.GetString(), m_szAppleIMDM.GetString(), m_szAppleIMDRINFO.GetString()); HTTPHeaderParam_t params[] = { {"Content-Type", "text/x-xml-plist"}, {"Accept", "*/*"}, {"User-Agent", "akd/1.0 CFNetwork/808.1.4"}, \ {"X-Mme-Client-Info", " "}, \ }; HTTPHeader_t header = { sizeof(params)/sizeof(HTTPHeaderParam_t), params, }; V_printf("%s\n",plist.GetString()); m_pGrandSlamClient->Post("/grandslam/GsService2", &header, plist.GetLenght(), plist); HTTPResponse_t stResponse = m_pGrandSlamClient->GetResponse(); V_printf("%i %i\n", stResponse.m_uCode, stResponse.m_bIsComplete); if (stResponse.m_uCode == 200) { V_printf("%s\n",stResponse.m_message.GetMemory()); } g_pHttpClientMgr->Disconnect(m_pGrandSlamClient); OPENSSL_free(pszA); return APPLE_AUTH_SUCCESS; } EAppleAuthStatus CAppleAuth::Submit2FA( const char *szCode ) { } static CAppleAuth s_appleAuth; EXPOSE_INTERFACE_GLOBALVAR(CAppleAuth, IAppleAuth, APPLE_AUTH_INTERFACE_VERSION, s_appleAuth);