• 1
  • 2(current)
  • 3
  • 4
  • 5
  • 13
NBC Peacock Addon Request
#16
(2021-06-11, 00:28)matthuisman Wrote: you need to use Chrome dev tools and figure out how to re-create the "x-sky-signature" header that is used on some requests.

Ok, I'll see what I can do.  Thank you for the tip!
Reply
#17
had a bit more of a play last night.

I now have a script that can be used to confirm the correct hash function is used.
Just need to know the correct hash function now. That's the hard part.
On the android app, they have it in a compiled library called libhmac.so
The secret must be embedded in that file.
I tried to decompile that, but seems to be quite obfuscated.
I think they are using HMAC with SHA1 as the resulting hash is 20 bytes in length.
Which is then base64 encoded

I think the only hope is figuring out the Javascript function which again - is all over the place

Anyway, here is the Python3 code for testing for a valid hash function
Code:
import base64
import hmac
import hashlib

target_hex = '783073b3f84521b9cd79c4060f2b1fc95fd59e32'
target_b64 = 'eDBzs/hFIbnNecQGDysfyV/VnjI='

data = {
    'method': 'GET',
    'url': '/mytv/continuewatching',
    'response_code': '',
    'app_id': 'NBCU-ANDROID-v3',
    'version': '1.0',
    'params_md5': 'd410761c1e765123d77869967943877e',
    'timestamp': '1624262240',
    'payload_md5': 'd41d8cd98f00b204e9800998ecf8427e',
}

def hash_func(to_hash):
    key = bytearray('123456789', 'utf8')
    hashed = hmac.digest(key, to_hash.encode('utf8'), hashlib.sha1)
    return base64.b64encode(hashed).decode('utf8')

to_hash = '{method}\n{url}\n{response_code}\n{app_id}\n{version}\n{params_md5}\n{timestamp}\n{payload_md5}\n'.format(**data)
result = hash_func(to_hash)

if result == target_b64:
    print("SUCCESS: {}".format(result))
else:
    print("WRONG: {} (need: {})".format(result, result_b64))
Reply
#18
I tried with an US IP but got "unknown errors" that occurred.  Nice to see that people had more luck.
Reply
#19
Anything I could help with?
Reply
#20
(2021-06-30, 23:15)27hectormanuel Wrote: Anything I could help with?

https://forum.kodi.tv/showthread.php?tid...pid3042383 says that the important part is how the website creates that header.
Reply
#21
Please can someone finish before the Olympics are over?
Reply
#22
(2021-06-21, 23:15)matthuisman Wrote: had a bit more of a play last night.

I now have a script that can be used to confirm the correct hash function is used.
Just need to know the correct hash function now. That's the hard part.
On the android app, they have it in a compiled library called libhmac.so
The secret must be embedded in that file.
I tried to decompile that, but seems to be quite obfuscated.
I think they are using HMAC with SHA1 as the resulting hash is 20 bytes in length.
Which is then base64 encoded

I think the only hope is figuring out the Javascript function which again - is all over the place

Anyway, here is the Python3 code for testing for a valid hash function
Code:
import base64
import hmac
import hashlib

target_hex = '783073b3f84521b9cd79c4060f2b1fc95fd59e32'
target_b64 = 'eDBzs/hFIbnNecQGDysfyV/VnjI='

data = {
    'method': 'GET',
    'url': '/mytv/continuewatching',
    'response_code': '',
    'app_id': 'NBCU-ANDROID-v3',
    'version': '1.0',
    'params_md5': 'd410761c1e765123d77869967943877e',
    'timestamp': '1624262240',
    'payload_md5': 'd41d8cd98f00b204e9800998ecf8427e',
}

def hash_func(to_hash):
    key = bytearray('123456789', 'utf8')
    hashed = hmac.digest(key, to_hash.encode('utf8'), hashlib.sha1)
    return base64.b64encode(hashed).decode('utf8')

to_hash = '{method}\n{url}\n{response_code}\n{app_id}\n{version}\n{params_md5}\n{timestamp}\n{payload_md5}\n'.format(**data)
result = hash_func(to_hash)

if result == target_b64:
    print("SUCCESS: {}".format(result))
