python-bna icon indicating copy to clipboard operation
python-bna copied to clipboard

bna restore: bna.http.HTTPError: mobile-service.blizzard.com returned status 502

Open mx03 opened this issue 1 year ago • 99 comments

Is this project still supported? Not sure how much you can do if the battlenet endpoints got changed, but maybe someone has an idea.

Traceback (most recent call last):
  File "/home/maximilian/.local/bin/bna", line 8, in <module>
    sys.exit(main())
  File "/home/maximilian/.local/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/home/maximilian/.local/lib/python3.8/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/home/maximilian/.local/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/maximilian/.local/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/maximilian/.local/lib/python3.8/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/home/maximilian/.local/lib/python3.8/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/maximilian/.local/lib/python3.8/site-packages/bna/cli.py", line 222, in restore
    secret = bna.restore(serial, restore_code)
  File "/home/maximilian/.local/lib/python3.8/site-packages/bna/http.py", line 129, in restore
    challenge = client.initiate_paper_restore(serial)
  File "/home/maximilian/.local/lib/python3.8/site-packages/bna/http.py", line 48, in initiate_paper_restore
    response = self.post("/enrollment/initiatePaperRestore.htm", data=serial)
  File "/home/maximilian/.local/lib/python3.8/site-packages/bna/http.py", line 32, in post
    raise HTTPError(
bna.http.HTTPError: mobile-service.blizzard.com returned status 502

mx03 avatar Jul 18 '23 07:07 mx03

If you want to fix it and submit a patch I will review and merge it, but in general I don't have a way of actively maintaining it.

jleclanche avatar Jul 18 '23 10:07 jleclanche

I am guessing the overall method for api is different now so not working... Its been 10 years since I worked with python, so I'll just use the ios authenticator.

J4bber avatar Jul 20 '23 16:07 J4bber

Yes as blizzard deprecated the battlenet authenticator and replaced it with battlenet messenger with authenticator included, they changed probably the api endpoints. I already looked a little bit how the new works but didn't find something.

mx03 avatar Jul 20 '23 17:07 mx03

I tracked the dns requests and found the domain authenticator-rest-api.bnet-identity.blizzard.net that has an swagger ui: https://authenticator-rest-api.bnet-identity.blizzard.net/swagger-ui/

(Dont know why blizz has that documentation online because i don't think they want third party implementations)

https://authenticator-rest-api.bnet-identity.blizzard.net/v1/authenticator/device deviceSecret is the secret as hex.

Biggest issue is that you need an oauth 2.0 with a specific scope that probably not avail with this way: https://develop.battle.net/documentation/guides/using-oauth

mx03 avatar Jul 23 '23 19:07 mx03

ix it possible to get that scope by snooping in the app binary or something?

alvinpeters avatar Jul 26 '23 11:07 alvinpeters

The scope is auth.authenticator (you can see it on the swagger page if you press the authorize button), i dont have much time at the moment, so i don't look further into the oauth auth with this scope.

mx03 avatar Jul 27 '23 06:07 mx03

Now this gets my interest. I'm writing a simple Rust binary for this. (i hate installing fuckloads of libraries lol) Hopefully done this weekend if I don't hit any roadblocks.

alvinpeters avatar Jul 27 '23 10:07 alvinpeters

Yup. Turns out you can't just ask for auth.authenticator scope and be granted that. I tried authenticating with various scopes plus that scope but turns out directly asking for auth.authenticator as some random app is just impossible, it gets silently blocked. I tried entering the access token into the authenticator swagger, no joy saying "must-revalidate" after trying out one of the urls.

This is what I got from redirecting to the swagger

auth error{"error":"invalid_client","error_description":"Unauthorized grant type: implicit","state":"random state token lol"

We need another approach for this. Maybe even some gray area methods by trying to get the Battle.net app info. For now, I can try sniffing the REST GETs and POSTs of the app with wireshark androiddump and see if there's something that can be useful.

alvinpeters avatar Jul 30 '23 00:07 alvinpeters

The api works with the extracted devicekey from the battlenet app. So yes thats the way it should work.

mx03 avatar Jul 30 '23 07:07 mx03

The api works with the extracted devicekey from the battlenet app. So yes thats the way it should work.

@mx03 how do you extract the devicekey? and also we need a way to either distribute the key (kinda grey area legal) or provide a way for people to reliably extract the device key.

Once done, I can finish my implementation within a few days.

alvinpeters avatar Jul 30 '23 08:07 alvinpeters

Sorry i meant the client id, its stored on a android device in this file under com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_CLIENT_ID and is custom for every user /data/data/com.blizzard.messenger/shared_prefs/com.blizzard.messenger.authenticator_preferences.xml

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="com.blizzard.messenger.AUTHENTICATOR_CREDENTIALS_ENCRYPTION_TYPE">AES</string>
    <boolean name="com.blizzard.messenger.AUTHENTICATOR_SETUP_POSTPONE_LOGIN" value="false" />
    <string name="com.blizzard.messenger.AUTHENTICATOR_RESTORE_CODE">Y</string>
    <string name="com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_CLIENT_ID">C</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_DEVICE_SECRET">X </string>
    <string name="com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_HOST_URL">oauth.battle.net</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_BGS_REGION_CODE">EU</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_SERIAL">R</string>
    <long name="com.blizzard.messenger.AUTHENTICATOR_SERVER_TIME_DIFF" value="0" />
</map>

mx03 avatar Jul 30 '23 08:07 mx03

LOL IT FUCKING WORKED HAHAHAHAHA THANK YOU SO MUCH @mx03

Sadly that forces everyone to download the app and login once before getting the client ID. Are you actually sure about the client ID being per-user? I'm gonna test with different accounts later if you haven't tried that. And would non-rooted users be able to access that directory?

For those waiting for an app to automate these steps. (only slightly due to the way of getting the client ID/device secret) This is what I did:

  1. Download the Battle.net Messenger
  2. Login to the app
  3. (This step might need root) Get the secret:
  • From the app
    1. Press "Enable now" when prompted to enable the authenticator
    2. Go to /data/data/com.blizzard.messenger/shared_prefs/com.blizzard.messenger.authenticator_preferences.xml
    3. Either copy the file to the PC or open it in the phone
    4. Save the content of the string tag named "com.blizzard.messenger.AUTHENTICATOR_DEVICE_SECRET"
  • From the REST API
    1. Go to /data/data/com.blizzard.messenger/shared_prefs/com.blizzard.messenger.authenticator_preferences.xml
    2. Either copy the file to the PC or open it in the phone
    3. Copy the content of the string tag named com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_CLIENT_ID
    4. Go to https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html

    You can skip all the steps above with this client ID (as long as this doesn't get changed lol): baedda12fe054e4abdfc3ad7bdea970a

    1. Make sure to tick the 'auth.authenticator' scope then click "Authorize," paste the acquired client ID to the client ID input then click "Authorize."
    2. Login if you are not logged in already. Either way, you should be redirected back and see the client ID input as just client_id: ******
    3. Click the "POST: Click and add a brand new authenticator..." header, click "Try it out," then "Execute."
    4. The response should be "200: OK" with a JSON output providing your device secret
    5. Save the value of deviceSecret and might as well save serial and restoreCode for backup
  1. Convert the device secret from hex to base32. On Linux and maybe macOS, this can be done with echo "PASTEYOURDEVICESECRETHERE" | xxd -r -p | base32
  2. Put the converted secret and set the digits to 8 on your authenticator of your choosing. I use Aegis and it works.

alvinpeters avatar Jul 30 '23 09:07 alvinpeters

Maybe there is an API that allows us to grab a custom per user client ID like the app but that's highly improbable.

alvinpeters avatar Jul 30 '23 13:07 alvinpeters

As the app has certificate pinning i haven't the time for look into more details, but it shouldn't be hard to make an oauth auth like the app and get the client id.

mx03 avatar Jul 30 '23 16:07 mx03

@mx03 does your client id start and end with 'b' and 'a' respectively? Because if so, the client ID is the same everywhere. I tried with two accounts and it is the same. Just wondering if it's also the same on all devices.

Just wondering because maybe we can just distribute the client ID since it's hard/impossible for people without rooted phones to get the client ID anyways.

alvinpeters avatar Jul 31 '23 12:07 alvinpeters

@mx03 does your client id start and end with 'b' and 'a' respectively? Because if so, the client ID is the same everywhere. I tried with two accounts and it is the same. Just wondering if it's also the same on all devices.

Just wondering because maybe we can just distribute the client ID since it's hard/impossible for people without rooted phones to get the client ID anyways.

Yes start with b and ending with a. So it seems it is the same. Just thought about oauth and yes the client id is no secret https://www.oauth.com/oauth2-servers/client-registration/client-id-secret/ . Just half year ago i implemented oauth myself just forget the naming and the use of the clientid.

mx03 avatar Jul 31 '23 14:07 mx03

Reckoned I'm backed into a corner on this one. The localhost redirects are not whitelisted for this client ID and only allows redirect to the Swagger UI (https://authenticator-rest-api.bnet-identity.blizzard.net/swagger-ui/oauth2-redirect.html) and probably the localhost address pointing to the messenger. I'm wondering how do Android apps implement OAuth2 with just a client ID then redirect to the device's web viewer/bowser? Snipping full HTTPS URLs is impossible so the only way to figure this out is by trying to reverse engineer it lol

So ye, it's kinda pointless even to make an app for this if you can't ask for an oauth2 token from the device with the client ID provided. I'm putting the client ID of the Battle.net Messenger baedda12fe054e4abdfc3ad7bdea970a so everyone can make use of it above

Screenshot_20230801-085240.png

alvinpeters avatar Jul 31 '23 23:07 alvinpeters

Yes this way probably only works with an electron app that can fetch the token from the returning url.

The android app itself does this login request https://account.battle.net/login?sdkVersion=masdk/7.2.1&code_verifier=[XXX]&deviceId=[XXX]&clientVersion=1.19.2.7&continuation-type=NATIVE_HANDOFF&flowTrackingId=[XXX]&app=BSAp&ca&ref=blizzard-social%3A%2F%2Flocalhost%3A0%2F but that url blizzard-social://localhost:0/ still dont work directly with the authenticator-rest api.

The response url is blizzard-social://localhost:0/?ST=[XXX]&STT=enc&accountId=[XXX]&flowTrackingId=[XXX]&flow_type=hard_account_login.

mx03 avatar Aug 01 '23 14:08 mx03

@striczkof Think the clientid might have changed, as I just tried this and get back 403: Forbidden..... The request requires higher privileges than provided by the access token. Gonna hunt down an old Android phone that's rooted so I can get the /data file to check the new clientid

lightmaster avatar Aug 03 '23 23:08 lightmaster

@striczkof Think the clientid might have changed, as I just tried this and get back 403: Forbidden..... The request requires higher privileges than provided by the access token. Gonna hunt down an old Android phone that's rooted so I can get the /data file to check the new clientid

@lightmaster Did you tick the "auth.authenticator" scope before trying to login? think I might have forgotten to add that in instructions.

alvinpeters avatar Aug 03 '23 23:08 alvinpeters

@lightmaster Oh ye I did forget 💀

alvinpeters avatar Aug 03 '23 23:08 alvinpeters

90% sure I did, but I'll run it again to make sure

lightmaster avatar Aug 04 '23 00:08 lightmaster

I was wrong, apparently I didn't tick that box. Got serial, restorecode, and secret back. Thx

lightmaster avatar Aug 04 '23 00:08 lightmaster

@striczkof thank you so much for solving this, finally can have totp in bitwarden for blizzard

BlastBolt5 avatar Aug 14 '23 14:08 BlastBolt5

I did @striczkof described (using the above device ID) but whenever i try and attach the converted device secret to a password manager (tried 1password and MS Authenticator) i only get 6 digit codes, which are then not accepted by the BN client.

EDIT: Nevermind. I created the QR code wrong. Works in 1Password now.

Drudoo avatar Sep 05 '23 14:09 Drudoo

I managed to get the AUTHENTICATOR_DEVICE_SECRET string from a rooted phone method, but I could not figure out what to do next and could not get it working by trial and error. For me AUTHENTICATOR_DEVICE_SECRET are 2 base64 strings separated by comma with length 64 and 24. What am I doing wrong?

TXort avatar Sep 13 '23 08:09 TXort

I managed to get the AUTHENTICATOR_DEVICE_SECRET string from a rooted phone method, but I could not figure out what to do next and could not get it working by trial and error. For me AUTHENTICATOR_DEVICE_SECRET are 2 base64 strings separated by comma with length 64 and 24. What am I doing wrong?

Same here, the API method seems to be patched when going to the swagger-ui:

{"errorCode":"BLZBNTARA10000000","message":"An unknown server error occurred."}

So the root method is the only option, I got the XML however its all bytes I believe after base64 decoding it. Hoping someone can figure this out, maybe @mx03

vmoffset avatar Sep 27 '23 18:09 vmoffset

I managed to get the AUTHENTICATOR_DEVICE_SECRET string from a rooted phone method, but I could not figure out what to do next and could not get it working by trial and error. For me AUTHENTICATOR_DEVICE_SECRET are 2 base64 strings separated by comma with length 64 and 24. What am I doing wrong?

Same here, the API method seems to be patched when going to the swagger-ui:

{"errorCode":"BLZBNTARA10000000","message":"An unknown server error occurred."}

So the root method is the only option, I got the XML however its all bytes I believe after base64 decoding it. Hoping someone can figure this out, maybe @mx03

LOL

I thought the same too, but apparently, they did not get rid of it. They just changed the URL to https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html (redirect from https://authenticator-rest-api.bnet-identity.blizzard.net/) and the client ID still works somehow. (tried getting my serial and restore and it works) Still invalid callback for localhost so can't make a client for this one :/

As for the device secret, they probably changed its format. I gotta check when I have free time.

alvinpeters avatar Sep 27 '23 21:09 alvinpeters

LOL IT FUCKING WORKED HAHAHAHAHA THANK YOU SO MUCH @mx03

Sadly that forces everyone to download the app and login once before getting the client ID. Are you actually sure about the client ID being per-user? I'm gonna test with different accounts later if you haven't tried that. And would non-rooted users be able to access that directory?

For those waiting for an app to automate these steps. (only slightly due to the way of getting the client ID/device secret) This is what I did:

  1. Download the Battle.net Messenger
  2. Login to the app
  3. (This step might need root) Get the secret:
  • From the app

    1. Press "Enable now" when prompted to enable the authenticator
    2. Go to /data/data/com.blizzard.messenger/shared_prefs/com.blizzard.messenger.authenticator_preferences.xml
    3. Either copy the file to the PC or open it in the phone
    4. Save the content of the string tag named "com.blizzard.messenger.AUTHENTICATOR_DEVICE_SECRET"
  • From the REST API

    1. Go to /data/data/com.blizzard.messenger/shared_prefs/com.blizzard.messenger.authenticator_preferences.xml
    2. Either copy the file to the PC or open it in the phone
    3. Copy the content of the string tag named com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_CLIENT_ID
    4. Go to https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html

    You can skip all the steps above with this client ID (as long as this doesn't get changed lol): baedda12fe054e4abdfc3ad7bdea970a

    1. Make sure to tick the 'auth.authenticator' scope then click "Authorize," paste the acquired client ID to the client ID input then click "Authorize."
    2. Login if you are not logged in already. Either way, you should be redirected back and see the client ID input as just client_id: ******
    3. Click the "POST: Click and add a brand new authenticator..." header, click "Try it out," then "Execute."
    4. The response should be "200: OK" with a JSON output providing your device secret
    5. Save the value of deviceSecret and might as well save serial and restoreCode for backup
  1. Convert the device secret from hex to base32. On Linux and maybe macOS, this can be done with echo "PASTEYOURDEVICESECRETHERE" | xxd -r -p | base32
  2. Put the converted secret and set the digits to 8 on your authenticator of your choosing. I use Aegis and it works.

I just wanted to chip in and provide my 2 cents about this one. I followed above instructions and turns out you do not need to have the authenticator installed, do not have to use a special clientID. Just do the following to get 2fa secret:

  • Go to https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html
  • use clientID: baedda12fe054e4abdfc3ad7bdea970a Make sure to tick the 'auth.authenticator' scope then click "Authorize," paste the acquired client ID to the client ID input then click "Authorize."
  • Login if you are not logged in already. Either way, you should be redirected back and see the client ID input as just client_id: ******
  • Click the "POST: /v1/authenticator - Click and add a brand new authenticator..." header, click "Try it out," then "Execute."
  • The response should be "200: OK" with a JSON output providing your device secret If it responds with anything other then "200: OK", read what it says and act accordingly. In my case I already had the battle.net app installed, and you cannot create a new authenticator if you do. So in that case, remove the authorization from the app and start the POST step again.
  • Save the value of deviceSecret and save serial and restoreCode as well for backup!!
  • Convert the device secret from hex to base32. On Linux and macOS use terminal. (on windows use WSL or a online tool) the command is echo "PASTEYOURDEVICESECRETHERE" | xxd -r -p | base32
  • Put the converted secret in your 2FA of choice and set the digits to 8. I used Aegis and it works perfectly.

As you can see, lots of overlap, but streamlined process. Hope this helps the next person! Thanks @mx03 and @striczkof!

ldehaas1612 avatar Oct 04 '23 11:10 ldehaas1612

awesome. Much cleaner instructions are great for people!

alvinpeters avatar Oct 04 '23 11:10 alvinpeters