📜 ⬆️ ⬇️

Decrypt Javascript on the example of file hosting mediafire.com

Nowadays, javascript encryption on sites is gaining popularity with the help of nested eval commands. I recently encountered this encryption on mediafire.com file hosting. Encryption was unusual, I was interested and I decided to understand how well this method works.

The site mediafire.com allows you to download files without captcha and at the same time, recently, it has become quite successful in defending against all kinds of automatic robots. It does this using the built-in javascript code generator. Moreover, the code is created new each time, which makes it difficult to emulate automatic means.

In this article, I will discuss how it is very easy to bypass such protection without deep analysis of the encrypted code and create an automatic script to download files from mediafire.com.

First, let me show you how the code looks like:
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);
  1. 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);
  2. 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);
  3. 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);
  4. 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, with each access to the page, the code changes: the encryption codes (XOR) change, the eval nesting changes, the names of variables and functions change.
')
The code calls one of the N functions (generated in html), which in turn turns on 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 the links to the pseudo-correct path to the file download to all blocks and writes the correct path to only one of these blocks.

So, we need to solve the problem of automatically downloading files from such
system.

Draw up a plan of action.

1. Download the main page, decrypt and determine which of the N functions is called and 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 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 it. Therefore, I offer you a different way, namely the emulation of some functions of the browser.

We will solve this problem with the attraction of improvised means: spidermonkey .

Install spidermonkey on the system (in my FreeBSD example):

cd /usr/ports/lang/spidermonkey
make install clean

The biggest problem I encountered is that it is not known in advance where exactly the executable code will save the links and what function it will call. In order not to parse the code itself, I created some similarity to the getElementById () function, the function is used to load values ​​into a specific HTML element. I did it like this:
Copy Source | Copy HTML
  1. var element = new Object ();
  2. element.innerHTML = "" ;
  3. var parent = new Object ();
  4. parent.document = new Object ();
  5. parent.document.getElementById = function theGetElementByID ( x ) {
  6. print ( "HTML:" + element.innerHTML );
  7. print ( "\ n" );
  8. print ( "ELEMENT:" + x + ":" );
  9. return element;
  10. };
  11. // INSERT CODE HERE
  12. 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 saved in innerHTML.

Thus, without changing the code, it becomes possible to determine what and where the script is stored.

