2021-06-11, 00:42
2021-06-21, 23:15
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
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))
2021-06-22, 08:28
I tried with an US IP but got "unknown errors" that occurred. Nice to see that people had more luck.
2021-07-01, 14:48
(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.
2021-09-17, 18:03
(2021-06-21, 23:15)matthuisman Wrote: had a bit more of a play last night.the valid key appears to be
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))
JuLQgyFz9n89D9pxcN6ZWZXKWfgj2PNBUb32zybj
could you please check?
2021-09-17, 21:56
@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
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
2021-09-18, 15:33
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.
2021-09-18, 20:48
Oh awesome. I use inspeckage which does hook into some crypto functions but obviously not the right ones this time
Good job!
Good job!
2021-09-18, 21:56
Thanks. But I found that there is another check for sign-in api calls using http headers.
Requests will be blocked without headers.
I'm hope you've found or will find a way call sign-in/token apis?
Requests will be blocked without headers.
I'm hope you've found or will find a way call sign-in/token apis?
2021-09-20, 09:40
(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?
2021-10-08, 10:36
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}
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}
2021-10-08, 21:35
Probably not smart to share your sky-ott-usertoken. Anyone could use that to access your account.