From 8d805c550f1114c59094d9c7515a66cc04faecad Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Tue, 22 May 2012 16:41:29 +0100 Subject: [PATCH] Started working on the Evasion/Obfuscation extension. Added scrambler, minifier and base64 encoder in the chain. --- Gemfile | 1 + config.yaml | 4 +- core/main/handlers/modules/beefjs.rb | 9 +++- extensions/evasion/config.yaml | 24 ++++++++++ extensions/evasion/evasion.rb | 52 ++++++++++++++++++++++ extensions/evasion/extension.rb | 31 +++++++++++++ extensions/evasion/obfuscation/base_64.rb | 42 +++++++++++++++++ extensions/evasion/obfuscation/minify.rb | 31 +++++++++++++ extensions/evasion/obfuscation/scramble.rb | 48 ++++++++++++++++++++ 9 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 extensions/evasion/config.yaml create mode 100644 extensions/evasion/evasion.rb create mode 100644 extensions/evasion/extension.rb create mode 100644 extensions/evasion/obfuscation/base_64.rb create mode 100644 extensions/evasion/obfuscation/minify.rb create mode 100644 extensions/evasion/obfuscation/scramble.rb diff --git a/Gemfile b/Gemfile index a4035422e..cd4bb331e 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,7 @@ end gem "thin" gem "sinatra", "1.3.2" gem "em-websocket", "~> 0.3.6" +gem "jsmin", "~> 1.0.1" gem "ansi" gem "term-ansicolor", :require => "term/ansicolor" gem "dm-core" diff --git a/config.yaml b/config.yaml index 2c09eac85..beff063f8 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,7 @@ beef: version: '0.4.3.5-alpha' - debug: false + debug: true restrictions: # subnet of browser ip addresses that can hook to the framework @@ -86,3 +86,5 @@ beef: console: shell: enable: false + evasion: + enable: false diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 7b1c9bc44..2b8125c11 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -73,7 +73,14 @@ module Modules # @note populate place holders in the beefjs string and set the response body eruby = Erubis::FastEruby.new(beefjs) - @body << eruby.evaluate(hook_session_config) + @hook = eruby.evaluate(hook_session_config) + + if config.get("beef.extension.evasion.enable") + evasion = BeEF::Extension::Evasion::Evasion.instance + @hook = evasion.obfuscate(@hook) + end + + @body << @hook end diff --git a/extensions/evasion/config.yaml b/extensions/evasion/config.yaml new file mode 100644 index 000000000..d8603a43d --- /dev/null +++ b/extensions/evasion/config.yaml @@ -0,0 +1,24 @@ +# +# 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. +# +beef: + extension: + evasion: + enable: true + name: 'Evasion' + authors: ["antisnatchor"] + scramble_variables: true + to_scramble: ["beef", "Beef"] + chain: ["scramble","minify","base_64"] \ No newline at end of file diff --git a/extensions/evasion/evasion.rb b/extensions/evasion/evasion.rb new file mode 100644 index 000000000..1ce45b1e7 --- /dev/null +++ b/extensions/evasion/evasion.rb @@ -0,0 +1,52 @@ +# +# 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. +# +module BeEF + module Extension + module Evasion + class Evasion + include Singleton + @@config = BeEF::Core::Configuration.instance + @@techniques = @@config.get('beef.extension.evasion.chain') + + def initialize + end + + # Obfuscate the input JS applying the chain of techniques defined in the main config file. + def obfuscate(input) + @input = apply_chain(input, @@techniques) + end + + def apply_chain(input, techniques) + @output = input + 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) + klass = klass.instance + @output = klass.execute(@output, @@config) + end + @output + end + @output + end + end + end + end +end + diff --git a/extensions/evasion/extension.rb b/extensions/evasion/extension.rb new file mode 100644 index 000000000..dc81f5200 --- /dev/null +++ b/extensions/evasion/extension.rb @@ -0,0 +1,31 @@ +# +# 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. +# +module BeEF +module Extension +module Evasion + extend BeEF::API::Extension + + @short_name = 'evasion' + @full_name = 'Evasion' + @description = 'Contains Evasion and Obfuscation techniques to prevent the likelihood that BeEF will be detected' +end +end +end + +require 'extensions/evasion/evasion' +require 'extensions/evasion/obfuscation/scramble' +require 'extensions/evasion/obfuscation/minify' +require 'extensions/evasion/obfuscation/base_64' diff --git a/extensions/evasion/obfuscation/base_64.rb b/extensions/evasion/obfuscation/base_64.rb new file mode 100644 index 000000000..3febac602 --- /dev/null +++ b/extensions/evasion/obfuscation/base_64.rb @@ -0,0 +1,42 @@ +# +# 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. +# +module BeEF + module Extension + module Evasion + class Base_64 + include Singleton + + def random_string(length=5) + chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' + result = '' + length.times { result << chars[rand(chars.size)] } + result + 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 = random_string(3) + input = "var #{var_name}=\"#{encoded}\";#{decode_function}eval(dec(#{var_name}));" + print_debug "[OBFUSCATION - BASE64] Javascript has been base64'ed'" + input + end + end + end + end +end + diff --git a/extensions/evasion/obfuscation/minify.rb b/extensions/evasion/obfuscation/minify.rb new file mode 100644 index 000000000..ec15424d5 --- /dev/null +++ b/extensions/evasion/obfuscation/minify.rb @@ -0,0 +1,31 @@ +# +# 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. +# +module BeEF + module Extension + module Evasion + require 'jsmin' + class Minify + include Singleton + def execute(input, config) + input = JSMin.minify(input) + print_debug "[OBFUSCATION - MINIFIER] Javascript has been minified" + input + end + end + end + end +end + diff --git a/extensions/evasion/obfuscation/scramble.rb b/extensions/evasion/obfuscation/scramble.rb new file mode 100644 index 000000000..c1450ee38 --- /dev/null +++ b/extensions/evasion/obfuscation/scramble.rb @@ -0,0 +1,48 @@ +# +# 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. +# +module BeEF + module Extension + module Evasion + class Scramble + include Singleton + + def random_string(length=5) + chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' + result = '' + length.times { result << chars[rand(chars.size)] } + result + end + + def execute(input, config) + to_scramble = config.get('beef.extension.evasion.to_scramble') + to_scramble.each do |var| + mod_var = random_string + input = input.gsub!(var,random_string) + print_debug "[OBFUSCATION - SCRAMBLER] string [#{var}] scrambled -> [#{mod_var}]" + + #todo: add scrambled vars to an Hash. + #todo: even better. Add them to the Configuration object, like "beef" => "cnjD3" + #@@to_scramble = config.get('beef.http.evasion.scramble_variables') + #@@scrambled = Hash.new + end + input + end + + end + end + end +end +