一堆乱码,什么都没有. 查看源代码也没有什么隐藏信息. 于是dirsearch扫描一下,发现 有个数据库登入页面. 发现不用登录直接就可以进去了. 但是发现这里面什么都没有.
这个漏洞出现在index.php中的
// If we have a valid target, let's load that script instead if (! empty($_REQUEST['target']) && is_string($_REQUEST['target']) && ! preg_match('/^index/', $_REQUEST['target']) && ! in_array($_REQUEST['target'], $target_blacklist) && Core::checkPageValidity($_REQUEST['target']) ) { include $_REQUEST['target']; exit; }部分. 这里可以看到一共有5层过滤,5层过滤后有一个文件包含.通过这个文件包含我们可以逐级尝试得到flag. 于是思路就是绕过这5层. 第一,第二,第三层是很好绕过的. 第四层是判断$_REQUEST[‘target’]是否在数组$target_blacklist中.
$target_blacklist = array ( 'import.php', 'export.php' );可以看到数组$target_blacklist也是很好绕过的.(就两个元素). 然后我们来到checkPageValidity函数.
public static function checkPageValidity(&$page, array $whitelist = []) { if (empty($whitelist)) { $whitelist = self::$goto_whitelist; } if (! isset($page) || !is_string($page)) { return false; } if (in_array($page, $whitelist)) { return true; } $_page = mb_substr( $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } $_page = urldecode($page); $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } return false; }第一个if是判断数组 w h i t e l i s t 是 否 为 空 , 显 然 这 里 我 们 并 没 有 赋 值 , 因 此 这 里 是 为 空 . 那 么 whitelist是否为空,显然这里我们并没有赋值,因此这里是为空. 那么 whitelist是否为空,显然这里我们并没有赋值,因此这里是为空.那么whitelist会指向$goto_whitelist数组(白名单). 该数组如下
public static $goto_whitelist = array( 'db_datadict.php', 'db_sql.php', 'db_events.php', 'db_export.php', 'db_importdocsql.php', 'db_multi_table_query.php', 'db_structure.php', 'db_import.php', 'db_operations.php', 'db_search.php', 'db_routines.php', 'export.php', 'import.php', 'index.php', 'pdf_pages.php', 'pdf_schema.php', 'server_binlog.php', 'server_collations.php', 'server_databases.php', 'server_engines.php', 'server_export.php', 'server_import.php', 'server_privileges.php', 'server_sql.php', 'server_status.php', 'server_status_advisor.php', 'server_status_monitor.php', 'server_status_queries.php', 'server_status_variables.php', 'server_variables.php', 'sql.php', 'tbl_addfield.php', 'tbl_change.php', 'tbl_create.php', 'tbl_import.php', 'tbl_indexes.php', 'tbl_sql.php', 'tbl_export.php', 'tbl_operations.php', 'tbl_structure.php', 'tbl_relation.php', 'tbl_replace.php', 'tbl_row_action.php', 'tbl_select.php', 'tbl_zoom_select.php', 'transformation_overview.php', 'transformation_wrapper.php', 'user_password.php', );第二个if不符合条件,不执行. 第三个if显然我们不能让他符合条件,因为如果符合条件的话我们并不能得到想要的结果. 那么来到第四个if.第五个if不得不说这里考虑的很细,还考虑到来url解码. 但是这里是存在漏洞的. 我们可以直接让target=db_datadict.php?/…/…/…/…/…/…/…/…/flag(这里我有些疑问,为什么其他博主的答案都是将’?'换成url编码?) 这里的第一个…/是为了跳出db_datadict.php?/的,显然db_datadict.php?/大概率不是一个目录.所以要先跳过,跳过之后包含的目录就是…/…/…/…/…/…/…/flag了.(一般flag都是在根目录下的,因此多加几个…/,直接回到根目录). flag(不同环境的flag很可能不同)