您好,登錄后才能下訂單哦!
這篇文章主要為大家分析了如何深入理解$_REQUESTS數組的相關知識點,內容詳細易懂,操作細節合理,具有一定參考價值。如果感興趣的話,不妨跟著跟隨小編一起來看看,下面跟著小編一起深入學習“如何深入理解$_REQUESTS數組”的知識吧。
題目叫做詩,代碼如下:
漏洞解析 :
這道題目包含了兩個漏洞,利用這兩個漏洞,我們可以往FTP連接資源中注入惡意數據,執行FTP命令。首先看到 第7行 代碼,可以發現程序使用 cleanInput 方法過濾 GET 、 POST 、 COOKIE 數據,將他們強制轉成整型數據。然而在 第8行 處,卻傳入了一個從 REQUEST 方式獲取的 mode 變量。我們都知道超全局數組 $_REQUEST 中的數據,是 $_GET 、 $_POST 、 $_COOKIE 的合集,而且數據是復制過去的,并不是引用。我們先來看一個例子,來驗證這一觀點:
可以發現 REQUEST 數據絲毫不受過濾函數的影響。回到本例題,例題中的程序過濾函數只對 GET 、 POST 、 COOKIE 數據進行操作,最后拿來用的卻是 REQUEST 數據,這顯然會存在安全隱患。想了解更多 $_REQUEST 信息,大家自己上官網學習。第二個漏洞的話,在代碼 第21行 ,這里用了 == 弱比較。關于這個問題,我們在前面的文章中講的也很細致了,大家可以參考:[紅日安全]PHP-Audit-Labs題解之Day1-4 (Day4)。
至于本次案例的攻擊payload,可以使用: ?mode=1%0a%0dDELETE%20test.file ,這個即可達到刪除FTP服務器文件的效果。
本次實例分析,我們分析的是 WordPress 的 All In One WP Security & Firewall 插件。該插件在 4.1.4 - 4.1.9 版本中存在反射型XSS漏洞,漏洞原因和本次案例中的漏洞成因一致,官方也在 4.2.0 版本中修復了該漏洞。本次,我們將以 4.1.4 版本插件作為案例講解。
將下載下來的插件zip包,通過后臺插件管理上傳壓縮包安裝即可。本次發生問題的文件在于 wp-content\plugins\all-in-one-wp-security-and-firewall\admin\wp-security-dashboard-menu.php ,為了方便大家理解,我將問題代碼抽取出來,簡化如下:
我們可以很清晰的看到,問題就出在 第25行 的 render_tab3 方法中,這里直接將 REQUEST 方式獲取的 tab 變量拼接并輸出。而實際上,在 第20行 已經獲取了經過過濾處理的 $tab 變量。我們來看一下 get_current_tab 方法:
過濾函數的調用鏈如下圖 第1行 ,接著 $tab 變量就會經過 wp_check_invalid_utf8 方法的檢測。
下面我們來看看攻擊 payload (向 http://website/wp-admin/admin.php?page=aiowpsec&tab=tab3 POST數據 tab="><script>alert(1)</script>
):
可以看到成功引發XSS攻擊。我們最后再根據 payload 對代碼的調用過程進行分析。首先,我們的 payload 會傳入 wp-admin/admin.php 文件中,最后進入 第14行 的 do_action('toplevel_page_aiowpsec'); 代碼。
在 wp-includes/plugin.php 文件中,程序又調用了 WP_Hook 類的 do_action 方法,該方法調用了自身的 apply_filters 方法。
然后 apply_filters 方法調用了 wp-content\plugins\all-in-one-wp-security-and-firewall\admin\wp-security-admin-init.php 文件的 handle_dashboard_menu_rendering 方法,并實例化了一個 AIOWPSecurity_Dashboard_Menu 對象。
接下來就是開頭文章分析的部分,也就是下面這張圖片:
整個漏洞的攻擊鏈就如下圖所示:
這里還有一個小知識點要提醒大家的是,案例中 $_REQUEST["tab"] 最后取到的是 $_POST["tab"] 的值,而不是 $_GET["tab"] 變量的值。這其實和 php.ini 中的 request_order 對應的值有關。例如在我的環境中, request_order 配置如下:
這里的 "GP" 表示的是 GET 和 POST ,且順序從左往右。例如我們同時以 GET 和 POST 方式傳輸 tab 變量,那么最終用 $_REQUEST['tab'] 獲取到的就是 $_POST['tab'] 的值。更詳細的介紹可以看如下PHP手冊的定義:
request_order string This directive describes the order in which PHP registers GET, POST and Cookie variables into the _REQUEST array. Registration is done from left to right, newer values override older values. If this directive is not set, variables_order is used for $_REQUEST contents. Note that the default distribution php.ini files does not contain the 'C' for cookies, due to security concerns.
對于這個漏洞的修復方案,我們只要使用過濾后的 $tab 變量即可,且變量最好經過HTML實體編碼后再輸出,例如使用 htmlentities 函數等。
看完了上述分析,不知道大家是否對 $_REQUEST 數組有了更加深入的理解,文中用到的 CMS 可以從這里( All In One WP Security & Firewall )下載,當然文中若有不當之處,還望各位斧正。如果你對我們的項目感興趣,歡迎發送郵件到 hongrisec@gmail.com 聯系我們。Day16 的分析文章就到這里,我們最后留了一道CTF題目給大家練手,題目如下:
// index.php <?php function check_inner_ip($url) { $match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url); if (!$match_result){ die('url fomat error1'); } try{ $url_parse=parse_url($url); } catch(Exception $e){ die('url fomat error2'); } $hostname=$url_parse['host']; $ip=gethostbyname($hostname); $int_ip=ip2long($ip); return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16 || ip2long('0.0.0.0')>>24 == $int_ip>>24; } function safe_request_url($url) { if (check_inner_ip($url)){ echo $url.' is inner ip'; } else{ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $output = curl_exec($ch); $result_info = curl_getinfo($ch); if ($result_info['redirect_url']){ safe_request_url($result_info['redirect_url']); } curl_close($ch); var_dump($output); } } $url = $_POST['url']; if(!empty($url)){ safe_request_url($url); } else{ highlight_file(__file__); } //flag in flag.php ?>
// flag.php <?php if (! function_exists('real_ip') ) { function real_ip() { $ip = $_SERVER['REMOTE_ADDR']; if (is_null($ip) && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) { foreach ($matches[0] AS $xip) { if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) { $ip = $xip; break; } } } elseif (is_null($ip) && isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (is_null($ip) && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) { $ip = $_SERVER['HTTP_CF_CONNECTING_IP']; } elseif (is_null($ip) && isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) { $ip = $_SERVER['HTTP_X_REAL_IP']; } return $ip; } } $rip = real_ip(); if($rip === "127.0.0.1") die("HRCTF{SSRF_can_give_you_flag}"); else die("You IP is {$rip} not 127.0.0.1"); ?>
關于“如何深入理解$_REQUESTS數組”就介紹到這了,更多相關內容可以搜索億速云以前的文章,希望能夠幫助大家答疑解惑,請多多支持億速云網站!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。