April 10, 2021

When you want to get the original video link from youtube for some normal videos of the grayed-checked channels, those original video links may have a security signature or be identified as cipher as shown below.

Array (

[s] => bObOq0QJ8wRgIhAOJPpnO9AcUCc9UEAwEKnUd = drP-m3xvnI3v1Dge4x_nAiEA8gpSsZEKeAcqbUnI03X0Q-JAN0zSPzpHeOkRwEHO03wR

[sp] => sig

[url] => https://r6—sn-vgqs7nls.googlevideo.com/videoplayback?expire=1590508352& [very long string with many parameters…]

)

[s] => encrypted signature, we need to decode this signature if we want the video to play

The structure to run the above url will be: [url]. '& sig ='. decode ([s])

To Decode [s] we need to use curl to get content from the link youtube.com/watch?v=IDVIDEO and retrieve the following js link: https://www.youtube.com/s/player/[4583e272]/player_ias.vflset/en_US/base.js  part [4583e272] it is a variable that will change over time so depending on the video and time there will be different url js, the js link above contains the functions to decode the cipher signature.

  • We need to find out what is func name decode;
  • We will rely on this structure to use the regex expression to find and retrieve the main func name decode
  • When the viewsource link js above we will also find the func name decode structure as shown below and we have to find a way to get this function to decode.

The sample func decode is as follows:

        zw = function(a) {
            a = a.split("");
            yw.ro(a, 2);
            yw.S6(a, 43);
            yw.ro(a, 3);
            yw.uW(a, 14);
            yw.uW(a, 68);
            yw.S6(a, 4);
            yw.uW(a, 49);
            yw.uW(a, 30);
            yw.uW(a, 69);
            return a.join("")
        };
We can use the following regex expression to get:




if (preg_match('@\b([a-zA-Z0-9$]{2})\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)@is', $js_code, $matches)) {
			echo $matches[1].'-';
           return preg_quote($matches[1]);
}

\ s *: denotes more or less white space
Or you can use the following command to get the funcname above function:

		$fcname=explode('(decodeURIComponent(c))',$js_code)[0];
		$fcname=preg_replace('#(.*)=#is','',$fcname);
		if($fcname!=''){
			return $fcname;
		}

Either way is essential that we need to determine the func name decode as in the above sample, the result is zw

Next, we need to restructure the decode function as the following annotation form:

	zw = function(a) {
		a = a.split("");
		yw.ro(a, 2); 	/* [0] => splice 	[1] => 2  */
		yw.S6(a, 43);   /* [0] => reverse 	[1] => 43 */
		yw.ro(a, 3); 	/* [0] => splice 	[1] => 3  */
		yw.uW(a, 14); 	/* [0] => swap 	        [1] => 14 */
		yw.uW(a, 68); 	/* [0] => swap   	[1] => 68 */
		yw.S6(a, 4); 	/* [0] => reverse 	[1] => 4  */
		yw.uW(a, 49); 	/* [0] => swap    	[1] => 49 */
		yw.uW(a, 30);	/* [0] => swap 	        [1] => 30 */
		yw.uW(a, 69);	/* [0] => swap  	[1] => 69 */
		return a.join("")
	};

Refactoring with ro = splice, S6 = reverse, uW = swap

How to restructure? we have the decoding formula:

  foreach ($instructions as $opt) {
  $command = $opt[0];
            $value = $opt[1];

            if ($command == 'swap') {

                $temp = $signature[0];
                $signature[0] = $signature[$value % strlen($signature)];
                $signature[$value] = $temp;

            } elseif ($command == 'splice') {
                $signature = substr($signature, $value);
            } elseif ($command == 'reverse') {
                $signature = strrev($signature);
            }
}

$ instructions has a sample value of an array as follows: [0] => splice [1] => 2 … cho đến [0] => swap [1] => 69 corresponding to each number in the sample function func name zw above.

for $ opt [0]: is the command the possible values ​​are: swap, splice, reverse

with $ opt [1]: are the values: 2, 43,3 … 69 respectively in the function func name zw that we get as the sample above

From there, apply the above formula to replace the original signature string, so we have successfully decoded.

About the author 

kill@rplayer

Leave a Repl​​​​​y

Your email address will not be published. Required fields are marked

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Subscribe now to get the latest updates!