Skip to content
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

Unable to authenticate #9

Open
otac0074 opened this issue Mar 2, 2020 · 138 comments
Open

Unable to authenticate #9

otac0074 opened this issue Mar 2, 2020 · 138 comments

Comments

@otac0074
Copy link

otac0074 commented Mar 2, 2020

i think this problem

bet365 update..

스크린샷 2020-03-03 오전 12 34 30

P + session_id + '????'

added

@tedmax100
Copy link

i was also unable to authenticate too.

@otac0074
Copy link
Author

otac0074 commented Mar 3, 2020

i was also unable to authenticate too.

How do you generate that value?

@mjgerace
Copy link

mjgerace commented Mar 3, 2020

I started having this issue today as well.

Here is the new source code, still cannot figure out where that value is coming in: https://gist.github.com/mjgerace/ae144c6bcf434c68cf85f1b686d3ce83

@otac0074
Copy link
Author

otac0074 commented Mar 3, 2020

I started having this issue today as well.

Here is the new source code, still cannot figure out where that value is coming in: https://gist.github.com/mjgerace/ae144c6bcf434c68cf85f1b686d3ce83

i think keyworld 'NST' or 'token'

@mjgerace
Copy link

mjgerace commented Mar 3, 2020

I would agree, although I cannot figure out what this means in the context of that file. nodecrypto also seems very interesting. Perhaps related to https://nodejs.org/api/crypto.html#crypto_diffiehellman_generatekeys_encoding

@otac0074
Copy link
Author

otac0074 commented Mar 3, 2020

I would agree, although I cannot figure out what this means in the context of that file. nodecrypto also seems very interesting.

I was trying

if you knows this problem

tell to me,

me to

스크린샷 2020-03-03 오후 2 40 46

and boot.nst what is mean?

@otac0074
Copy link
Author

otac0074 commented Mar 3, 2020

i find you file

스크린샷 2020-03-03 오후 2 42 37

스크린샷 2020-03-03 오후 2 43 10

but nothing 'h' functions

@mjgerace
Copy link

mjgerace commented Mar 3, 2020

I am investigating the 'h' business now. This is really interesting, as is your find. What is the name of that file?

@otac0074
Copy link
Author

otac0074 commented Mar 3, 2020

I am investigating the 'h' business now. This is really interesting, as is your find. What is the name of that file?

just bet365 mainpage source

no another file

@otac0074
Copy link
Author

otac0074 commented Mar 3, 2020

스크린샷 2020-03-03 오후 2 50 58

@mjgerace
Copy link

mjgerace commented Mar 3, 2020

I am stumped, will revisit this tomorrow.

@Smart828
Copy link

Smart828 commented Mar 3, 2020

Any thoughts? Since last night, I have been trying to figure out how they can form this parameter.

@mjgerace
Copy link

mjgerace commented Mar 4, 2020

I'm gunna look at it later

@otac0074
Copy link
Author

otac0074 commented Mar 4, 2020

difficult..

@lucifer-v
Copy link

lucifer-v commented Mar 4, 2020

I figure out what is the '???' in "P + session_id + '????'"。
First you can find a B365SimpleEncrypt.decrypt() in bet365 source code as follow:
图片

And, you get two string about nstToken from response of "https://www.288-365.com"。As show in picture.
图片

Then, you bind two string with dot , after that, use B365SimpleEncrypt.decrypt() function decrypt the string( PHP Code I use), as follow:
图片

you will calculate "????", which is the surffix value of handshake message of wss of "wss://premws-pt3.365lpodds.com/zap/"。
图片

And I also find out in request "wss://pshudws.365lpodds.com/zap/", you may get another string looks like the nstToken in request "wss://premws-pt3.365lpodds.com/zap/"。
图片

If you work on the string with B365SimpleEncrypt.decrypt(), you will get the result of upstream "command" message in request "wss://premws-pt3.365lpodds.com/zap/".
图片

But, even I have done this all, I can not receive valid match data. Do you have any more brain holes?

@mjgerace
Copy link

mjgerace commented Mar 4, 2020

@lucifer-v

