jleclanche / python-bna

Python implementation of the mobile Blizzard Authenticator (TOTP)
https://eu.battle.net/support/en/article/24520
MIT License
256 stars 38 forks source link

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

Open mx03 opened 1 year ago

mx03 commented 1 year ago

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
ps245 commented 11 months ago

@oelna

put it in the setup URL like so

Just on that the otpauth url is supposed to look like this:

otpauth://totp/Battle.net%3A<SERIAL>?period=30&digits=8&algorithm=SHA1&secret=<SECRET>

The number after the the issuer "Battle.net" is supposed to be the serial, (it's in that JSON structure that is returned) and that is how it was with the old python-bna tool. This won't stop it from working however if you have something else in there.

@ldehaas1612

So far I'm not worried that my account will be stripped from the 2FA

Me neither. I suspect Blizzard wanted to retire the old API used by the old app for a more standard approach with swagger oauth2 as it's quite clear they're removing legacy services that didn't support OAuth. I also suspect it's easier for them to invalidate all old authenticators before a certain date than try to migrate them.

Also by having one official app there is now only one codebase to maintain and make sure meets the Google Play target API requirements.

James-E-A commented 10 months ago

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.

@jleclanche if you're considering adding this baedda12fe054e4abdfc3ad7bdea970a functionality to the program to override the above policy of Blizzard's, could you consider gating it behind a “--client-spoof” flag of some kind, since this is obviously stepping outside and beyond what the Swagger API actually allows for 3rd-party clients?

Blizzard may suspend or revoke your license to use the Platform, or parts, components and/or single features thereof, if you violate, or assist others in violating, the license limitations set forth below. You agree that you will not, in whole or in part or under any circumstances …

  • Use any unauthorized process or software that intercepts, collects, reads, or “mines” information generated or stored by the Platform; provided, however, that Blizzard may, at its sole and absolute discretion, allow the use of certain third-party user interfaces.
  • Facilitate, create or maintain any unauthorized connection to the Platform including without limitation (i) any connection to any unauthorized server that emulates, or attempts to emulate, the Platform; and (ii) any connection using third-party programs or tools not expressly authorized by Blizzard

(To be clear, I think this is a frickin' awesome feature that should be added, to work around a deeply asinine policy of Blizzard's; I just think it might be appropriate to make users cross that threshold with both eyes open.)

kilmarac commented 10 months ago

@oelna

put it in the setup URL like so

Just on that the otpauth url is supposed to look like this:

otpauth://totp/Battle.net%3A<SERIAL>?period=30&digits=8&algorithm=SHA1&secret=<SECRET>

HA! Thanks. This was EXACTLY what I needed to generate a QR code to use in iOS's new built in authentication. :chefs kiss: The first one wasn't working.

kilmarac commented 10 months ago

Wanted to add my two cents.

If you are unable to use command line for any reason to convert your secret, you can go to https://cryptii.com/pipes/hex-to-base32 get it made as well.

QRENCODE

If you can’t use qrencode command line, you can go to https://qrdex.io/ to make a QR for your authentication app. This link was created by a reddit user and does not appear to save your QR code or redirect it anywhere. However, use at your own risk.

Iolaum commented 10 months ago

I had an old authenticator key created with a similar process some years ago that also got the depreciation email. Removed the old authenticator from the account on the official website. Then tried to add a new one per the instructions:

  • 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.

However I got the following response

{
  "url": "https://account.battle.net/creation/",
  "requireHealup": true
}

I can login to the account normally with only my password. I don't understand what they mean by heal up. Looks internal? Maybe the issue is that I don't have a phone number attached? I don't want to add my phone.

Fma965 commented 10 months ago

I had an old authenticator key created with a similar process some years ago that also got the depreciation email. Removed the old authenticator from the account on the official website. Then tried to add a new one per the instructions:

  • 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.

However I got the following response

{
  "url": "https://account.battle.net/creation/",
  "requireHealup": true
}

I can login to the account normally with only my password. I don't understand what they mean by heal up. Looks internal? Maybe the issue is that I don't have a phone number attached? I don't want to add my phone.

I had this issue. and then i actually read and realised this image

You need to setup a phonenumber on your Battle.net Account

ningmeng52022 commented 10 months ago

几年前,我有一个用类似过程创建的旧身份验证器密钥,该密钥也收到了折旧电子邮件。从官方网站上的帐户中删除了旧的身份验证器。然后尝试按照说明添加一个新的:

  • 前往 https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html
  • 使用 clientID:baedda12fe054e4abdfc3ad7bdea970a
  • 确保勾选“auth.authenticator”范围,然后单击“授权”,将获取的客户端 ID 粘贴到客户端 ID 输入中,然后单击“授权”。
  • 如果您尚未登录,请登录。无论哪种方式,您都应该被重定向回去,并看到客户端 ID 输入仅client_id: **
  • 单击“POST: /v1/authenticator - 单击并添加全新的身份验证器...”标题中,单击“试用”,然后单击“执行”。
  • 响应应为“200:OK”,并带有提供设备密钥的 JSON 输出 如果它响应的是“200:OK”以外的任何内容,请阅读它所说的内容并采取相应的行动。就我而言,我已经安装了 battle.net 应用程序,如果安装了,则无法创建新的身份验证器。因此,在这种情况下,请从应用程序中删除授权,然后再次启动 POST 步骤。
  • 保存deviceSecret的值,并保存serial和restoreCode进行备份!!
  • 将设备密钥从十六进制转换为 base32。在 Linux 和 macOS 上使用终端。(在 Windows 上使用 WSL 或在线工具)命令是 echo “PASTEYOURDEVICESECRETHERE” |xxd -r -p |基数32
  • 将转换后的密钥放入您选择的 2FA 中,并将数字设置为 8。我使用了宙斯盾,它运行良好。

但是,我得到了以下回复

{
  "url": "https://account.battle.net/creation/",
  "requireHealup": true
}

我只需使用密码即可正常登录该帐户。我不明白他们所说的治愈是什么意思。看起来很内在?也许问题是我没有附加电话号码?我不想添加我的手机。

我有这个问题。然后我实际上阅读并意识到了这一点 图像

您需要在 Battle.net 帐户上设置电话号码

https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html
Unable to access anymore----

kindyear commented 9 months ago

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.

https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html was closed,but api still work,We need a new callback url to get token

ningmeng52022 commented 9 months ago

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 and might as well save and for backupdeviceSecret``serial``restoreCode
  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.

https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html was closed,but api still work,We need a new callback url to get token

Thank you for your reply. Can you teach me how to callback?

kindyear commented 9 months ago

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 and might as well save and for backupdeviceSecretserialrestoreCode
  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.

https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html was closed,but api still work,We need a new callback url to get token

Thank you for your reply. Can you teach me how to callback?

Still exploring, seems to have nothing to do with the callback address, the interface may have changed, even if they are still there, I am trying to look at the bnet app code to think about its request method If you have similar development experience, you can also discuss it with me: me@kindyear.cn

wpeii commented 9 months ago

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 and might as well save and for backupdeviceSecretserialrestoreCode
  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.

https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html was closed,but api still work,We need a new callback url to get token

Thank you for your reply. Can you teach me how to callback?

Still exploring, seems to have nothing to do with the callback address, the interface may have changed, even if they are still there, I am trying to look at the bnet app code to think about its request method If you have similar development experience, you can also discuss it with me: me@kindyear.cn

Hey. Any luck? Also, I tried the root files method but i don't know to what I should exactly convert the secret.

kabforks commented 9 months ago

The auth URL doesn't seem to be working: https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html

Has it moved to a new location?

jleclanche commented 9 months ago

Hi folks, I see a lot of activity here, FYI I'm reading and if someone wants to contribute a PR (or take maintenance over), let me know and I will make it happen.

L-Goncalves commented 9 months ago

The auth URL doesn't seem to be working: https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html

Has it moved to a new location?

It looks like the url is responding 401.

If anyone finds a bypass would be great.

Fma965 commented 9 months ago

You need to do the actual API call that swagger would have done this has been mentioned before in this issue

jameshartig commented 9 months ago

You need to do the actual API call that swagger would have done this has been mentioned before in this issue

Unfortunately they shut down the client ID so that doesn't work.

L-Goncalves commented 9 months ago

mentioned

I been able to replicate the request, I opened the battle.net app on my phone with the account logged in. and I used the Charles Proxy I saw the network traffic and re used the Bearer token making a POST request to https://authenticator-rest-api.bnet-identity.blizzard.net/v1/authenticator and there it was, same response from the Swagger.

Example: {"serial":"EU24011347630","restoreCode":"8DPG1N5G8","deviceSecret":"","timeMs":1705110732452,"requireHealup":false}

Now I just wonder how can I generate the Bearer Token of the account

ldehaas1612 commented 9 months ago

mentioned

I been able to replicate the request, I opened the battle.net app on my phone with the account logged in. and I used the Charles Proxy I saw the network traffic and re used the Bearer token making a POST request to https://authenticator-rest-api.bnet-identity.blizzard.net/v1/authenticator and there it was, same response from the Swagger.

Example: {"serial":"EU24011347630","restoreCode":"8DPG1N5G8","deviceSecret":"","timeMs":1705110732452,"requireHealup":false}

Now I just wonder how can I generate the Bearer Token of the account

If you were able to retrieve the bearer token from the proxy, you might also be able to get your clientID from the proxy. This is send to retrieve your bearer token and will be send along with the initial login request. I will just leave a link here to the internet archive of the swagger ui page which shows the steps and options to follow. Hopefully they will help you or someone else out. https://web.archive.org/web/20231027095822/https://authenticator-rest-api.bnet-identity.blizzard.net/webjars/swagger-ui/index.html#/Battle.net%20Authenticator%20REST%20API/getAuthenticatorDeviceInfo

jaredm4 commented 9 months ago

It looks like Blizzard is back to trying to outsmart us. I figured with the swagger UI locked down now, I'd go the android root route, install the app, get the secret from the xml file.

The way I did this was actually with a rooted android virtual device so I don't have to root my phone. I got this working, installed the app, logged in to battle.net.

However, the xml file has changed since the ones dumped above, there is now a changed like for encryption type from AES to MASK. I also noted AUTHENTICATOR_SERVER_TIME_DIFF but unsure if that affects anything.

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="com.blizzard.messenger.AUTHENTICATOR_CREDENTIALS_ENCRYPTION_TYPE">MASK</string>
    <boolean name="com.blizzard.messenger.AUTHENTICATOR_SETUP_POSTPONE_LOGIN" value="false" />
    <string name="com.blizzard.messenger.AUTHENTICATOR_RESTORE_CODE">x</string>
    <string name="com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_CLIENT_ID">baedda12fe054e4abdfc3ad7bdea970a</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_DEVICE_SECRET">y</string>
    <string name="com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_HOST_URL">oauth.battle.net</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_BGS_REGION_CODE">US</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_SERIAL">z</string>
    <long name="com.blizzard.messenger.AUTHENTICATOR_SERVER_TIME_DIFF" value="-123" />
</map>

It looks like restore code, serial and secret are all masked somehow. I can tell because the serial and restore code do not match what the app show (you can get these values from the battle.net app itself). Simply base32'ing and dehexing it didn't work.

Maybe someone else can determine how they're masking the values, but it could be any number of algorithms. ☹️

P.S. the client ID is not masked and confirms indeed it is the same for everyone using the app.

kindyear commented 9 months ago

It looks like Blizzard is back to trying to outsmart us. I figured with the swagger UI locked down now, I'd go the android root route, install the app, get the secret from the xml file.

The way I did this was actually with a rooted android virtual device so I don't have to root my phone. I got this working, installed the app, logged in to battle.net.

However, the xml file has changed since the ones dumped above, there is now a changed like for encryption type from AES to MASK. I also noted AUTHENTICATOR_SERVER_TIME_DIFF but unsure if that affects anything.

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="com.blizzard.messenger.AUTHENTICATOR_CREDENTIALS_ENCRYPTION_TYPE">MASK</string>
    <boolean name="com.blizzard.messenger.AUTHENTICATOR_SETUP_POSTPONE_LOGIN" value="false" />
    <string name="com.blizzard.messenger.AUTHENTICATOR_RESTORE_CODE">x</string>
    <string name="com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_CLIENT_ID">baedda12fe054e4abdfc3ad7bdea970a</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_DEVICE_SECRET">y</string>
    <string name="com.blizzard.messenger.PREF_AUTHENTICATION_PROVIDER_HOST_URL">oauth.battle.net</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_BGS_REGION_CODE">US</string>
    <string name="com.blizzard.messenger.AUTHENTICATOR_SERIAL">z</string>
    <long name="com.blizzard.messenger.AUTHENTICATOR_SERVER_TIME_DIFF" value="-123" />
</map>

It looks like restore code, serial and secret are all masked somehow. I can tell because the serial and restore code do not match what the app show (you can get these values from the battle.net app itself). Simply base32'ing and dehexing it didn't work.

Maybe someone else can determine how they're masking the values, but it could be any number of algorithms. ☹️

P.S. the client ID is not masked and confirms indeed it is the same for everyone using the app.

If install old version Bnet?

BillyCurtis commented 9 months ago

Here's how i got it working with 1Password using Charles Proxy and the Battle.net App on my iPhone

  1. Begin by downloading and installing Charles Proxy.

  2. Navigate to Help > SSL Proxying within Charles Proxy and select Install Charles Root Certificate on a Mobile Device or Remote Browser. Follow the provided instructions to enable SSL Proxying for your iPhone.

  3. Launch the Battle.net App on your iPhone. Then return to Charles Proxy and right-click on https://authenticator-rest-api.bnet-identity.blizzard.net within the list of sites and enable SSL Proxying.

  4. Inside the Battle.net App, enable the Authenticator. Then return to Charles Proxy, and expand the contents of https://authenticator-rest-api.bnet-identity.blizzard.net, then locate the device entry. Click on it, then go to Contents, and you will find an output similar to the following:

    {
        "serial": "XXX",
        "restoreCode": "XXX",
        "deviceSecret": "XXX",
        "timeMs": "XXX",
        "requireHealup": false
    }
  5. Copy the deviceSecret and convert it from hex to base32 using echo "deviceSecret" | xxd -r -p | base32 on Linux/macOS or cryptii.com if on Windows

  6. Replace deviceSecret in the following URL: otpauth://totp/BattleNet:Battle.net?secret=deviceSecret&digits=8 with the newly obtained base32 device secret, and you should have a working TOTP.

schleeb commented 9 months ago

My apologies if this is too far off-topic, but I was able to use all the tricks that have been documented here to generate a QR code that works in Google Authenticator, but when I try to use it with Authy, I get a "Invalid format" "Token format not supported." error message. Does anyone have any ideas? I know I've previously used python-bna to generate a code that did work in Authy, so I know it supports 8-digit codes.

BillyCurtis commented 9 months ago

My apologies if this is too far off-topic, but I was able to use all the tricks that have been documented here to generate a QR code that works in Google Authenticator, but when I try to use it with Authy, I get a "Invalid format" "Token format not supported." error message. Does anyone have any ideas? I know I've previously used python-bna to generate a code that did work in Authy, so I know it supports 8-digit codes.

I was able to add it to Authy by creating a QR code using qrencode -t ANSI "otpauth://totp/BattleNet:Battle.net?secret=deviceSecret&digits=8"

schleeb commented 9 months ago

My apologies if this is too far off-topic, but I was able to use all the tricks that have been documented here to generate a QR code that works in Google Authenticator, but when I try to use it with Authy, I get a "Invalid format" "Token format not supported." error message. Does anyone have any ideas? I know I've previously used python-bna to generate a code that did work in Authy, so I know it supports 8-digit codes.

I was able to add it to Authy by creating a QR code using qrencode -t ANSI "otpauth://totp/BattleNet:Battle.net?secret=deviceSecret&digits=8"

Thank you so much, that works! Oddly, the command I'd been using had -t ansiutf8 which, now that I think about it, doesn't really make sense, and I'm not sure where I even found it in the first place... Regardless, though, I'm sorted out!

forrestwparker commented 9 months ago

For those in the Apple ecosystem with no access to Windows:

Follow the steps in this comment, but install this free app on your iPhone or iPad as an alternative to Charles Proxy. No other device needed.

3936355 commented 9 months ago

How do I get Bearer Tokens without using Charles

jaredm4 commented 9 months ago

Here's how i got it working with 1Password using Charles Proxy and the Battle.net App on my iPhone

Bummer this does not work on Android. Recent Android releases adopt a safe-by-default method for using custom CAs. Each app has to be manually configured to accept the Charles CA, which we can't do since we don't have access to the app source.

Sucks. I hate you, Blizzard.

BillyCurtis commented 9 months ago

Here's how i got it working with 1Password using Charles Proxy and the Battle.net App on my iPhone

Bummer this does not work on Android. Recent Android releases adopt a safe-by-default method for using custom CAs. Each app has to be manually configured to accept the Charles CA, which we can't do since we don't have access to the app source.

Sucks. I hate you, Blizzard.

I have another way of doing this without needing to use the Battle.net App. i'll post a guide later

BillyCurtis commented 9 months ago

Here is another way without having to use the Battle.net App

1. Retrieve SSO Token:

2. Get Bearer Token:

3. Get Serial & Restore Codes:

4. Get Existing Authenticator Device Secret:

5. Create and Add a New Authenticator:

jaredm4 commented 9 months ago

That works, thanks @BillyCurtis !

Notes for others:

BuongiornoTexas commented 9 months ago

Hi Billy,

I just tried this and died on step 2 with {"error":"invalid_token","error_description":"Invalid SSO token."}. I've tried it twice with two separate logins and SSO tokens. There seem to be a couple of places I could be going wrong.

1) I'm using a web browser in step 1 to generate the token, and then going to a terminal shell to run the curl command in step 2 (I've been careful about copying the sso token, so I'm pretty sure this isn't the problem). Is this OK, or do I need to be generating the sso token directly from the terminal session (not my area, so not sure how this would work?). 2) I'm getting a sso token starting with KR- for the Korean authentication server. Could this mean I need to use a different oauth uri or client id? (I think the have the correct terminology here). 3) I do already have a sign in working with the battle.net client and have my restore code and serial - I was expecting I would be able to skip steps 3 and 5 to get everything up and running - does this sound right?

Cheers!

L-Goncalves commented 9 months ago

Hello Everyone, I've been able to replicate the OAuth, you will need to first login into your account at account.battle.net

The open Dev Tools from the browser, go into Cookies Section and get the following value of the Cookie:

image

You will need to copy it and use in OAuth to get the bearer token to use in the Authenticator Rest API:

I've made Javascript script to do that but it can be converted to python too:

async function generateToken() {
  const headers = {
    'Host': 'account.battle.net',
    'accept': 'application/json; charset=UTF-8',
    'content-type': 'application/json; charset=UTF-8',
    'user-agent': 'Battle.net/7123 CFNetwork/1404.0.5 Darwin/22.3.0',
    'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
  };

  const url = 'https://account.battle.net/login/sso/generate';

  const data = {
    program_id: 'BSAp',
    platform_id: 'ios',
    client_version: 1,
    login_ticket: '[BA-tassadar COOKIE USE IT HERE]'
  };

  const options = {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(data),
  };

  try {
    const response = await fetch(url, options);
    const dataResponse = await response.json();
    return await oauth(dataResponse.authentication_token);
  } catch (error) {
    console.error(error);
    throw error; // Rethrow the error to propagate it up
  }
}

async function oauth(generated_token) {
  const headers = {
    'Host': 'oauth.battle.net',
    'accept': '*/*',
    'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
    'user-agent': 'BlizzardSocial/1.24.2 (com.blizzard.social; build:7123; iOS 16.3.1) Alamofire/5.8.0',
    'accept-language': 'en-BR;q=1.0, pt-BR;q=0.9',
  };

  const url = 'https://oauth.battle.net/oauth/sso';

  const data = {
    client_id: 'baedda12fe054e4abdfc3ad7bdea970a',
    grant_type: 'client_sso',
    scope: 'auth.authenticator',
    token: generated_token
  };

  const body = new URLSearchParams(data);

  const options = {
    method: 'POST',
    headers: headers,
    body: body,
  };

  try {
    const response = await fetch(url, options);
    return await response.json();
  } catch (error) {
    console.error(error);
    throw error; // Rethrow the error to propagate it up
  }
}

These 2 Functions are used to generate the SSO Token and the other one retrives the Bearer Token to use it then after having the bearer token you are free to use in the request for the rest api like that:

async function fetchAuthenticatorData(bearerToken) {
  const url = 'https://authenticator-rest-api.bnet-identity.blizzard.net/v1/authenticator';

  const headers = {
    'Host': 'authenticator-rest-api.bnet-identity.blizzard.net',
    'accept': '*/*',
    'user-agent': 'BlizzardSocial/1.24.2 (com.blizzard.social; build:7123; iOS 16.3.1) Alamofire/5.8.0',
    'accept-language': 'en-BR;q=1.0, pt-BR;q=0.9',
    'authorization': `Bearer ${bearerToken}`,
    'Content-Type': 'application/json',
  };

  const options = {
    method: 'POST',
    headers: headers,
  };

  try {
    const response = await fetch(url, options);
    return await response.json();
  } catch (error) {
    console.error(error);
    throw error;
  }
}
MotorkinR12P commented 9 months ago

2. Get Bearer Token:

* Replace `<SSO_TOKEN>` with the token you got from step 1 and execute the following curl command to obtain the Bearer Token:

hello, I also have problems with step 2, i'm running it on windows 11, cmd as administrator 1

EDIT: problem fixed, it was because of the syntax in Windows

BuongiornoTexas commented 9 months ago

Resolved my problem. In step 1, I grabbed the sso token at the 404 page. However, it changed between this page and the account overview. My success path was:

1) Login on a web browser, get to my account page and then extract the BA-tassadar value (thanks @L-Goncalves).

2) Use @BillyCurtis step 2 for the bearer token and step 4 for the device secret (I already had the recovery code and serial info).

Thank you to all of the thread contributors - much appreciated.

BillyCurtis commented 9 months ago

Resolved my problem. In step 1, I grabbed the sso token at the 404 page. However, it changed between this page and the account overview. My success path was:

  1. Login on a web browser, get to my account page and then extract the BA-tassadar value (thanks @L-Goncalves).
  2. Use @BillyCurtis step 2 for the bearer token and step 4 for the device secret (I already had the recovery code and serial info).

Thank you to all of the thread contributors - much appreciated.

Using the SSO token from the 404 page URL should work without having to get it from the BA-tassadar value.

BuongiornoTexas commented 9 months ago

Using the SSO token from the 404 page URL should work without having to get it from the BA-tassadar value.

I thought so too, but it failed several times for me using the token from the 404 page. I've just rechecked, and the BA-tassadar value is different from the token value on the 404 page and the account page (same value both times). On Windows this time.

So I'm not sure what is different for me? Maybe firefox, maybe the fact that I already have the Blizzard authenticator setup and I'm just trying to recover the devicesecret?

Regardless, I thought I would share as it may provide a resolution for others.

GlassedSilver commented 8 months ago

For anyone unable to locate the SSO Token in step one you may already have the authenticator added like me (for the sweet sweet push notification approval). In that case you need to go to the Security Section of your Account page and select Get Restore Code.

Then open dev tools and find the required token as described.

This thread should be made into a wiki if you ask me.

lightmaster commented 8 months ago

Blizzard killed my 2fa cuz I still had an old version of their authenticator authorized. Trying @BillyCurtis's steps, and I get the SSO-token and the bearer token, but when I try to add a new authenticator, I get this response:

{"url":"https://account.battle.net/creation/","requireHealup":true}% 
L-Goncalves commented 8 months ago

Blizzard killed my 2fa cuz I still had an old version of their authenticator authorized. Trying @BillyCurtis's steps, and I get the SSO-token and the bearer token, but when I try to add a new authenticator, I get this response:

{"url":"https://account.battle.net/creation/","requireHealup":true}% 

I believe that the requireHealup value is if it needs a phone number, usually when I was attaching authenticators I would get that if no phone number was attached to the account.

ldehaas1612 commented 8 months ago

Blizzard killed my 2fa cuz I still had an old version of their authenticator authorized. Trying @BillyCurtis's steps, and I get the SSO-token and the bearer token, but when I try to add a new authenticator, I get this response:

{"url":"https://account.battle.net/creation/","requireHealup":true}% 

Read carefully.. You have to specify an phone number to your account in order to create a 2FA. This is their fallback method

lightmaster commented 8 months ago

@ldehaas1612 @L-Goncalves Just found that when reading all the messages since last time I had to do this dance with Blizzard. Today I had just looked at the most recent set of instructions and didn't realize there had to be a phone number on the account. Also, I definitely had a phone number on it before cuz the verification message when I just added my number showed the last time they sent verification to my number. Not sure why they removed my number at some point.

EDIT: It worked now, thanks.

stjeffrey commented 8 months ago

Trying to follow @BillyCurtis's method and it fails for me at step 3 {"errorCode":"BLZBNTARA10000303","message":"Failed to retrieve authenticator; authenticator not found."}%

Can someone confirm if this method still works?

BillyCurtis commented 8 months ago

Trying to follow @BillyCurtis's method and it fails for me at step 3 {"errorCode":"BLZBNTARA10000303","message":"Failed to retrieve authenticator; authenticator not found."}%

Can someone confirm if this method still works?

Go straight to step 5 after you get the bearer token if you don’t already have an authenticator

wpeii commented 8 months ago

2. Get Bearer Token:

* Replace `<SSO_TOKEN>` with the token you got from step 1 and execute the following curl command to obtain the Bearer Token:

hello, I also have problems with step 2, i'm running it on windows 11, cmd as administrator 1

EDIT: problem fixed, it was because of the syntax in Windows

I'm getting this error too. Can you please share the fixed command you used?

ningmeng52022 commented 8 months ago

Here's how i got it working with 1Password using Charles Proxy and the Battle.net App on my iPhone

Bummer this does not work on Android. Recent Android releases adopt a safe-by-default method for using custom CAs. Each app has to be manually configured to accept the Charles CA, which we can't do since we don't have access to the app source.

Sucks. I hate you, Blizzard.

Thank you, I have successfully obtained the device secret following your tutorial.

ciphersimian commented 6 months ago

I'm pleased to report that @BillyCurtis's refined steps here:

https://github.com/jleclanche/python-bna/issues/38#issuecomment-1902482544

still work like a charm!

I received the dreaded e-mail today that my legacy authenticator was removed from my account so I had no authenticator, and they also reset my password. I followed the password reset e-mail, logged in, did step 1 & 2, skipped to step 5 and everything went perfectly. I was able to logout and back in, was prompted for the auth code, and the andOTP worked using:

Type TOTP Issuer Battle.net Label Battle.net Secret <base32 device secret from step 5 above> Period 30 Digits 8 Algorithm SHA1

Thanks to everyone who contributed here!

Gigafrost commented 6 months ago

https://github.com/jleclanche/python-bna/issues/38#issuecomment-1902482544 by @BillyCurtis and https://github.com/jleclanche/python-bna/issues/38#issuecomment-1902517172 by @L-Goncalves Also still works for me as well! With some slight alterations

So what worked for me was first following steps to get the Bearer token from https://github.com/jleclanche/python-bna/issues/38#issuecomment-1902517172 by @L-Goncalves

I only needed the first code but had to convert it to python because I didn't know how to run it properly as a js file. Here's my python version of the code which seemed to work:

import requests

def generate_token():
    headers = {
        'Host': 'account.battle.net',
        'accept': 'application/json; charset=UTF-8',
        'content-type': 'application/json; charset=UTF-8',
        'user-agent': 'Battle.net/7123 CFNetwork/1404.0.5 Darwin/22.3.0',
        'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
    }

    url = 'https://account.battle.net/login/sso/generate'

    data = {
        'program_id': 'BSAp',
        'platform_id': 'ios',
        'client_version': 1,
        'login_ticket': '[BA-tassadar COOKIE USE IT HERE]'
    }

    try:
        response = requests.post(url, headers=headers, json=data)
        response.raise_for_status()
        data_response = response.json()
        return oauth(data_response['authentication_token'])
    except requests.exceptions.RequestException as error:
        print(error)
        raise

def oauth(generated_token):
    headers = {
        'Host': 'oauth.battle.net',
        'accept': '*/*',
        'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
        'user-agent': 'BlizzardSocial/1.24.2 (com.blizzard.social; build:7123; iOS 16.3.1) Alamofire/5.8.0',
        'accept-language': 'en-BR;q=1.0, pt-BR;q=0.9',
    }

    url = 'https://oauth.battle.net/oauth/sso'

    data = {
        'client_id': 'baedda12fe054e4abdfc3ad7bdea970a',
        'grant_type': 'client_sso',
        'scope': 'auth.authenticator',
        'token': generated_token
    }

    try:
        response = requests.post(url, headers=headers, data=data)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as error:
        print(error)
        raise

# Usage
try:
    token = generate_token()
    print('Bearer Token:', token)
except Exception as error:
    print('An error occurred:', error)

Then I followed @BillyCurtis 's tutorial from there, but for me the formatting of the curl commands didn't work on my end, so I figured out that I had to remove the backslashes and change the single quotes to double quotes, then making it all a single line

So for example his first curl command

curl -X 'POST' \
'https://oauth.battle.net/oauth/sso' \
-H "content-type: application/x-www-form-urlencoded; charset=utf-8" \
-d "client_id=baedda12fe054e4abdfc3ad7bdea970a&grant_type=client_sso&scope=auth.authenticator&token=<SSO_TOKEN>"

was changed to this:

curl -X "POST" "https://oauth.battle.net/oauth/sso" -H "content-type: application/x-www-form-urlencoded; charset=utf-8" -d "client_id=baedda12fe054e4abdfc3ad7bdea970a&grant_type=client_sso&scope=auth.authenticator&token=<SSO_TOKEN>"

Which then worked. Also learned that for 1password you can add it via editing the URL > +add more button > then One-Time password

image

And pasting your entire otpauth URL right in that field and hitting save

Took a bit to figure out but now it works great!~ Thanks so much guys for helping us with this!

Ed1123 commented 1 month ago

