From 49a967c18e4cb71e3b0730b7ef049f91436e4ea4 Mon Sep 17 00:00:00 2001 From: Sasuke-Duck UwU <95662926+SASUKE-DUCK@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:49:01 -0500 Subject: [PATCH] Add files via upload --- cdm/wks.py | 23 ++++++++++++++++++++- main_dsnp.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 main_dsnp.py diff --git a/cdm/wks.py b/cdm/wks.py index f991f31..b6eb9e4 100644 --- a/cdm/wks.py +++ b/cdm/wks.py @@ -761,4 +761,25 @@ class KeyExtractor: license_b64 = b64encode(response.content) wvdecrypt.update_license(license_b64) keys = wvdecrypt.start_process() - return keys \ No newline at end of file + return keys + +class DataExtractor_DSNP: + def __init__(self, content): + self.content = content + + def extract_base64_by_choice(self, choice): + if self.content: + matches = [(match[0], re.search(r'base64,(.*)', match[1]).group(1)) for match in re.findall(r'KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSIONS="[^"]+",CHARACTERISTICS="([^"]+)",URI="([^"]+)"', self.content)] + if matches: + if 1 <= choice <= len(matches): + characteristics, base64_data = matches[choice - 1] + return characteristics, base64_data + else: + return None, None + return None, None + + def get_characteristics_list(self): + if self.content: + matches = [(match[0], re.search(r'base64,(.*)', match[1]).group(1)) for match in re.findall(r'KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSIONS="[^"]+",CHARACTERISTICS="([^"]+)",URI="([^"]+)"', self.content)] + return matches + return [] diff --git a/main_dsnp.py b/main_dsnp.py new file mode 100644 index 0000000..d2e3b7c --- /dev/null +++ b/main_dsnp.py @@ -0,0 +1,58 @@ +import argparse +from cdm.wks import KeyExtractor, DataExtractor_DSNP +import requests +token = "" +def get_keys_license(m3u8_url): + response = requests.get(m3u8_url) + content = response.text if response.status_code == 200 else None + + data_extractor = DataExtractor_DSNP(content) + + if content: + characteristics_list = data_extractor.get_characteristics_list() + + if characteristics_list: + print("Choose CHARACTERISTICS Value:") + for i, (characteristics, _) in enumerate(characteristics_list): + print(f"{i + 1}. {characteristics}") + + choice = int(input("Enter the number of the CHARACTERISTICS you want: ")) + characteristics, base64_data = data_extractor.extract_base64_by_choice(choice) + + if characteristics and base64_data: + print("CHARACTERISTICS Value:", characteristics) + + print("PSSH value (Base64 Data):", base64_data) + + license_url = "https://disney.playback.edge.bamgrid.com/widevine/v1/obtain-license" + + headers = { + 'authorization': f'Bearer {token}', + 'origin': 'https://www.disneyplus.com', + 'referer': 'https://www.disneyplus.com/', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', + } + + cert_b64 = None + key_extractor = KeyExtractor(base64_data, cert_b64, license_url, headers) + keys = key_extractor.get_keys() + + for key in keys: + if isinstance(key, list): + if key: + for key_str in key: + print(f"KEY: {key_str}") + + return base64_data + +def main(): + parser = argparse.ArgumentParser(description="Decrypt Widevine content using M3U8 URL") + parser.add_argument("-m3u8", required=True, help="URL of the M3U8 manifest") + args = parser.parse_args() + + m3u8_url = args.m3u8 + + pssh_value = get_keys_license(m3u8_url) + +if __name__ == "__main__": + main()