We decipher Javascript on the example of file hosting mediafire.com
Currently, a way to encrypt javascript on sites using nested eval commands is gaining popularity. Recently, I came across such encryption on mediafire.com file hosting. Encryption was unusual, it interested me and I decided to understand how well this method works.
Mediafire.com site allows you to download files without captcha and at the same time, recently, it has become quite successfully protected from all kinds of automatic robots. He does this using the built-in javascript code generator. Moreover, each time a new code is created, which makes it difficult to emulate it by automatic means.
In this article, I’ll talk about how you can very easily circumvent such protection without in-depth analysis of encrypted code and create an automatic file upload script from mediafire.com.
First, I’ll show you how this code looks:
As you can see from the example, the code is encrypted. Also, each time you access the page, the code changes: the encryption codes (XOR) change, the nesting of eval changes, the names of variables and functions change.
The code calls one of the N functions (generated in html), which in turn includes one of the N blocks on the screen (also generated in html) and displays it on the screen. Then, an additional script (also encrypted) is loaded, which writes links to the pseudo-correct path to the file download to all blocks and writes the correct path to one of these blocks.
So, we need to solve the problem of automatically downloading files from such a
system.
Draw up an action plan.
1. Download the main page, decrypt and determine which of the N functions is called and in which of the N blocks it includes (find out the key)
2. Download the file with links by key, decrypt and determine which of the N links is real (determine by key)
3. Download the file
Honestly, I dismissed the idea of parsing the code and the encryption method right away, since the code is constantly changing, there is no sense in this. Therefore, I bring to your attention another way, namely emulating some browser functions.
We will solve this problem with the help of improvised means: spidermonkey .
Install spidermonkey on the system (in my FreeBSD example):
The biggest problem that I encountered is that it is not known in advance exactly where the executable code will store links and which function it will call. In order not to parse the code itself, I created some kind of getElementById () function, the function is used to load values into a specific HTML element. I did it like this:
The code itself, unchanged, is inserted inside this wrapper and executed. If the code calls the getElementById () function, my code will display everything that is stored in innerHTML.
Thus, without changing the code, it becomes possible to determine what and where the script saves.
And in conclusion, I suggest you familiarize yourself with a working example of downloading files from the mediafire.com resource:
Mediafire.com site allows you to download files without captcha and at the same time, recently, it has become quite successfully protected from all kinds of automatic robots. He does this using the built-in javascript code generator. Moreover, each time a new code is created, which makes it difficult to emulate it by automatic means.
In this article, I’ll talk about how you can very easily circumvent such protection without in-depth analysis of encrypted code and create an automatic file upload script from mediafire.com.
First, I’ll show you how this code looks:
Copy Source | Copy HTML- var h5u='';
- var ybb=unescape('rev%24l%7Djg9%23%23%3Frev%24swhsp4l9qjawgeta%2C%23%213Bl%213F%216%3Da4c0%2A%2A6%213Bl%<<<тут был длинный код шифрованных символов>>>Z%3D--%3Fareh%2Cl%7Djg-%3F');
- for(i=0;i<1324;i++)h5u=h5u+(String.fromCharCode(ybb.charCodeAt(i)^4));
- eval(h5u);
As you can see from the example, the code is encrypted. Also, each time you access the page, the code changes: the encryption codes (XOR) change, the nesting of eval changes, the names of variables and functions change.
The code calls one of the N functions (generated in html), which in turn includes one of the N blocks on the screen (also generated in html) and displays it on the screen. Then, an additional script (also encrypted) is loaded, which writes links to the pseudo-correct path to the file download to all blocks and writes the correct path to one of these blocks.
So, we need to solve the problem of automatically downloading files from such a
system.
Draw up an action plan.
1. Download the main page, decrypt and determine which of the N functions is called and in which of the N blocks it includes (find out the key)
2. Download the file with links by key, decrypt and determine which of the N links is real (determine by key)
3. Download the file
Honestly, I dismissed the idea of parsing the code and the encryption method right away, since the code is constantly changing, there is no sense in this. Therefore, I bring to your attention another way, namely emulating some browser functions.
We will solve this problem with the help of improvised means: spidermonkey .
Install spidermonkey on the system (in my FreeBSD example):
cd /usr/ports/lang/spidermonkey
make install clean
The biggest problem that I encountered is that it is not known in advance exactly where the executable code will store links and which function it will call. In order not to parse the code itself, I created some kind of getElementById () function, the function is used to load values into a specific HTML element. I did it like this:
Copy Source | Copy HTML- var element = new Object();
- element.innerHTML = "";
- var parent = new Object();
- parent.document = new Object();
- parent.document.getElementById = functiontheGetElementByID(x) {
- print("HTML:" + element.innerHTML);
- print("\n");
- print("ELEMENT:" + x + ":");
- return element;
- };
-
- // INSERT CODE HERE
-
- print("HTML:" + element.innerHTML);
The code itself, unchanged, is inserted inside this wrapper and executed. If the code calls the getElementById () function, my code will display everything that is stored in innerHTML.
Thus, without changing the code, it becomes possible to determine what and where the script saves.
And in conclusion, I suggest you familiarize yourself with a working example of downloading files from the mediafire.com resource:
Copy Source | Copy HTML- /*
* Copyright (C) AIG
* aignospam at gmail.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/ -
- function jsDecode($code)
- {
- $fh = fopen('./code.js', 'w');
- fwrite($fh, 'var element = new Object();element.innerHTML = "";');
- fwrite($fh, 'var parent = new Object();parent.document = new Object();');
- fwrite($fh, 'parent.document.getElementById = function theGetElementByID(x) {print("HTML:" + element.innerHTML);print("\n");print("ELEMENT:" + x + ":");return element;};');
- fwrite($fh, $code);
- fwrite($fh, 'print("HTML:" + element.innerHTML);');
- fclose($fh);
- return `js ./code.js 2>&1`;
- }
-
- function downloadMediafire($url)
- {
- $cookie_file = './cookie.mediafire.txt';
- @unlink($cookie_file);
-
- $user_agent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
-
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
- curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
- curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
- curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
- $result_parent = curl_exec($ch);
-
- $referer = $url;
-
- // search all functions
- if (!preg_match_all("/function\s+([a-z0-9]+)\(qk\,pk\,r\)/", $result_parent, $match_function_names)) {
- print "unable to find generated functions\n";
- print $result_parent;
- return false;
- }
-
- $code_header = '';
- foreach ($match_function_names[1] as $function_name) {
- $code_header .= 'function ';
- $code_header .= $function_name;
- $code_header .= '(qk,pk,r)';
- $code_header .= '{print("KEY:" + qk + ":" + pk + ":" + r + ":" + "' . $function_name . '" + ":");};';
- }
-
- if (!preg_match('/Eo\(\);(.*?eval.*?)if/', $result_parent, $match_code)) {
- print "unable to find key code\n";
- print $result_parent;
- return false;
- }
-
- // decode eval functions...
- $code = jsDecode($code_header . $match_code[1]);
-
- if (!preg_match('/KEY:(.*?):(.*?):(.*?):(.*?):/', $code, $match_key)) {
- print $code;
- return false;
- }
-
- $qk = $match_key[1];
- $pk = $match_key[2];
- $r = $match_key[3];
-
- $valid_function_name = $match_key[4];
-
- // search for visible element...
- if (!preg_match('/function ' . $valid_function_name . '\(.*?document.getElementById\(\'(.{32})\'\)/', $result_parent, $match_id)) {
- print $result_parent;
- return false;
- }
-
- $element_id = $match_id[1];
-
- $url = 'http://www.mediafire.com/dynamic/download.php?qk=' . $qk . '&pk=' . $pk . '&r=' . $r;
-
- print "URL=$url\n";
-
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_REFERER, $referer);
- $result_fetch = curl_exec($ch);
- curl_close($ch);
-
- if (!preg_match('/(var\s+et\s*=\s*15.*?)function/', $result_fetch, $match_header)) {
- print "unable to find link header\n";
- print $result_fetch;
- return false;
- }
-
- $code_header = $match_header[1];
-
- if (!preg_match('/case\s+15:(.*?)break;/', $result_fetch, $match_code)) {
- print "unable to find link code\n";
- print $result_fetch;
- return false;
- }
-
- // decode eval functions...
- $code = jsDecode($code_header . $match_code[1]);
-
- if (!preg_match('/' . $element_id . '.*?href="http:\/\/([^"]+)"/', $code, $match_url)) {
- print "unable to find element url\n";
- print $code;
- return false;
- }
-
- $file_url = $match_url[1];
-
- print "URL=$file_url\n";
-
- $file = basename($file_url);
- $url = "http://$file_url";
-
- if (file_exists($file)) {
- return true;
- }
-
- $fp = fopen($file, 'w');
-
- $ch = curl_init($url);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch,CURLOPT_USERAGENT, $user_agent);
- curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
- curl_setopt($ch,CURLOPT_COOKIEJAR, $cookie_file);
- curl_setopt($ch,CURLOPT_COOKIEFILE, $cookie_file);
- curl_setopt($ch,CURLOPT_REFERER, $referer);
- curl_setopt($ch, CURLOPT_FILE, $fp);
- $result = curl_exec($ch);
- $info = curl_getinfo($ch);
- curl_close($ch);
-
- fclose($fp);
-
- if ($info['http_code'] != 200) {
- print_r($info);
- return false;
- }
-
- return true;
- }
-