-
-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: download pkg #476
base: master
Are you sure you want to change the base?
feat: download pkg #476
Conversation
Signed-off-by: Pedro Tôrres <[email protected]>
@blacktop, I implemented this in the simplest way possible to get some feedback from you and hear your thoughts on some stuff.
Let me know what you think about these points. |
I'll try and run this soon. I'm still traveling etc.
|
|
|
|
|
HTTP/1.1 403 Apple WebObjects 5.8.59-b05
Server: Apple
Date: Tue, 21 May 2024 02:28:21 GMT
Content-Length: 0
Connection: keep-alive
x-responding-instance: MZFinance:541067:::
apple-timing-app: 3 ms
cache-control: no-cache, no-store
g: t
edge-control: no-store
x-apple-lokamai-no-cache: true
Set-Cookie: ns-mzf-inst=105-88-443-54-221-9531---st44; version=1; Max-Age=1800; path=/WebObjects/; domain=.apple.com; httponly
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block I think it is okay to compromise on the App Receipt for this first version. The impact of not having the receipt is that paid apps that look for it will not work. |
|
curl \
-X 'POST' \
-i 'https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate' \
-H 'X-Apple-ActionSignature: ApihkrdgFfk3AWg/9leQfJ/10TgL5bAXRnTQOf4Ua/Z8AAAB0AMAAAABAAABAMeUUZwgWi3XDfewdH6biENNaTuQg9Hi2wr0svhmIhbwCTK0ILz9aADHKY7UH0Pvi6YqB/vfLc3gk/9C4VYQXe5g0KczEZcvuQUt+jKc4JWw27n2rctwaFFeb77FTbQagYjP6+L/NKkq0eQGoWDZJ+HLjhdUcmDvTzbzCK8toZtaOB/nllKdTboyIcYP2vX0tWBd8Q/omlPLdyaOiass3fInO7NFnOAQMfJVKvlAlipk7iQD9Zln5AYP9kfHTD+ih7FSXEBOkpq8P7Eq8WPuDRGrNjebuhq0K1b3AvhqkMX69IciySxcZsMDySTDI7qfxqFxaFoFH1f9mp/1jwbo3pUAAAARRtt+jeHNsLhsz/6hhs5ANE8AAACfAYRqkNSp8/hlGy2/BaoN5Ds0hy6mAAAAhgMEKO5SiJtb/y//nFhEOAYOpWZQXG3fhaiD+tJNTEDCzPtpRtYN8T1pvkEPF1PQk6cFooPccXNLteoLuyFqw9Qsba36Qc1LoYKwfrwRNcBEKp1RggQiBLCl53bJldaJmT1d9ijDvWjhx5lCTnTUGy0ohpms35/U1Fl0sJq92SdEYrLOalqgAAAAAAAAAAAAAAAAAAAA' \
-H 'User-Agent: MacAppStore/1.3 (Macintosh; OS X 10.9.5) AppleWebKit/537.78.2' \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>appleId</key>
<string>***</string>
<key>attempt</key>
<string>2</string>
<key>guid</key>
<string>***</string>
<key>password</key>
<string>***</string>
<key>rmp</key>
<string>0</string>
<key>why</key>
<string>signIn</string>
</dict>
</plist>
' Right before making the authentication request, the MAS performed two other requests that look interesting.
<plist>
<dict>
<key>sign-sap-setup-cert</key>
<data>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</data>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>sign-sap-setup-buffer</key>
<data>
AQhKdD/RkztjkJ7mPuEMP55hQlU0+5QpqEJPEkZPVoUyCMrZqn+iLDK5D7H3pDBDG2iP
TkD+/lh4vG2Uwx1TWuhi8UvMD87W3dfzNo4TuMNPKdX1smzdyMtwz/zhT27m8A3HyDp5
uXIF7Jfl2MPlyBMrEjjKUD3jzd7gdZ8c+qOAZbI+o784fJreifNij+XSIPNojlEQPgkN
DxHViOLIK6N/2BJ64MHgIcV/8thju3ij4ua/kO5Frq77P3SHBFrdpwOa+NdebpuI8Ux5
Wv+4SKgqH4DwMnyyLzKnf/npocTzNoF7vTqq1W8oxTI/q+4daqgaItC/6DebxjV+EzCj
JOYgZrURzLez4buylvhXdJiWwnsXl3S4k26XAAAAMBqOmFtYyU89G1viAUMEDnPB0LSS
n33UQOFgslX17sPkI8m6Cn7S5cOZlwQZK1bsGKbBwbVVI1cKgH6AzyKmtmYEpYsT
</data>
</dict>
</plist>
<plist>
<dict>
<key>sign-sap-setup-buffer</key>
<data>AsC1MFA+NMqN9r93PrIBSbAAAATgC31iU1uEq08p3PuP2cISZm+qQc5nYPz+bA962LF3RuxyvgsLMc0mAGBFGkomhpFjgU4hlCZfun4n/Z/TcGk+liahJPjCn850xP51jLrFBjJIQW9oTWFYqwpVmZWaUnsbtya9mPMM/Pqz/0YyR+xMiqvvN8CVvkQ7uaJjuGI1Hlped5Z/QOHM10fhd0CeR7XPEdLHKHEz7jkw+aAb2nUSLCyDdpuqoi8wFx/7cLFlR6NMS5nz6mNCMCsfryUw4biIuAPhwPq5HamMSG/v6vTjal7rgEhBSBll2HnzusziXElifEvTEy/CJvMjh6aHtXoxoTSRBdtlTs2feX0OJnmwqf938nR9haG5LVQKdrvsq4Ky94Wj0yCkUe0Q3VFZjOYKREr9YD2KdEpD2/s6Nmdim0TYqrdf+aOBnEgXitNYsQsTVPKurrbm+OCUkCadNekY0EVhc1wOlRfI6cDhk2O2/3J8eo1c7EFMr8Yc10Sox82gvSLLzgS0Kf1juImXM+OoQWuokS+jhu8EH9w/KDBHC5kKJusQJ6E5odJPGG1QebPKCYyV/osHqKWKeqthbfLBbQWWbzqbcpt5i03UW7pHhE0AMp2x7m3/OLqru28lpQ9I1o0/ZD7Cipgtsg/YN2tZ1paO9rrHUVS1A4mmrj47TjPyJL3+qDQ3yL/PzTZqI90HvznQKxnby6gO8vMERNjmDssIPYi4/rk8hJWxyXw8qe6AvfRhXievIZWtYajhuH1oN/HSt1o71LT1sqg48AEl5f1xJuaUWzb3EVlb/5BVMX4dYmufOXfZqScjckIkXStx5XgNHbibcCRMnDqgYDWT+ydSf0qC7FAVSbqvZSvVir6mdRn2HZ33Rc9GjyBaKUEjnnB2dF4tjfRDi/NxenCtqopJ95cBozcODFT0/0ae6oDKZHghacA+51j4zbZ5ptiIWjb3dvuMBUpz0o9AVufbZkhGsyzCeUu56vebMbwKxrhMAYvfWq1d4XRps8VhWfwsS6DKhJO53lgoDIVvVbzmoxS2OGVCMwyN6XBBqP13bvtsYaHytICkqsQpKJNbVishfW2OTytDDv9pDlrlkz/3KivVQffcjYiUsgcT1YmFiFqTMqDFljetMFUK9T+pQfldk7noLwEzFFjuwbDskL5637C+GzaLQRhdkotsDrlTa6v9GouvMz3+/GXj0K4N2LHWTZHxDdsnAVvcJBl4zPC6WJvhePfwCmy+Lvdt6MJRnR9LLihsbHeu934vnJZ0jdKxrY8ZAFuewL1CKzN54hxyIfFtPQiPn8bhPz9PVPWitSr7hl68999p2TWFtPO42esOR4LbxBIseLY/eFMjmvpzEGfjAZegsyh+yTzrux7nYmdKRpDuSVDiBHnBCjn071VVbVt8zFR75gaBY+i01yvnpxClpBVTiBE6fpLPxi2xZ+z7m4b3py21hXhWs5ZrVlg1DcNN9fdLSehY4yWSrhxe1M0/+ZGFjbovttW+9BgC+WykpLUkSzHN3qJnHTpoFyp8Xq9AxE8ZmKngh3uEtTRVSNYkx+6A93MHu+y5vFgRyS7xAdy8FXiuizHengSvo3FTIUQbDA43jjZQvX5c1+v4dV7var/zqjrKsQLWGHQ5/DA3jMe4e5apJ4wG5yvK4VLeYH423vyVNZaUF8ahTMQ+AYRqkNSp8/hlGy2/BaoN5Ds0hy6mAAAAhgMEKO5SiJtb/y//nFhEOAYOpWZQXG3fhaiD+tJNTEDCzPtpRtYN8T1pvkEPF1PQk6cFooPccXNLteoLuyFqw9Qsba36Qc1LoYKwfrwRNcBEKp1RggQiBLCl53bJldaJmT1d9ijDvWjhx5lCTnTUGy0ohpms35/U1Fl0sJq92SdEYrLOalqg</data>
</dict>
</plist> I'm not entirely sure yet, but it looks like FairPlay may be not involved and we might be able to implement the signing algorithm. |
|
Not sure if this is too heavy handed (and I've not researched FairPlay) but I do use the unicorn emulator in another cmd. If we are only calling a few functions in FP maybe we could emulate it? |
I thought a lot about emulation this past week, but I didn't know about Unicorn. It's a really amazing tool. But to use it, we first need to reverse some client interfacing with the CoreFP library so we can limit the scope of the emulation. What I have implemented in Objective-C is mostly calls to private frameworks methods that interface with the The only exception to this is the PKG decryption tool I made. I load the But CoreFP is heavily obfuscated and so are the parts of Based on what I've seen, most people just gave up understanding it and just use some binary that already communicates with CoreFP to perform the desired action. For |
For macOS, I just built this: https://github.com/t0rr3sp3dr0/SAPSigner. I was able to successfully authenticate as the App Store after using it to sign the request body and placing the signature in the I still need to verify whether this header is also necessary for the |
I just finish my tests and the That's all you need to do: import requests
s = requests.session()
s.headers['Content-Type'] = 'application/x-apple-plist'
s.headers['User-Agent'] = 'MacAppStore/1.3 (Macintosh; OS X 10.9.5) AppleWebKit/537.78.2'
r = s.post('https://p54-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate', data=b'<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>appleId</key><string>***</string><key>attempt</key><string>1</string><key>guid</key><string>***</string><key>password</key><string>***</string><key>rmp</key><string>0</string><key>why</key><string>signIn</string></dict></plist>', headers={'X-Apple-ActionSignature': '***'})
print(r.text)
r = s.post('https://p54-buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct', data=b'<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>guid</key><string>***</string><key>price</key><string>0</string><key>pricingParameters</key><string>STDRDL</string><key>productType</key><string>C</string><key>salableAdamId</key><string>682658836</string></dict></plist>', headers={'X-Dsid': '***'})
print(r.text) |
I forgot to mention, the server uses the macOS version from the User-Agent to determine if the app is compatible or not before proceeding. If the OS version is not compatible but there is an older version of the app that is compatible with your OS, it expects you resend the requests with the <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plist version="1.0">
<dict>
<key>pings</key>
<array></array>
<key>metrics</key>
<dict>
<key>dialogId</key><string>MZCommerce.OsRequiresEarlierAppVersion.OSX</string>
<key>message</key><string>Download an older version</string>
<key>options</key>
<array>
<string>Download</string>
<string>Cancel</string>
</array>
<key>subjectId</key><string>adamId:682658836</string>
<key>actionUrl</key><string>p54-buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct</string>
<key>asnState</key><integer>0</integer>
<key>mtTopic</key><string>xp_its_main</string>
<key>eventType</key><string>dialog</string>
</dict>
<key>failureType</key><string></string>
<key>customerMessage</key><string>Download an older version of GarageBand?</string>
<key>m-allowed</key><false/>
<key>dialog</key>
<dict><key>m-allowed</key><false/>
<key>isFree</key><true/>
<key>message</key><string>Download an older version of GarageBand?</string>
<key>explanation</key><string>The current version requires OS X 13.5 or later, but you can download the last compatible version.</string>
<key>defaultButton</key><string>ok</string>
<key>okButtonString</key><string>Download</string>
<key>okButtonAction</key><dict><key>kind</key><string>Buy</string>
<key>buyParams</key><string>pricingParameters=STDRDL&salableAdamId=682658836&guid=***&appExtVrsId=813573506&price=0&productType=C</string>
<key>itemName</key><string>null</string>
</dict>
<key>cancelButtonString</key><string>Cancel</string>
<key>initialCheckboxValue</key><true/></dict>
<key>cancel-purchase-batch</key><true/>
</dict>
</plist> If has never been a version of the app compatible with your system, this is what you get: <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plist version="1.0">
<dict>
<key>pings</key>
<array></array>
<key>metrics</key>
<dict>
<key>dialogId</key><string>MZCommerce.ProductRequiresLaterStoreVersion</string>
<key>message</key><string>This application requires</string>
<key>options</key>
<array>
<string>OK</string>
</array>
<key>subjectId</key><string>adamId:682658836</string>
<key>actionUrl</key><string>p54-buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct</string>
<key>asnState</key><integer>0</integer>
<key>mtTopic</key><string>xp_its_main</string>
<key>eventType</key><string>dialog</string>
</dict>
<key>failureType</key><string></string>
<key>customerMessage</key><string>This application requires macOS 13.5 or later.</string>
<key>m-allowed</key><false/>
<key>dialog</key>
<dict><key>m-allowed</key><false/>
<key>isFree</key><true/>
<key>message</key><string>This application requires macOS 13.5 or later.</string>
<key>explanation</key><string>You must update to macOS 13.5 in order to download and use this application.</string>
<key>defaultButton</key><string>ok</string>
<key>okButtonString</key><string>OK</string>
<key>initialCheckboxValue</key><true/></dict>
<key>cancel-purchase-batch</key><true/>
</dict>
</plist> I set the version of macOS to INT32_MAX and I was able to download any app I wanted. Even apps that are no longer supported by the most recent versions of macOS, like iPhoto. If we set the version to any number larger than 2147483647, the server returns 500. s.headers['User-Agent'] = 'MacAppStore/1.3 (Macintosh; OS X 2147483647) AppleWebKit/537.78.2' |
@t0rr3sp3dr0 do you use Discord at all? |
@blacktop, I do! We can chat over there if you want. I'm @t0rr3sp3dr0 there and pretty much everywhere else 😂 |
Btw, I just finished reversing the client-side interface of CoreFP. Based on the logs I found, this component seems to be called Mescal Client and is present on applications that talk with CoreFP. I have reimplemented the SAPSigner in pure C with what I've learned: https://github.com/t0rr3sp3dr0/SAPSigner/blob/master/Sources/SAPSignerAlt/main.c. But it still relies on CommerceKit (from OS X Mavericks) or any library containing the Mescal Client. Newer versions of CommerceKit don't include the Mescal Client, but I was able to use a copy of the library from Mavericks on Sonoma without a problem, indicating that the CoreFP interface is super stable and hasn't changed since 10.9. On macOS Sonoma, I found the Mescal Client on the Osprey Framework, but its symbols are marked as local-only and we would need to use dlopen and dlsym to access those functions. This C implementation will help a lot with the emulation idea, as we no longer need to worry about the Objective-C runtime and all async stuff that happens there. But I still would like to understand the interface of CoreFP library and completely bypass the Mescal Client. |
I think this is related to the same reason the ipa downloads stoped working? |
it might be nice to get the PR refactored to support both and merged? Would you have time to support that? |
I wouldn't mind this being macOS only and using dlopen. I think you might have solved your original goal another way by now? lmk if I'm wrong |
This patch implements support for downloading PKGs from the Mac App Store.