VideoHelp Forum
+ Reply to Thread
Results 1 to 10 of 10
Thread
  1. Member
    Join Date
    May 2024
    Location
    New Jersey
    Search Comp PM
    Hi,

    I'm attempting to extract keys from a service, but it has a custom body payload in its license URL. I've tried using both cdrm-project.com and getwvkeys.cc, but due to the custom body payloads and headers, I haven't had any success. Is there a way to extract these keys using any API that can accept custom json body and headers for its license? I'm working on creating a custom script with my own CDM, but this is my first time doing this, and I could use some advice if you can provide it. The service I'm working with is similar to Noor Play.

    Below I have attached the license key payloads and its response.

    Image
    [Attachment 79392 - Click to enlarge]

    Image
    [Attachment 79393 - Click to enlarge]

    Image
    [Attachment 79394 - Click to enlarge]

    Image
    [Attachment 79395 - Click to enlarge]

    Image
    [Attachment 79396 - Click to enlarge]

    Image
    [Attachment 79397 - Click to enlarge]

    Image
    [Attachment 79398 - Click to enlarge]
    Quote Quote  
  2. Member aqzs's Avatar
    Join Date
    Mar 2024
    Location
    Paris
    Search Comp PM
    You have to use something like this :
    HTML Code:
    licence = requests.post(url=lic_url, headers=headers, json={'licenseRequest': f'{base64.b64encode(challenge).decode(),
    ‘Blabla’ : ‘blabla’}'})
    Send a private message with more informations I can make the custom python
    Quote Quote  
  3. Probably something like this:

    Code:
    import json
    from pywidevine.cdm import Cdm
    from pywidevine.device import Device
    from pywidevine.pssh import PSSH
    import base64
    import requests
    
    WVD = r"path_to.wvd"
    LICENSE_URL = 'https://vdrm.mobiotics.com/prod/proxy/v1/license/widevine'
    
    json_payload = r'{"payload": "CAQ=", "contentid": "...."}'
    pssh = PSSH('AAA....')
    headers = {}
    
    device = Device.load(WVD)
    cdm = Cdm.from_device(device)
    session_id = cdm.open()
    challenge = cdm.get_license_challenge(session_id, pssh)
    
    custom_payload = json.loads(json_payload)
    custom_payload["payload"] = base64.b64encode(challenge).decode('utf-8')
    custom_payload = json.dumps(custom_payload)
    response = requests.post(LICENSE_URL, data=custom_payload, headers=headers)
    response.raise_for_status()
    response_json = json.loads(response.content)
    license = response_json["body"]
    cdm.parse_license(session_id, license)
    
    for key in cdm.get_keys(session_id):
        if key.type == 'CONTENT':
            print(f'--key {key.kid.hex}:{key.key.hex()}', end=' ')
    cdm.close(session_id)
    Not sure about headers, probably not needed though.
    Quote Quote  
  4. Member aqzs's Avatar
    Join Date
    Mar 2024
    Location
    Paris
    Search Comp PM
    Originally Posted by white_snake View Post
    Probably something like this:

    Code:
    import json
    from pywidevine.cdm import Cdm
    from pywidevine.device import Device
    from pywidevine.pssh import PSSH
    import base64
    import requests
    
    WVD = r"path_to.wvd"
    LICENSE_URL = 'https://vdrm.mobiotics.com/prod/proxy/v1/license/widevine'
    
    json_payload = r'{"payload": "CAQ=", "contentid": "...."}'
    pssh = PSSH('AAA....')
    headers = {}
    
    device = Device.load(WVD)
    cdm = Cdm.from_device(device)
    session_id = cdm.open()
    challenge = cdm.get_license_challenge(session_id, pssh)
    
    custom_payload = json.loads(json_payload)
    custom_payload["payload"] = base64.b64encode(challenge).decode('utf-8')
    custom_payload = json.dumps(custom_payload)
    response = requests.post(LICENSE_URL, data=custom_payload, headers=headers)
    response.raise_for_status()
    response_json = json.loads(response.content)
    license = response_json["body"]
    cdm.parse_license(session_id, license)
    
    for key in cdm.get_keys(session_id):
        if key.type == 'CONTENT':
            print(f'--key {key.kid.hex}:{key.key.hex()}', end=' ')
    cdm.close(session_id)
    Not sure about headers, probably not needed though.
    I recommand using :
    HTML Code:
    data = {}
    request.get(…. json=data)
    Or :
    HTML Code:
    data = {}
    jsondata = json.loads(data)
    request.get(…. data=jsondata)

    Instead of sending the payload as str. (Sorry Im at school rn editing on phone is hard)
    Quote Quote  
  5. Originally Posted by aqzs View Post
    I recommand using :
    HTML Code:
    data = {}
    request.get(…. json=data)
    I believe deserialization still happens inside the requests library, so it's functionally the same, although more concise.


    Or :
    HTML Code:
    data = {}
    jsondata = json.loads(data)
    request.get(…. data=jsondata)

    Instead of sending the payload as str. (Sorry Im at school rn editing on phone is hard)
    json.loads() returns a dict type, so it's probably best to send this with:
    Code:
    json=jsondata
    Also
    Code:
    data = {}
    jsondata = json.loads(data)
    would give you a TypeError.
    Quote Quote  
  6. had tested a free content, (make a free account), only got 576p resolution, does premium account provide 1080p? @josephsamual
    Quote Quote  
  7. Member aqzs's Avatar
    Join Date
    Mar 2024
    Location
    Paris
    Search Comp PM
    Originally Posted by white_snake View Post
    Code:
    data = {}
    jsondata = json.loads(data)
    would give you a TypeError.
    Sorry, I wanted to say json.dumps() instead of json.loads()
    Quote Quote  
  8. Originally Posted by aqzs View Post
    Originally Posted by white_snake View Post
    Code:
    data = {}
    jsondata = json.loads(data)
    would give you a TypeError.
    Sorry, I wanted to say json.dumps() instead of json.loads()
    Well, then it's basically what I did.

    Code:
    custom_payload = json.dumps(custom_payload)
    response = requests.post(LICENSE_URL, data=custom_payload, headers=headers)
    Quote Quote  
  9. Member
    Join Date
    May 2024
    Location
    New Jersey
    Search Comp PM
    Originally Posted by aqzs View Post
    You have to use something like this :
    HTML Code:
    licence = requests.post(url=lic_url, headers=headers, json={'licenseRequest': f'{base64.b64encode(challenge).decode(),
    ‘Blabla’ : ‘blabla’}'})
    Send a private message with more informations I can make the custom python

    Thank you. I sent you a PM
    Quote Quote  
  10. Member aqzs's Avatar
    Join Date
    Mar 2024
    Location
    Paris
    Search Comp PM
    Basic script to get the keys for others interested:

    HTML Code:
    from pywidevine.cdm import Cdm
    from pywidevine.device import Device
    from pywidevine.pssh import PSSH
    import requests
    import base64
    
    headers = {'x-session': TRUNCATED,}
    data = {
        'contentid': 'UMaHUPObcAX',
        'packageid': '123km10RCF8WttMg',
        'drmscheme': 'WIDEVINE',
        'availabilityid': 'EZ5WAHC7',
        'seclevel': 'SW'
        }
    TOKEN = requests.post('https://vcms.mobiotics.com/prodv3/subscriber/v1/content/drmtoken', headers=headers, data=data).json()['success']
    
    headers = {'content-type': 'application/json',
        'x-session': TRUNCATED,}
    pssh = input('pssh: ')
    pssh = PSSH(pssh)
    lic_url = 'https://vdrm.mobiotics.com/prod/proxy/v1/license/widevine'
    
    device = Device.load("device.wvd")
    cdm = Cdm.from_device(device)
    session_id = cdm.open()
    challenge = cdm.get_license_challenge(session_id, pssh)
    json_data = {
        'payload': base64.b64encode(challenge).decode(),
        'contentid': 'UMaHUPObcAX',
        'providerid': 'sainapl',
        'timestamp': 1716826686,
        'drmscheme': 'WIDEVINE',
        'customdata': {
            'packageid': '123km10RCF8WttMg',
            'drmtoken': TOKEN,
        },
    }
    licence = requests.post(url=lic_url, headers=headers, json=json_data)
    cdm.parse_license(session_id, licence.json()['body'])
    returned_keys = []
    for key in cdm.get_keys(session_id):
        if key.type != "SIGNING":
            returned_keys.append(f"{key.kid.hex}:{key.key.hex()}")
            print(f"\n--key {key.kid.hex}:{key.key.hex()}")
    cdm.close(session_id)
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!