You have made it further than I did. I did the regex part like this in python. Please note d_value here is NOT ??? by your logic, I am not running decrypt on it.

def get_d_value(user_agent) -> str:
    headers = {
        'Cookie': SESSION_COOKIE_HEADER,
        'User-Agent': user_agent
    }

    req = requests.get(url=HOME_PAGE, headers=headers)
    regex = r'boot&&boot.nst&&boot.nst\((.*)\)'
    matches = re.search(regex, req.text)

    if not matches:
        raise Exception(
            'Session', 'Did not find D value.')

    group = matches.group(0).split("\"")
    d_value = "{}.{}".format(group[1], group[3])
    print(d_value)
    return d_value

To get the nstToken (pre-decryption), but you are drawing important correlations between the values. My initial assumption was that this value was the D value, but after seeing your response, it is clear it is not.

Also worth noting: boot.nst value changes dynamically without refreshing the page. Just view the source a couple of times and see it continuously change.

@lucifer-v
Copy link

lucifer-v commented Mar 4, 2020

@mjgerace
In one refresh, the D_value can be calculated by the value find in the response of "www.288-365.com" passed into B365SimpleEncrypt.decrypt(). you can have a try.

You know: "boot.nst( "str1", "str2" )"
D_value (without "D_") = B365SimpleEncrypt.decrypt( "str1"+"."+"str2" )

@mjgerace
Copy link

mjgerace commented Mar 4, 2020

@lucifer-v

I was just pointing out that the value seems to change repeatedly. IE, the nst ("str1", "str2") changes if you inspect the page source without refreshing (dynamically).

@lucifer-v
Copy link

lucifer-v commented Mar 4, 2020

@mjgerace
Yes it will change when you open the page source. you can also inspect the value in this "Network " window, in "response" Tab, the value is fixed, and which is looks like the value used in the whole wss connection
图片

