M README.md => README.md +3 -1
@@ 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.
-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
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
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
This is for educational purposes only. Downloading copyrighted materials from streaming services may violate their Terms of Service. **Use at your own risk.**
M content_key_decryption.js => content_key_decryption.js +16 -16
@@ 166,21 166,21 @@ function wordToByteArray(wordArray)
// byte array to CryptoJS format
function arrayToWordArray(u8Array)
{
- var words = [], i = 0, len = u8Array.length;
-
- while (i < len) {
- words.push(
- (u8Array[i++] << 24) |
- (u8Array[i++] << 16) |
- (u8Array[i++] << 8) |
- (u8Array[i++])
- );
- }
-
- return {
- sigBytes: len,
- words: words
- };
+ var words = [], i = 0, len = u8Array.length;
+
+ while (i < len) {
+ words.push(
+ (u8Array[i++] << 24) |
+ (u8Array[i++] << 16) |
+ (u8Array[i++] << 8) |
+ (u8Array[i++])
+ );
+ }
+
+ return {
+ sigBytes: len,
+ words: words
+ };
}
const toHexString = bytes => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
@@ 209,4 209,4 @@ function PEM2Binary(pem)
return bytes.buffer;
}
-}());>
\ No newline at end of file
+}());
M content_script.js => content_script.js +14 -14
@@ 2,9 2,9 @@ injectScripts();
async function injectScripts()
{
- await injectScript('lib/pbf.3.0.5.min.js');
- await injectScript('lib/cryptojs-aes_0.2.0.min.js');
- await injectScript('protobuf-generated/license_protocol.proto.js');
+ await injectScript('lib/pbf.3.0.5.min.js');
+ await injectScript('lib/cryptojs-aes_0.2.0.min.js');
+ await injectScript('protobuf-generated/license_protocol.proto.js');
await injectScript('content_key_decryption.js');
@@ 13,14 13,14 @@ async function injectScripts()
function injectScript(scriptName)
{
- return new Promise(function(resolve, reject)
- {
- var s = document.createElement('script');
- s.src = chrome.extension.getURL(scriptName);
- s.onload = function() {
- this.parentNode.removeChild(this);
- resolve(true);
- };
- (document.head||document.documentElement).appendChild(s);
- });
-}>
\ No newline at end of file
+ return new Promise(function(resolve, reject)
+ {
+ var s = document.createElement('script');
+ s.src = chrome.extension.getURL(scriptName);
+ s.onload = function() {
+ this.parentNode.removeChild(this);
+ resolve(true);
+ };
+ (document.head||document.documentElement).appendChild(s);
+ });
+}
M manifest.json => manifest.json +22 -22
@@ 1,29 1,29 @@
{
"manifest_version": 2,
- "name": "Widivine Decryptor",
+ "name": "Widevine Decryptor",
"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",
- "permissions":
+ "permissions":
[
-
+
],
- "icons":
- {
-
- },
- "browser_action": {
-
- },
-
- "content_scripts":
- [
- {
- "matches": ["https://*/*"],
- "js": ["content_script.js"],
+ "icons":
+ {
+
+ },
+ "browser_action": {
+
+ },
+ "content_scripts":
+ [
+ {
+ "matches": ["https://*/*"],
+ "js": ["content_script.js"],
"css": [],
- "run_at": "document_start"
- }
- ],
- "web_accessible_resources": ["content_key_decryption.js", "eme_interception.js", "lib/*", "protobuf-generated/*"]
-}>
\ No newline at end of file
+ "run_at": "document_start",
+ "all_frames": true
+ }
+ ],
+ "web_accessible_resources": ["content_key_decryption.js", "eme_interception.js", "lib/*", "protobuf-generated/*"]
+}