Теперь, key для расшифровки постоянно меняется и запакован в скрипте.
<?php
$link = isset($_GET["url"]) ? $_GET["url"] : ""; if (!$link) die("No url!");
$referer = isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $link;
// Притворяемся браузером, передаём куки, подменяем Referer'а
$opts = Array('http'=>Array(
'method'=>"GET",
'header'=>"Referer: $referer\r\n" .
"User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36\r\n"));
// Скачиваем html страницу
$html = file_get_contents($link, false, stream_context_create($opts));
// Получаем значения hash и id
$data = $html;
for ($n=0; $n<9; $n++) if (preg_match('#"(\w+)",(\d+),"(\w+)",(\d+),(\d+),(\d+)#s', $data, $m)) $data = JsUnpack($m[1], $m[2], $m[3], $m[4], $m[5], $m[6]);
$apdjk = "Russkie ne zdautsa!";
$key = preg_match('#.*=\s*["\'](.*?)["\']#', $data, $m) ? $m[1] : "";
if (!$key) die("No key found in loaded html page!");
if (!isset($_GET["info"])) {
$file3_separator = "##";
$enc2 = "9";
$enc3 = "7";
$trash = [];
$trash[] = "##P3w7Xl58Kj4qPj8/Pl58Xjx8Pnw/ISrihJYofDshP17ihJY+";
$trash[] = "##Pzs+KSEoKjt8fD58KjxefCp8XipgPj98KHwqPnx8fl1bfD58Kl4q";
$trash[] = "##PGBeKmAqPnzihJYqKuKEll0/Wyo7fHw+fCrihJY7Xipg4oSWKj4=";
$trash[] = "##fFs+KuKElj5eP1s7fHw+fCo8KirihJZdfHxePCoqfA==";
$trash[] = "##OyE/XuKElj4qXipgfHxePCrihJZ8fF4qYF4qKnzihJYqfl1bfD58";
$options = preg_match('#Playerjs\("(.*?)"#', $html, $m) ? $m[1] : "";
$options = AllohaDecode($options, $enc2, $enc3, $trash);
$file = preg_match('#"file":"(.*?)"#s', $options, $m) ? $m[1] : "";
$file = AllohaDecode($file, $enc2, $enc3, $trash, $key);
echo $file;
} else {
echoInfo($link, $html, $key, $opts);
}
///////////////////////////////////////////////////////////////////////////
// !!!!! Ну что, найдём значение мусора автоматически? !!!!!
function echoInfo($link, $html, $key, $opts) {
$urlBase = preg_match('#^(.*?//.*?)/#', $link, $m) ? $m[1] : "";
$jsLink = preg_match('#src="(/js/playerjs.*?)"#', $html, $m) ? $m[1] : "";
if (!$jsLink) die("Not found playerjs link in loaded html page!");
$jscode = file_get_contents($urlBase.$jsLink, false, stream_context_create($opts));
// Ищем упакованный скрипт в загруженном html
$jscode = preg_match('#(eval.*?\{\}\)\))#', $jscode, $m) ? $m[1] : $jscode;
// Создаём распаковщик js-кода
$unpacker = new JavascriptUnpacker;
// Распаковываем js
$unpackedJs = $unpacker->unpack($jscode);
// Находим зашифрованный конфиг (объект v в Playerjs)
$encoded = preg_match("/u:'(#1.*?)'/", $unpackedJs, $m) ? $m[1] : "";
$decoded = AllohaDecode($encoded);
$file3_separator = preg_match('#"file3_separator":"(.*?)"#', $decoded, $m) ? $m[1] : "";
$enc2 = preg_match('#"enc2":"(.*?)"#', $decoded, $m) ? $m[1] : "2";
$enc3 = preg_match('#"enc3":"(.*?)"#', $decoded, $m) ? $m[1] : "3";
$trash = [];
for ($i=0; $i<8; $i++) {
if (preg_match('#"bk'.$i.'":"(.*?)"#', $decoded, $m)) {
$str = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($m) {return mb_convert_encoding(pack('H*', $m[1]), 'UTF-8', 'UCS-2BE');}, $m[1]);
$str = str_replace("\x0", ">", $str); // Странные дела - чтобы всё работало, нулевых кодов не должно быть
$str = str_replace("@" , "~", $str);
//$trash[] = $str;
//$trash[] = urlencode($str);
$trash[] = $file3_separator.base64_encode($str);
}
}
$options = preg_match('#Playerjs\("(.*?)"#', $html, $m) ? $m[1] : "";
$options = AllohaDecode($options, $enc2, $enc3, $trash);
$file = preg_match('#"file":"(.*?)"#s', $options, $m) ? $m[1] : "";
$file = AllohaDecode($file, $enc2, $enc3, $trash, $key);
$v = Array();
$v["file3_separator"] = $file3_separator;
$v["enc2" ] = $enc2;
$v["enc3" ] = $enc3;
$v["trash" ] = $trash;
$v["key" ] = $key;
$v["file" ] = $file;
//$v["options"] = $options;
header("Content-Type: application/json");
echo json_encode($v, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
///////////////////////////////////////////////////////////////////////////////////
function AllohaDecode($t, $enc2="2", $enc3="3", $trash=[], $key="") {
$t = stripslashes($t);
// Избавляемся от мусора
foreach($trash as $tr) $t = str_replace($tr, "", $t);
foreach($trash as $tr) $t = str_replace($tr, "", $t); // Иногда мусор встраивается в мусор, поэтому проходим два раза
switch(substr($t, 0, 2)) {
case "#0": return Html5Decode($t); break;
case "#1": return salt_d(pepper(substr($t, 2), -1)); break;
case "#".$enc2: return base64_decode(substr($t, 2)); break;
case "#".$enc3: return AesDecrypt($t, $key); break;
default : return $t;
}
}
///////////////////////////////////////////////////////////////////////////////////
function AesDecrypt($t, $key) {
$separator = "##";
$len_sep = strlen($separator);
$len_salt = 16;
$len_iv = 32;
$pos_sep1 = $len_salt+$len_sep + $len_iv+$len_sep; // Позиция с конца разделителя 1
$pos_sep2 = $len_salt+$len_sep; // Позиция с конца разделителя 2
if ((substr($t, -$pos_sep1, 2)==$separator) && (substr($t, -$pos_sep2, 2)==$separator)) {
$ct = substr($t, 2, -$pos_sep1);
$iv = substr($t, -$pos_sep1+$len_sep, $len_iv);
$s = substr($t, -$len_salt, $len_salt);
return CryptoJsAesDecrypt($key, '{"ct":"'.$ct.'","iv":"'.$iv.'","s":"'.$s.'"}');
}
return $t;
}
///////////////////////////////////////////////////////////////////////////////////
function pepper($s, $n) {
$abc = "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz";
$a = 22 * $n; // sugar(d.y) = sugar('xx??x?=xx??x?=') in player-alloha-new.js
$a += strlen($abc) / 2;
$r = substr($abc, $a * 2) . substr($abc, 0, $a * 2);
$t = preg_replace_callback("/([A-Za-z])/", function ($matches) use ($r, $abc, $s) { return $r[strrpos($abc, $matches[0])]; }, $s);
return $t;
}
///////////////////////////////////////////////////////////////////////////////////
function salt_d($e) {
$abc = "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz";
$keyStr = $abc."0123456789+/=";
$e = str_split($e);
$t = "";
$f = 0;
while ($f < count($e)) {
$s = strrpos($keyStr, $e[$f++]);
$o = strrpos($keyStr, $e[$f++]);
$u = strrpos($keyStr, $e[$f++]);
$a = strrpos($keyStr, $e[$f++]);
$n = $s << 2 | $o >> 4;
$r = ($o & 15) << 4 | $u >> 2;
$i = ($u & 3) << 6 | $a;
$t .= chr($n);
if ($u != 64) $t .= chr($r);
if ($a != 64) $t .= chr($i);
}
$e = str_split($t);
$t = "";
$n = 0;
while ($n < count($e)) {
$r = ord($e[$n]);
if ($r < 128) {
$t .= chr($r);
$n++;
} else if ($r > 191 && $r < 224) {
$c2 = ord($e[$n+1]);
$t .= chr(($r & 31) << 6 | $c2 & 63);
$n += 2;
} else {
$c2 = ord($e[$n+1]);
$c3 = ord($e[$n+2]);
$t .= chr(($r & 15) << 12 | ($c2 & 63) << 6 | $c3 & 63);
$n += 3;
}
}
return $t;
}
///////////////////////////////////////////////////////////////////////////////////
function Html5Decode($b) {
if (strpos($b, ".") == false) {
$b = substr($b, 1);
$s2 = "";
for ($j = 0; $j < strlen($b); $j += 3) {
$s2 .= '\\u0' . substr($b, $j, 3);
}
$b = json_decode('"' . $s2 . '"');
}
return $b;
}
///////////////////////////////////////////////////////////////////////////////////
function CryptoJsAesDecrypt($passphrase, $jsonString){
$jsondata = json_decode ($jsonString, true);
$salt = hex2bin ($jsondata["s" ]);
$ct = base64_decode($jsondata["ct"]);
$iv = hex2bin ($jsondata["iv"]);
$concatedPassphrase = $passphrase.$salt;
$md5 = array();
$md5[0] = md5($concatedPassphrase, true);
$result = $md5[0];
for ($i = 1; $i < 3; $i++) {
$md5[$i] = md5($md5[$i - 1].$concatedPassphrase, true);
$result .= $md5[$i];
}
$key = substr($result, 0, 32);
$data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
return json_decode($data, true);
}
////////////////////////////////////////////////////////////////////////////
function b64c($d, $e, $f) {
$g = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/';
$h = substr($g, 0, $e);
$i = substr($g, 0, $f);
$d = strrev($d);
$j = 0;
for($c=0; $c<strlen($d); $c++) {
$j += strpos($h, $d[$c]) * pow($e, $c);
}
$k = '';
while ($j > 0) {
$k = $i[$j % $f] . $k;
$j = ($j - ($j % $f)) / $f;
}
return $k ? $k : '0';
}
////////////////////////////////////////////////////////////////////////////
function JsUnpack($h, $u, $n, $t, $e, $r) {
$r = "";
for ($i=0; $i < strlen($h); $i++) {
$s = "";
while ($h[$i] !== $n[$e]) {
$s .= $h[$i];
$i++;
}
for ($j=0; $j < strlen($n); $j++) $s = str_replace($n[$j], $j, $s);
$ch = chr(b64c($s, $e, 10) - $t);
$r .= $ch;
}
return $r;
}
////////////////////////////////////////////////////////////////////////////
// Распаковщик js-кода https://github.com/ptcong/php-javascript-unpacker
class JavaScriptUnpacker
{
protected $alphabet = array(
52 => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP',
54 => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR',
62 => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
95 => ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
);
private $base;
private $map;
public function unpack($source, $dynamicHeader = true)
{
if (! $this->isPacked($source, $dynamicHeader)) return $source;
preg_match("/}\('(.*)',\s*(\d+),\s*(\d+),\s*'(.*?)'\.split\('\|'\)/", $source, $match);
$payload = $match[1];
$this->base = (int) $match[2];
$count = (int) $match[3];
$this->map = explode('|', $match[4]);
if ($count != count($this->map)) return $source;
$result = preg_replace_callback('#\b\w+\b#', array($this, 'lookup'), $payload);
$result = strtr($result, array('\\' => ''));
return $result;
}
public function isPacked($source, $dynamicHeader = true)
{
$header = $dynamicHeader ? '\w+,\w+,\w+,\w+,\w+,\w+' : 'p,a,c,k,e,[rd]';
$source = strtr($source, array(' ' => ''));
return (bool) preg_match('#^eval\(function\('.$header.'\){#i', trim($source));
}
protected function lookup($match)
{
$word = $match[0];
$unbased = $this->map[$this->unbase($word, $this->base)];
return $unbased ? $unbased : $word;
}
protected function unbase($value, $base)
{
if (2 <= $base && $base <= 36) return intval($value, $base);
static $dict = array();
$selector = $this->getSelector($base);
if (empty($dict[$selector])) {
$dict[$selector] = array_flip(str_split($this->alphabet[$selector]));
}
$result = 0;
$array = array_reverse(str_split($value));
for ($i = 0, $count = count($array); $i < $count; $i++) {
$cipher = $array[$i];
$result += pow($base, $i) * $dict[$selector][$cipher];
}
return $result;
}
protected function getSelector($base)
{
if ($base > 62) return 95;
if ($base > 54) return 62;
if ($base > 52) return 54;
return 52;
}
}