else:
    print("WRONG: {} (need: {})".format(result, result_b64))
the valid key appears to be
JuLQgyFz9n89D9pxcN6ZWZXKWfgj2PNBUb32zybj
could you please check?
Reply
#23
@thantthet
Wow, it works! Amazing stuff!

i would love if you could document how you found it in-case they change it in the future
There are also a few other services (nowtv, skygo uk) that use the same auth, but different key.
So if you can find the keys relatively easy, it would open up them to have add-ons too
Reply
#24
I looked into libhmac.so. It seems to be calling java crypto codes back for HMAC from there. And then I hooked java crypto functions with frida to find the key. There the key reveals.
Reply
#25
Oh awesome. I use inspeckage which does hook into some crypto functions but obviously not the right ones this time Smile

Good job!
Reply
#26
Thanks. But I found that there is another check for sign-in api calls using http headers.
Requests will be blocked without headers. Confused

I'm hope you've found or will find a way call sign-in/token apis?
Reply
#27
(2021-06-21, 23:15)matthuisman Wrote: had a bit more of a play last night.

I now have a script that can be used to confirm the correct hash function is used.
Just need to know the correct hash function now. That's the hard part.
On the android app, they have it in a compiled library called libhmac.so
The secret must be embedded in that file.
I tried to decompile that, but seems to be quite obfuscated.
I think they are using HMAC with SHA1 as the resulting hash is 20 bytes in length.
Which is then base64 encoded

I think the only hope is figuring out the Javascript function which again - is all over the place

Anyway, here is the Python3 code for testing for a valid hash function
Code:
import base64
import hmac
import hashlib

target_hex = '783073b3f84521b9cd79c4060f2b1fc95fd59e32'
target_b64 = 'eDBzs/hFIbnNecQGDysfyV/VnjI='

data = {
    'method': 'GET',
    'url': '/mytv/continuewatching',
    'response_code': '',
    'app_id': 'NBCU-ANDROID-v3',
    'version': '1.0',
    'params_md5': 'd410761c1e765123d77869967943877e',
    'timestamp': '1624262240',
    'payload_md5': 'd41d8cd98f00b204e9800998ecf8427e',
}

def hash_func(to_hash):
    key = bytearray('123456789', 'utf8')
    hashed = hmac.digest(key, to_hash.encode('utf8'), hashlib.sha1)
    return base64.b64encode(hashed).decode('utf8')

to_hash = '{method}\n{url}\n{response_code}\n{app_id}\n{version}\n{params_md5}\n{timestamp}\n{payload_md5}\n'.format(**data)
result = hash_func(to_hash)

if result == target_b64:
    print("SUCCESS: {}".format(result))
else:
    print("WRONG: {} (need: {})".format(result, result_b64))

How do we know which data to add to the string to hash? Like in this case, method, url, response code, app ID, etc?
Reply
#28
can you please show me how to calculate correctly on this example signature ?

PUT https://ovp.peacocktv.com/concurrency/st...1e05632e7c HTTP/1.1
Host: ovp.peacocktv.com
Connection: keep-alive
Content-Length: 26
sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"
X-SkyOTT-UserToken: [REMOVED BY MOD]
X-SkyOTT-Territory: US
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36
X-SkyOTT-COPPA: false
Content-Type: application/vnd.stopstream.v1+json
X-SkyOTT-Provider: NBCU
Accept: application/vnd.stopstream.v1+json
sec-ch-ua-mobile: ?0
x-sky-signature: SkyOTT client="NBCU-WEB-v6",signature="rxV7yhIdBtu+Og2TbLXpSgGUJ3s=",timestamp="1633681657",version="1.0"
X-SkyOTT-Agent: NBCUOTT.COMPUTER.PC
sec-ch-ua-platform: "Windows"
Origin: https://www.peacocktv.com
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.peacocktv.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: cs-CZ,cs;q=0.9

{"streamPosition":7002845}
Reply
#29
Probably not smart to share your sky-ott-usertoken. Anyone could use that to access your account.
Reply
#30
anyone working on this?
Reply
  • 1
  • 2(current)
  • 3
  • 4
  • 5
  • 13

Logout Mark Read Team Forum Stats Members Help
NBC Peacock Addon Request0