And I paste the code of B365SimpleEncrypt, you can transfer it to python:
(function(e) { var t = (function() { function e() {} return e.encrypt = function(t) { var n, i = "", o = t.length, r = 0, s = 0; for (r = 0; o > r; r++) { for (n = t.substr(r, 1), s = 0; s < e.MAP_LEN; s++) if (n == e.charMap[s][0]) { n = e.charMap[s][1]; break } i += n } return i } , e.decrypt = function(t) { var n, i = "", o = t.length, r = 0, s = 0; for (r = 0; o > r; r++) { for (n = t.substr(r, 1), s = 0; s < e.MAP_LEN; s++) { if (":" == n && ":|~" == t.substr(r, 3)) { n = "\n", r += 2; break } if (n == e.charMap[s][1]) { n = e.charMap[s][0]; break } } i += n } return i } , e.MAP_LEN = 64, e.charMap = [["A", "d"], ["B", "e"], ["C", "f"], ["D", "g"], ["E", "h"], ["F", "i"], ["G", "j"], ["H", "k"], ["I", "l"], ["J", "m"], ["K", "n"], ["L", "o"], ["M", "p"], ["N", "q"], ["O", "r"], ["P", "s"], ["Q", "t"], ["R", "u"], ["S", "v"], ["T", "w"], ["U", "x"], ["V", "y"], ["W", "z"], ["X", "a"], ["Y", "b"], ["Z", "c"], ["a", "Q"], ["b", "R"], ["c", "S"], ["d", "T"], ["e", "U"], ["f", "V"], ["g", "W"], ["h", "X"], ["i", "Y"], ["j", "Z"], ["k", "A"], ["l", "B"], ["m", "C"], ["n", "D"], ["o", "E"], ["p", "F"], ["q", "0"], ["r", "1"], ["s", "2"], ["t", "3"], ["u", "4"], ["v", "5"], ["w", "6"], ["x", "7"], ["y", "8"], ["z", "9"], ["0", "G"], ["1", "H"], ["2", "I"], ["3", "J"], ["4", "K"], ["5", "L"], ["6", "M"], ["7", "N"], ["8", "O"], ["9", "P"], ["\n", ":|~"], ["\r", ""]], e } )(); e.B365SimpleEncrypt = t }

When you get any progress, please inform us. thanks

@otac0074
Copy link
Author

otac0074 commented Mar 4, 2020

@mjgerace
Yes it will change when you open the page source. you can also inspect the value in this "Network " window, in "response" Tab, the value is fixed, and which is looks like the value used in the whole wss connection
图片

And I paste the code of B365SimpleEncrypt, you can transfer it to python:
(function(e) { var t = (function() { function e() {} return e.encrypt = function(t) { var n, i = "", o = t.length, r = 0, s = 0; for (r = 0; o > r; r++) { for (n = t.substr(r, 1), s = 0; s < e.MAP_LEN; s++) if (n == e.charMap[s][0]) { n = e.charMap[s][1]; break } i += n } return i } , e.decrypt = function(t) { var n, i = "", o = t.length, r = 0, s = 0; for (r = 0; o > r; r++) { for (n = t.substr(r, 1), s = 0; s < e.MAP_LEN; s++) { if (":" == n && ":|~" == t.substr(r, 3)) { n = "\n", r += 2; break } if (n == e.charMap[s][1]) { n = e.charMap[s][0]; break } } i += n } return i } , e.MAP_LEN = 64, e.charMap = [["A", "d"], ["B", "e"], ["C", "f"], ["D", "g"], ["E", "h"], ["F", "i"], ["G", "j"], ["H", "k"], ["I", "l"], ["J", "m"], ["K", "n"], ["L", "o"], ["M", "p"], ["N", "q"], ["O", "r"], ["P", "s"], ["Q", "t"], ["R", "u"], ["S", "v"], ["T", "w"], ["U", "x"], ["V", "y"], ["W", "z"], ["X", "a"], ["Y", "b"], ["Z", "c"], ["a", "Q"], ["b", "R"], ["c", "S"], ["d", "T"], ["e", "U"], ["f", "V"], ["g", "W"], ["h", "X"], ["i", "Y"], ["j", "Z"], ["k", "A"], ["l", "B"], ["m", "C"], ["n", "D"], ["o", "E"], ["p", "F"], ["q", "0"], ["r", "1"], ["s", "2"], ["t", "3"], ["u", "4"], ["v", "5"], ["w", "6"], ["x", "7"], ["y", "8"], ["z", "9"], ["0", "G"], ["1", "H"], ["2", "I"], ["3", "J"], ["4", "K"], ["5", "L"], ["6", "M"], ["7", "N"], ["8", "O"], ["9", "P"], ["\n", ":|~"], ["\r", ""]], e } )(); e.B365SimpleEncrypt = t }

When you get any progress, please inform us. thanks

php b365simpleEncrypt source

can i get that?

@elpaxel
Copy link

elpaxel commented Mar 4, 2020

They changed boot.nst[] to two variables var order=['WJcVaW=='] and var loadingflags=['ES1RgM8F13q8jNKI1ryxD2+AxGKXzFGQJLF0Odaeaet=']

@lucifer-v
Copy link

lucifer-v commented Mar 4, 2020

@otac0074
PHP version, you change ext name to "php" by yourself.

Bet365SimpleEncrypt.txt

some samples as follow:
// command
// �command�nst�FkBeXg==.4iswQ11b6Xlqbc5WxU3AX3cxm+iGCmDQ8AE4wr/5Buo=�SPTBK
$val = "iAeUaW==.KY26tHHRMaB0RSLz7xJdaJS7C+YjfCgtOdhK61/Le4E=";
$val = "eEPUaW==.pXXEoxBRljjF16VK3FcrXbqDLECBWOgWoStFH7GG4rd=";
$val = "HmyUaW==.UnOZs53sCPWceRF0q+5COVUe1mjj1/sbkW5gD3dWReb=";
var_dump( Bet365SimpleEncrypt::decrypt($val) );

@teocns
Copy link

teocns commented Mar 4, 2020

def decryptToken(t):
    n = ""
    i = ""
    o = len(t)
    r = 0
    s = 0
    MAP_LEN = 64
    charMap = [["A", "d"], ["B", "e"], ["C", "f"], ["D", "g"], ["E", "h"], ["F", "i"], ["G", "j"], ["H", "k"], ["I", "l"], ["J", "m"], ["K", "n"], ["L", "o"], ["M", "p"], ["N", "q"], ["O", "r"], ["P", "s"], ["Q", "t"], ["R", "u"], ["S", "v"], ["T", "w"], ["U", "x"], ["V", "y"], ["W", "z"], ["X", "a"], ["Y", "b"], ["Z", "c"], ["a", "Q"], ["b", "R"], ["c", "S"], ["d", "T"], ["e", "U"], ["f", "V"], [
        "g", "W"], ["h", "X"], ["i", "Y"], ["j", "Z"], ["k", "A"], ["l", "B"], ["m", "C"], ["n", "D"], ["o", "E"], ["p", "F"], ["q", "0"], ["r", "1"], ["s", "2"], ["t", "3"], ["u", "4"], ["v", "5"], ["w", "6"], ["x", "7"], ["y", "8"], ["z", "9"], ["0", "G"], ["1", "H"], ["2", "I"], ["3", "J"], ["4", "K"], ["5", "L"], ["6", "M"], ["7", "N"], ["8", "O"], ["9", "P"], ["\n", ":|~"], ["\r", ""]]
    for r in range(0, o):
        n = t[r]
        for s in range(0, MAP_LEN):
            if ":" == n and ":|~" == t[r:3]:
                n = "\n"
                r = r + 2
                break
            if n == charMap[s][1]:
                n = charMap[s][0]
                break
        i = i+n
    return i

This is the Python version for the decrypt function, guys

@otac0074
Copy link
Author

otac0074 commented Mar 4, 2020

def decryptToken(t):
    n = ""
    i = ""
    o = len(t)
    r = 0
    s = 0
    MAP_LEN = 64
    charMap = [["A", "d"], ["B", "e"], ["C", "f"], ["D", "g"], ["E", "h"], ["F", "i"], ["G", "j"], ["H", "k"], ["I", "l"], ["J", "m"], ["K", "n"], ["L", "o"], ["M", "p"], ["N", "q"], ["O", "r"], ["P", "s"], ["Q", "t"], ["R", "u"], ["S", "v"], ["T", "w"], ["U", "x"], ["V", "y"], ["W", "z"], ["X", "a"], ["Y", "b"], ["Z", "c"], ["a", "Q"], ["b", "R"], ["c", "S"], ["d", "T"], ["e", "U"], ["f", "V"], [
        "g", "W"], ["h", "X"], ["i", "Y"], ["j", "Z"], ["k", "A"], ["l", "B"], ["m", "C"], ["n", "D"], ["o", "E"], ["p", "F"], ["q", "0"], ["r", "1"], ["s", "2"], ["t", "3"], ["u", "4"], ["v", "5"], ["w", "6"], ["x", "7"], ["y", "8"], ["z", "9"], ["0", "G"], ["1", "H"], ["2", "I"], ["3", "J"], ["4", "K"], ["5", "L"], ["6", "M"], ["7", "N"], ["8", "O"], ["9", "P"], ["\n", ":|~"], ["\r", ""]]
    for r in range(0, o):
        n = t[r]
        for s in range(0, MAP_LEN):
            if ":" == n and ":|~" == t[r:3]:
                n = "\n"
                r = r + 2
                break
            if n == charMap[s][1]:
                n = charMap[s][0]
                break
        i = i+n
    return i

This is the Python version for the decrypt function, guys

yes, but no receive data..
i think have any more another checkpoint from bet365

@teocns
Copy link

teocns commented Mar 4, 2020

We should investigate on the second socket connection. My assumption is that there's a red-light semaphore for receiving messages from the first socket until the second socket fires the message.
I'll try to block with firewall the domain from the second socket and see the effect

Edit
I have blocked the domain from the secondary socket (the one that stops receiving messages) and it does not affect the main socket, it still receives messages. So the issue must be somewhere. I guess it's easier than we think, but we must be blind to not find it :)

@otac0074
Copy link
Author

otac0074 commented Mar 4, 2020

We should investigate on the second socket connection. My assumption is that there's a red-light semaphore for receiving messages from the first socket until the second socket fires the message.
I'll try to block with firewall the domain from the second socket and see the effect

Edit
I have blocked the domain from the secondary socket (the one that stops receiving messages) and it does not affect the main socket, it still receives messages. So the issue must be somewhere. I guess it's easier than we think, but we must be blind to not find it :)

Is there still no response?

@teocns
Copy link

teocns commented Mar 4, 2020

Stll no response. I am investigating on other variables. I am performing my tests on bet365.it

@otac0074
Copy link
Author

otac0074 commented Mar 4, 2020

Stll no response. I am investigating on other variables. I am performing my tests on bet365.it

dont give up, me to try
bless you..

if possible, tell me please

@mjgerace
Copy link

mjgerace commented Mar 4, 2020

I will resume attempts tonight as well, in like 10 hrs (I am EST timezone). One thing to peak at is Sec-Websocket-Key and Sec-Websocket-Accept. Normally, these values don't actually do anything and are for the client to verify they are talking to the right server. In this case, they could be doing something smart with the key to verify they are talking to the same client.

@HMaker
Copy link

HMaker commented Oct 20, 2020

X-Net-Sync-Term header requires nst token that appears in WS messages: �command�nst�s0uPXw==.ywWk3mMsexd0PAPFwPQPogXdD7JYuRaAiIJiMoe9rHc=�SPTBK.

Using selenium 4 Dev Tools Network can get WS messages

Yes. I think NST is a shorthand for Net Sync Term.

@iflp
Copy link

iflp commented Oct 20, 2020

@HMaker: Nice work getting there. A question: Which part of the NST token is the b64 encoded expiry time?

@iflp
Copy link

iflp commented Oct 20, 2020

@HMaker Thanks for the thorough explanation! Probably easier to go through the whole auth flow again using an arbitrarily short expiry.

@286844626
Copy link

@tpikachu Well I am able to use selenium driver to generate the token in headless mode, it's just needed to setup the driver to be undetectable. Also the obfuscated code includes the checking of the current environment, they try to figure out if it is being ran in a browser but not controlled by a bot, if it is controlled by a bot the resulting NST token will be invalid. It's needed to clean the obfuscated code to remove the browser environment checking.

https://github.com/286844626/bet3656-

@iflp
Copy link

iflp commented Oct 21, 2020

@HMaker Not in my experience.. the PSTK expiry can be set to 12 hours in your settings, and I don't think the NST token has an expiry per se, once you successfully authenticate with a socket and get a response you should be good to use it for it's lifetime.

@marc6691
Copy link

After open the websocket and send every second the message \x16\x006V' + EVENT_ID + '\x01' the websocket stop receiving messages about 40 seconds. Anybody has the same issue?

@HMaker
Copy link

HMaker commented Oct 22, 2020

What about creating the discord server? So that we can keep the secure discussion. So many observers...
If anyone is going to create this, please ping me first

Yes, I was thinking about that too, we should make a discord server.

@HMaker
Copy link

HMaker commented Oct 22, 2020

After open the websocket and send every second the message \x16\x006V' + EVENT_ID + '\x01' the websocket stop receiving messages about 40 seconds. Anybody has the same issue?

You are sending repeated subscription messages? Messages starting with the byte 22 (\x16) means subscription. Generally bet365's frontend does batch subscription by joining several topics separated by commas.

@iflp
Copy link

iflp commented Oct 22, 2020

I've created a discord for further discussion. Please join and indicate your github username: https://discord.gg/NsSRzJk

@dochenaj
Copy link

After open the websocket and send every second the message \x16\x006V' + EVENT_ID + '\x01' the websocket stop receiving messages about 40 seconds. Anybody has the same issue?

You are sending repeated subscription messages? Messages starting with the byte 22 (\x16) means subscription. Generally bet365's frontend does batch subscription by joining several topics separated by commas.

I was wondering if you can subscribe to multiple events at once or you'll need to unsubscribe before subscribing to the another.

\x16 for subscribe and \x17

@marc6691
Copy link

After open the websocket and send every second the message \x16\x006V' + EVENT_ID + '\x01' the websocket stop receiving messages about 40 seconds. Anybody has the same issue?

You are sending repeated subscription messages? Messages starting with the byte 22 (\x16) means subscription. Generally bet365's frontend does batch subscription by joining several topics separated by commas.

I sent topics separated by commas and it closes in the same way. I think bet365 websocket has some mechanism to detect if I flood sending messages..?

After open the websocket and send every second the message \x16\x006V' + EVENT_ID + '\x01' the websocket stop receiving messages about 40 seconds. Anybody has the same issue?

You are sending repeated subscription messages? Messages starting with the byte 22 (\x16) means subscription. Generally bet365's frontend does batch subscription by joining several topics separated by commas.

I was wondering if you can subscribe to multiple events at once or you'll need to unsubscribe before subscribing to the another.

\x16 for subscribe and \x17

I haven't seen any unsubscribe messages at the moment..

@dochenaj
Copy link

@marc6691 If you were to visit multiple events on the browser, search the websocket stream for \x17, and you'll see that each time you move to a new event the old one was unsubscribed.

@marc6691
Copy link

I share my code, but it stops receiving messages after a while. https://github.com/marc6691/bet365-websocket/blob/master/bet365.py

@dochenaj
Copy link

@marc6691 you need to connect to the other socket too. If you observe the websocket in Chrome Dev Tools, you'll notice it connects to two different sockets and sends the handshake code to both of them. I will share that code with you when I get to my computer.

@dochenaj
Copy link

I share my code, but it stops receiving messages after a while. https://github.com/marc6691/bet365-websocket/blob/master/bet365.py

Look at this and you'll figure it out.
https://github.com/JoeBili/bet365-websocket-crawler/blob/master/bet365_websocket_spider.py

@HMaker
Copy link

HMaker commented Nov 7, 2020

Well bet365 changed the token code and broke its evaluation in nodejs, but it is still possible to generate the token with nodejs.

@dochenaj
Copy link

dochenaj commented Nov 7, 2020

I discovered that today, and have been trying to figure out how to extract the new code. Strangely the old code pattern can still be calculated but it is doesn't get the websocket authorized. Have you solved the new issue?

@HMaker
Copy link

HMaker commented Nov 7, 2020

I discovered that today, and have been trying to figure out how to extract the new code. Strangely the old code pattern can still be calculated but it is doesn't get the websocket authorized. Have you solved the new issue?

I am able to do it. They changed the code a little but it is still possible to do the reverse engineering, extract only the needed token code and evaluate it with NodeJS.

@4501771
Copy link

4501771 commented Jan 9, 2021

Hello,
anyone managed this or any other bet365 live game scraper to get working?
thanks in advance

@velafrys
Copy link

velafrys commented Feb 1, 2021

has anyone faced the problem of using chromedriver & selenium in the last couple of days?
Infinity white loading screen during opening bet365.com i mean.

@b0dnar
Copy link

b0dnar commented Feb 4, 2021

I have similar problem. @velafrys do you decided problem?

@ihor2005
Copy link

ihor2005 commented Jun 9, 2021

Hi, have no problem to get in-live data via socket,
but i have problem with decoding PRELIVE odds, they encode odds, like "OD=5(>;|"

can anybody help, please?

@286844626
Copy link

Hi, have no problem to get in-live data via socket,
but i have problem with decoding PRELIVE odds, they encode odds, like "OD=5(>;|"

can anybody help, please?

hi I also encountered the same problem, did you solve it?

@ihor2005
Copy link

ihor2005 commented Jun 9, 2021 via email

@xino1010
Copy link

@ihor2005 would you mind to give some tips to get in-live via socket? Not all the details only the steps. Thank you

@ihor2005
Copy link

ihor2005 commented Jun 24, 2021 via email

@HMaker HMaker mentioned this issue Jul 25, 2021
@dochenaj
Copy link

dochenaj commented Sep 2, 2021

Hi, have no problem to get in-live data via socket,
but i have problem with decoding PRELIVE odds, they encode odds, like "OD=5(>;|"

can anybody help, please?

You figured this out yet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests