diff --git a/Gemfile b/Gemfile index 63bffad85..8a3d151b5 100644 --- a/Gemfile +++ b/Gemfile @@ -42,6 +42,7 @@ gem "rubyzip", ">= 1.0.0" gem "rubydns", "0.7.0" # DNS extension gem "geoip" # geolocation support gem "dm-serializer" # network extension +gem "qr4r" # QRcode extension # For running unit tests if ENV['BEEF_TEST'] diff --git a/extensions/qrcode/config.yaml b/extensions/qrcode/config.yaml index d3feb2ff9..0991fa091 100644 --- a/extensions/qrcode/config.yaml +++ b/extensions/qrcode/config.yaml @@ -7,8 +7,8 @@ beef: extension: qrcode: name: 'QR Code Generator' - enable: false - authors: ["xntrik"] - target: ["/demos/basic.html"] - qrsize: "300x300" - + enable: false + authors: ["xntrik", "bcoles"] + targets: ["/demos/basic.html", "http://beefproject.com/"] + qrsize: 3 + qrborder: 1 diff --git a/extensions/qrcode/extension.rb b/extensions/qrcode/extension.rb index 5dc73d376..6cba299bd 100644 --- a/extensions/qrcode/extension.rb +++ b/extensions/qrcode/extension.rb @@ -11,10 +11,10 @@ module Qrcode @short_name = 'qrcode' @full_name = 'QR Code Generator' - @description = 'This extension prints out a link to a QR Code which can be used to hook browsers into BeEF' + @description = 'This extension generates QR Codes for specified URLs which can be used to hook browsers into BeEF.' end end end -require 'extensions/qrcode/qrcode' \ No newline at end of file +require 'extensions/qrcode/qrcode' diff --git a/extensions/qrcode/qrcode.rb b/extensions/qrcode/qrcode.rb index 8b623baab..a09e08d20 100644 --- a/extensions/qrcode/qrcode.rb +++ b/extensions/qrcode/qrcode.rb @@ -13,49 +13,66 @@ module Qrcode def self.pre_http_start(http_hook_server) require 'uri' + require 'qr4r' fullurls = [] - partialurls = [] + # get server config configuration = BeEF::Core::Configuration.instance + beef_proto = configuration.get('beef.http.https.enable') == true ? "https" : "http" + beef_host = configuration.get("beef.http.public") || configuration.get("beef.http.host") + beef_port = configuration.get("beef.http.public_port") || configuration.get("beef.http.port") - configuration.get("beef.extension.qrcode.target").each do |target| + # get URLs from QR config + configuration.get("beef.extension.qrcode.targets").each do |target| if target.lines.grep(/^https?:\/\//i).size > 0 fullurls << target else - partialurls << target - end - end - - if fullurls.size > 0 - print_success "Custom QRCode images available:" - data = "" - fullurls.each do |target| - url = URI.escape(target,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) - data += "https://chart.googleapis.com/chart?cht=qr&chs=#{configuration.get("beef.extension.qrcode.qrsize")}&chl=#{url}\n" - end - print_more data - - end - - if partialurls.size > 0 - BeEF::Core::Console::Banners.interfaces.each do |int| - next if int == "localhost" or int == "127.0.0.1" - print_success "QRCode images available for interface: #{int}" - data = "" - partialurls.each do |target| - url = "http://#{int}:#{configuration.get("beef.http.port")}#{target}" - url = URI.escape(url,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) - data += "https://chart.googleapis.com/chart?cht=qr&chs=#{configuration.get("beef.extension.qrcode.qrsize")}&chl=#{url}\n" + # network interfaces + BeEF::Core::Console::Banners.interfaces.each do |int| + next if int == "0.0.0.0" + fullurls << "#{beef_proto}://#{int}:#{beef_port}#{target}" + end + # beef host + unless beef_host == "0.0.0.0" + fullurls << "#{beef_proto}://#{beef_host}:#{beef_port}#{target}" end - print_more data end end + + unless fullurls.empty? + data = "" + fullurls.uniq.each do |target| + fname = ('a'..'z').to_a.shuffle[0,8].join + qr_path = "extensions/qrcode/images/#{fname}.png" + begin + qr = Qr4r::encode( + target, qr_path, { + :pixel_size => configuration.get("beef.extension.qrcode.qrsize"), + :border => configuration.get("beef.extension.qrcode.qrborder") + }) + rescue + print_error "[QR] Could not write file '#{qr_path}'" + next + end + print_debug "[QR] Wrote file '#{qr_path}'" + BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind( + "/#{qr_path}", "/qrcode/#{fname}", 'png') + data += "#{beef_proto}://#{beef_host}:#{beef_port}/qrcode/#{fname}.png\n" + data += "- URL: #{target}\n" + # Google API + #url = URI.escape(target,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) + #w = configuration.get("beef.extension.qrcode.qrsize").to_i * 100 + #h = configuration.get("beef.extension.qrcode.qrsize").to_i * 100 + #data += "- Google API: https://chart.googleapis.com/chart?cht=qr&chs=#{w}x#{h}&chl=#{url}\n" + end + print_info "QR code images available:" + print_more data + end end end - end end end