commit
08f1abc046
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
But Widevine's least secure security level, L3, as used in most browsers and PCs, is implemented 100% in software (i.e no hardware TEEs), thereby making it reversible and bypassable.
|
But Widevine's least secure security level, L3, as used in most browsers and PCs, is implemented 100% in software (i.e no hardware TEEs), thereby making it reversible and bypassable.
|
||||||
|
|
||||||
This Chrome extension demonstates how it's possible to bypass Widevine DRM by hijacking calls to the browser's [Encrypted Media Extensions (EME)](https://www.html5rocks.com/en/tutorials/eme/basics) and decrypting all Widevine content keys transferred - effectively turning it into a clearkey DRM.
|
This Chrome extension demonstrates how it's possible to bypass Widevine DRM by hijacking calls to the browser's [Encrypted Media Extensions (EME)](https://www.html5rocks.com/en/tutorials/eme/basics) and decrypting all Widevine content keys transferred - effectively turning it into a clearkey DRM.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
To see this concept in action, just load the extension in Developer Mode and browse to any website that plays Widevine-protected content, such as https://bitmovin.com/demos/drm _[Update: link got broken?]_.
|
To see this concept in action, just load the extension in Developer Mode and browse to any website that plays Widevine-protected content, such as https://bitmovin.com/demos/drm _[Update: link got broken?]_.
|
||||||
@ -35,5 +35,7 @@ Some reversing job on that binary can then be done to extract the secret keys an
|
|||||||
## Why
|
## Why
|
||||||
This PoC was done to further show that code obfuscation, anti-debugging tricks, whitebox cryptography algorithms and other methods of security-by-obscurity will eventually by defeated anyway, and are, in a way, pointless.
|
This PoC was done to further show that code obfuscation, anti-debugging tricks, whitebox cryptography algorithms and other methods of security-by-obscurity will eventually by defeated anyway, and are, in a way, pointless.
|
||||||
|
|
||||||
|
This is **NOT** intended for copyright infringement or encouraging piracy.
|
||||||
|
|
||||||
## Legal Disclaimer
|
## Legal Disclaimer
|
||||||
This is for educational purposes only. Downloading copyrighted materials from streaming services may violate their Terms of Service. **Use at your own risk.**
|
This is for educational purposes only. Downloading copyrighted materials from streaming services may violate their Terms of Service. **Use at your own risk.**
|
||||||
|
@ -166,21 +166,21 @@ function wordToByteArray(wordArray)
|
|||||||
// byte array to CryptoJS format
|
// byte array to CryptoJS format
|
||||||
function arrayToWordArray(u8Array)
|
function arrayToWordArray(u8Array)
|
||||||
{
|
{
|
||||||
var words = [], i = 0, len = u8Array.length;
|
var words = [], i = 0, len = u8Array.length;
|
||||||
|
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
words.push(
|
words.push(
|
||||||
(u8Array[i++] << 24) |
|
(u8Array[i++] << 24) |
|
||||||
(u8Array[i++] << 16) |
|
(u8Array[i++] << 16) |
|
||||||
(u8Array[i++] << 8) |
|
(u8Array[i++] << 8) |
|
||||||
(u8Array[i++])
|
(u8Array[i++])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sigBytes: len,
|
sigBytes: len,
|
||||||
words: words
|
words: words
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const toHexString = bytes => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
|
const toHexString = bytes => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
|
||||||
@ -209,4 +209,4 @@ function PEM2Binary(pem)
|
|||||||
return bytes.buffer;
|
return bytes.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -2,9 +2,9 @@ injectScripts();
|
|||||||
|
|
||||||
async function injectScripts()
|
async function injectScripts()
|
||||||
{
|
{
|
||||||
await injectScript('lib/pbf.3.0.5.min.js');
|
await injectScript('lib/pbf.3.0.5.min.js');
|
||||||
await injectScript('lib/cryptojs-aes_0.2.0.min.js');
|
await injectScript('lib/cryptojs-aes_0.2.0.min.js');
|
||||||
await injectScript('protobuf-generated/license_protocol.proto.js');
|
await injectScript('protobuf-generated/license_protocol.proto.js');
|
||||||
|
|
||||||
|
|
||||||
await injectScript('content_key_decryption.js');
|
await injectScript('content_key_decryption.js');
|
||||||
@ -13,14 +13,14 @@ async function injectScripts()
|
|||||||
|
|
||||||
function injectScript(scriptName)
|
function injectScript(scriptName)
|
||||||
{
|
{
|
||||||
return new Promise(function(resolve, reject)
|
return new Promise(function(resolve, reject)
|
||||||
{
|
{
|
||||||
var s = document.createElement('script');
|
var s = document.createElement('script');
|
||||||
s.src = chrome.extension.getURL(scriptName);
|
s.src = chrome.extension.getURL(scriptName);
|
||||||
s.onload = function() {
|
s.onload = function() {
|
||||||
this.parentNode.removeChild(this);
|
this.parentNode.removeChild(this);
|
||||||
resolve(true);
|
resolve(true);
|
||||||
};
|
};
|
||||||
(document.head||document.documentElement).appendChild(s);
|
(document.head||document.documentElement).appendChild(s);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Widivine Decryptor",
|
"name": "Widevine Decryptor",
|
||||||
"short_name": "WidevineDecryptor",
|
"short_name": "WidevineDecryptor",
|
||||||
"description": "Decrypts and logs media keys from websites that use Widivine DRM",
|
"description": "Decrypts and logs media keys from websites that use Widevine DRM",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"permissions":
|
"permissions":
|
||||||
[
|
[
|
||||||
|
|
||||||
],
|
],
|
||||||
"icons":
|
"icons":
|
||||||
{
|
{
|
||||||
|
|
||||||
},
|
},
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
"content_scripts":
|
||||||
"content_scripts":
|
[
|
||||||
[
|
{
|
||||||
{
|
"matches": ["https://*/*"],
|
||||||
"matches": ["https://*/*"],
|
"js": ["content_script.js"],
|
||||||
"js": ["content_script.js"],
|
|
||||||
"css": [],
|
"css": [],
|
||||||
"run_at": "document_start"
|
"run_at": "document_start",
|
||||||
}
|
"all_frames": true
|
||||||
],
|
}
|
||||||
"web_accessible_resources": ["content_key_decryption.js", "eme_interception.js", "lib/*", "protobuf-generated/*"]
|
],
|
||||||
}
|
"web_accessible_resources": ["content_key_decryption.js", "eme_interception.js", "lib/*", "protobuf-generated/*"]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user