Greasy Fork is available in English.
Intercepta por completo el botón de JDownloader y descifra los enlaces directamente
// ==UserScript==
// @name Click'n'Load Interceptor
// @namespace http://tampermonkey.net/
// @version 2.0
// @description Intercepta por completo el botón de JDownloader y descifra los enlaces directamente
// @author JesusACD
// @match https://hopepaste.download/*
// @grant none
// @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Función para resolver el código de la llave (JK)
function resolverJK(jkString) {
try {
const f = new Function(jkString + " return f();");
return f();
} catch (e) {
console.error("Error al resolver JK:", e);
return null;
}
}
// Función para descifrar usando AES/CBC/NoPadding
function descifrarEnlaces(cryptedBase64, jkHex) {
try {
const key = CryptoJS.enc.Hex.parse(jkHex);
const iv = CryptoJS.enc.Hex.parse(jkHex);
const decrypted = CryptoJS.AES.decrypt(cryptedBase64, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.NoPadding
});
const textoPlano = decrypted.toString(CryptoJS.enc.Utf8);
return textoPlano.replace(/\x00+$/g, "").trim();
} catch (e) {
console.error("Error en el descifrado AES:", e);
return null;
}
}
function inicializarInterception() {
// Buscamos todos los formularios que apunten a JDownloader
const formularios = document.querySelectorAll('form');
formularios.forEach(form => {
if (form.action && form.action.includes('9666')) {
// Creamos la caja de texto donde mostraremos los enlaces limpios
const txtArea = document.createElement('textarea');
txtArea.style.width = "100%";
txtArea.style.height = "150px";
txtArea.style.marginTop = "15px";
txtArea.style.display = "none";
txtArea.style.fontFamily = "monospace";
txtArea.style.padding = "10px";
txtArea.style.border = "1px solid #ced4da";
txtArea.style.borderRadius = "4px";
form.appendChild(txtArea);
// Interceptamos el evento 'submit' (el envío) del formulario
form.addEventListener('submit', function(e) {
// ¡Paso Clave!: Evita que el navegador abra la pestaña de 127.0.0.1:9666
e.preventDefault();
e.stopPropagation();
const cryptedInput = form.querySelector('input[name="crypted"]');
const jkInput = form.querySelector('input[name="jk"]');
if (cryptedInput && jkInput) {
const keyHex = resolverJK(jkInput.value);
if (keyHex) {
const enlaces = descifrarEnlaces(cryptedInput.value, keyHex);
if (enlaces) {
// Separamos los enlaces limpiamente por línea
txtArea.value = enlaces.replace(/\s+/g, '\n');
txtArea.style.display = "block";
// Cambiamos el texto del botón para avisar que ya está listo
const btn = form.querySelector('input[type="submit"]') || form.querySelector('button') || form.querySelector('img');
if (btn && btn.value) btn.value = "¡Enlaces mostrados abajo!";
} else {
alert("No se pudieron descifrar los enlaces.");
}
} else {
alert("No se pudo resolver la clave de descifrado (JK).");
}
} else {
alert("No se encontraron los datos cifrados en el formulario.");
}
}, true);
}
});
}
// Ejecutar cuando el DOM esté listo
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", inicializarInterception);
} else {
inicializarInterception();
}
})();