Thanks to https://github.com/jleclanche/python-bna/issues/38#issuecomment-1902482544 Just a couple of notes of things I had to do:

When I came back to the tab where I was login I had to login again. It asked me for the auth code. Used the one in Aegis and worked like a champ!

wpeii commented 1 month ago

Hello everyone. Thanks to @BillyCurtis and @Gigafrost, I made it too! I have wrapped up both their methods, tested, and rewrote them for people who still are facing issues. Here is my guide on how to attach an authenticator to a Battle.net account.

Before Starting...

  1. This guide is only made for attaching a new authenticator.
  2. I have only tested this on a Windows machine.
  3. Everything here is based on my own results, and may differ for you.

    Perquisites

  4. Have a phone number linked to your Battle.net account.
  5. Check if you have an attached authenticator to your Battle.net account and go ahead detaching it by going to account.battle.net > Security > Battle.net Authenticator - click "Detach" > and confirm by clicking "Detach" again. If you do not have an attached authenticator, skip this and go to Step 1.

    Step 1. Retrieve SSO Token

    • Go to account.battle.net/login/en/?ref=localhost. Log in, and ignore the "404" error. From the URL bar, look for the "ST=" entry and copy the SSO token following it.
      • This is how the SSO Token should look like: EU-u33pyxqgx5l73zu936oujss6mabeyhry-1177987422 or US-u33pyxqgx5l73zu936oujss6mabeyhry-1177987422
      • The token starts with either "EU" or "US" depending from which country you logged in from.
      • If you received an error with the SSO Token in steps to follow, use a VPN to change the beginning format of the token. For example, if you received an error with an SSO Token that starts with "EU", then use a VPN to route your connection to the United States (make sure that you are at us.account.battle.net/login/en/?ref=localhost (or eu.account.battle.net/login/en/?ref=localhost if you are routing your connection from the United States to an EU country)) and retry Step 1 to retrieve an SSO Token that starts with "US" (or "EU"). This will not affect your Battle.net account region/payments/pricings or any similar settings and is intended for the authenticator only.

        Step 2. Get Bearer Token

    • Replace <SSO_TOKEN> with the SSO Token you retrieved from Step 1 in the following command and execute it to obtain the Bearer Token.
    • Open CMD.
    • Run:
      curl -X "POST" "https://oauth.battle.net/oauth/sso" -H "content-type: application/x-www-form-urlencoded; charset=utf-8" -d "client_id=baedda12fe054e4abdfc3ad7bdea970a&grant_type=client_sso&scope=auth.authenticator&token=<SSO_TOKEN>"
      • Response that you should be getting: {"access_token":"XXX","token_type":"bearer","expires_in":0,"scope":"auth.authenticator","sub":"XXX"}
    • Save the response somewhere safe, keep CMD open, and go ahead to Step 3.

      Step 3. Attach a New Authenticator

    • Replace <BREARER_TOKEN> with the Bearer Token you retrieved from Step 2 in the following command and execute it to attach an authenticator to your Battle.net account and obtain Device Secret.
    • Run:
      curl -X "POST" "https://authenticator-rest-api.bnet-identity.blizzard.net/v1/authenticator" -H "accept: application/json" -H "Authorization: Bearer <BEARER_TOKEN>"
      • Response that you should be getting: {"serial":"XXX","restoreCode":"XXX","deviceSecret":"XXX","timeMs":0,"requireHealup":false}
    • Now you have successfully attached an authenticator to your Battle.net account.
    • Save the response somewhere safe too and read Additional Notes below.

      Additional Notes

    • Save both responses from Step 2 and Step 3 somewhere safe. Do NOT save it in your password manager as it may cause a security risk. Treat them like backup/recovery credentials. Feel free to save SSO Token too.
    • You can close CMD now.

      Step 4. Setup the Attached Authenticator to a TOTP URL

    • After you have obtained deviceSecret, convert it from hex to base32 using cryptii.com/pipes/hex-to-base32.
    • Place deviceSecret with the following TOTP URL with the newly obtained Device Secret, and you should have a working TOTP URL.
    • otpauth://totp/Battle.net?secret=deviceSecret&digits=8
    • Lastly, paste the TOTP to an authenticator app or a password manager that supports TOTP.

      Credits

    • #38 (comment) by @BillyCurtis.
    • #38 (comment) by @Gigafrost.
Jimmy-Z commented 4 days ago

https://github.com/jleclanche/python-bna/issues/38#issuecomment-1902482544 @BillyCurtis thanks, this worked for me.