And in conclusion, I suggest that you familiarize yourself with the working example of downloading files from mediafire.com:
Copy Source | Copy HTML
  1. / * <br/> * Copyright (C) AIG <br/> * aignospam at gmail.com * * modification , </ i * * met: < br /> * 1. You must have your copyright code . <br/> * 2. Redistributions in binary form should be noted . <br/> * <br/> THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `` AS IS '' AND <br/> * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE <br/> * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE <br/> * ARE DISCLAIMED. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL <br /> * DAMAGES (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS <br/> * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY <br/> * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF <br/> * SUCH DAMAGE. <br/> * /
  2. function jsDecode ( $ code )
  3. {
  4. $ fh = fopen ( './code.js' , 'w' );
  5. fwrite ( $ fh , 'var element = new Object (); element.innerHTML = "";' );
  6. fwrite ( $ fh , 'var parent = new Object (); parent.document = new Object ();' );
  7. fwrite ( $ fh , 'parent.document.getElementById = function theGetElementByID (x) {print ("HTML:" + element.innerHTML); print ("\ n"); print ("ELEMENT:" + x + ":" ); return element;}; ' );
  8. fwrite ( $ fh , $ code );
  9. fwrite ( $ fh , 'print ("HTML:" + element.innerHTML);' );
  10. fclose ( $ fh );
  11. return `js ./code.js 2 > & 1`;
  12. }
  13. function downloadMediafire ( $ url )
  14. {
  15. $ cookie_file = './cookie.mediafire.txt' ;
  16. @unlink ( $ cookie_file );
  17. $ user_agent = "Mozilla / 4.0 (compatible; MSIE 5.01; Windows NT 5.0)" ;
  18. $ ch = curl_init ( $ url );
  19. curl_setopt ( $ ch , CURLOPT_RETURNTRANSFER, 1 );
  20. curl_setopt ( $ ch , CURLOPT_USERAGENT, $ user_agent );
  21. curl_setopt ( $ ch , CURLOPT_FOLLOWLOCATION, 1 );
  22. curl_setopt ( $ ch , CURLOPT_COOKIEJAR, $ cookie_file );
  23. curl_setopt ( $ ch , CURLOPT_COOKIEFILE, $ cookie_file );
  24. $ result_parent = curl_exec ( $ ch );
  25. $ referer = $ url ;
  26. // search all functions
  27. if (! preg_match_all ( "/ function \ s + ([a-z0-9] +) \ (qk \, pk \, r \) /" , $ result_parent , $ match_function_names )) {
  28. print "unable to find generated functions \ n" ;
  29. print $ result_parent ;
  30. return false ;
  31. }
  32. $ code_header = '' ;
  33. foreach ( $ match_function_names [ 1 ] as $ function_name ) {
  34. $ code_header . = 'function' ;
  35. $ code_header . = $ function_name ;
  36. $ code_header . = '(qk, pk, r)' ;
  37. $ code_header . = '{print ("KEY:" + qk + ":" + pk + ":" + r + ":" + "' . $ function_name . '" + ":");};' ;
  38. }
  39. if (! preg_match ( '/Eo\(\\;;(.*?eval.*?)if/' , $ result_parent , $ match_code )) {
  40. print "unable to find key code \ n" ;
  41. print $ result_parent ;
  42. return false ;
  43. }
  44. // decode eval functions ...
  45. $ code = jsDecode ( $ code_header . $ match_code [ 1 ]);
  46. if (! preg_match ( '/KEY:(.*?):(.*?):(.*?):(.*?):/' , $ code , $ match_key )) {
  47. print $ code ;
  48. return false ;
  49. }
  50. $ qk = $ match_key [ 1 ];
  51. $ pk = $ match_key [ 2 ];
  52. $ r = $ match_key [ 3 ];
  53. $ valid_function_name = $ match_key [ 4 ];
  54. // search for visible element ...
  55. if (! preg_match ( '/ function' . $ valid_function_name . '\ (. *? document.getElementById \ (\' (. {32}) \ '\) /' , $ result_parent , $ match_id )) {
  56. print $ result_parent ;
  57. return false ;
  58. }
  59. $ element_id = $ match_id [ 1 ];
  60. $ url = 'http://www.mediafire.com/dynamic/download.php?qk=' . $ qk . '& pk =' . $ pk . '& r =' . $ r ;
  61. print "URL = $ url \ n" ;
  62. curl_setopt ( $ ch , CURLOPT_URL, $ url );
  63. curl_setopt ( $ ch , CURLOPT_REFERER, $ referer );
  64. $ result_fetch = curl_exec ( $ ch );
  65. curl_close ( $ ch );
  66. if (! preg_match ( '/(var\s+et\s*=\s*15.*?)function/' , $ result_fetch , $ match_header )) {
  67. print "unable to find link header \ n" ;
  68. print $ result_fetch ;
  69. return false ;
  70. }
  71. $ code_header = $ match_header [ 1 ];
  72. if (! preg_match ( '/case\s+15: ( ..??)break;/' , $ result_fetch , $ match_code )) {
  73. print "unable to find link code \ n" ;
  74. print $ result_fetch ;
  75. return false ;
  76. }
  77. // decode eval functions ...
  78. $ code = jsDecode ( $ code_header . $ match_code [ 1 ]);
  79. if (! preg_match ( '/' . $ element_id . '. *? href = "http: \ / \ / ([^"] +) "/' , $ code , $ match_url )) {
  80. print "unable to find element url \ n" ;
  81. print $ code ;
  82. return false ;
  83. }
  84. $ file_url = $ match_url [ 1 ];
  85. print "URL = $ file_url \ n" ;
  86. $ file = basename ( $ file_url );
  87. $ url = "http: // $ file_url" ;
  88. if (file_exists ( $ file )) {
  89. return true ;
  90. }
  91. $ fp = fopen ( $ file , 'w' );
  92. $ ch = curl_init ( $ url );
  93. curl_setopt ( $ ch , CURLOPT_RETURNTRANSFER, 1 );
  94. curl_setopt ( $ ch , CURLOPT_USERAGENT, $ user_agent );
  95. curl_setopt ( $ ch , CURLOPT_FOLLOWLOCATION, 1 );
  96. curl_setopt ( $ ch , CURLOPT_COOKIEJAR, $ cookie_file );
  97. curl_setopt ( $ ch , CURLOPT_COOKIEFILE, $ cookie_file );
  98. curl_setopt ( $ ch , CURLOPT_REFERER, $ referer );
  99. curl_setopt ( $ ch , CURLOPT_FILE, $ fp );
  100. $ result = curl_exec ( $ ch );
  101. $ info = curl_getinfo ( $ ch );
  102. curl_close ( $ ch );
  103. fclose ( $ fp );
  104. if ( $ info [ 'http_code' ]! = 200 ) {
  105. print_r ( $ info );
  106. return false ;
  107. }
  108. return true ;
  109. }

Source: https://habr.com/ru/post/87705/


All Articles