zl程序教程

您现在的位置是:首页 >  后端

当前栏目

PHP反序列化练习册

PHP 序列化
2023-09-27 14:28:02 时间

0x01、PHP反序列化练习册

1.pass-[间接修改密码]-[反序列化字符逃逸]-[关键词变长]-[本地复现]

提示:
对于反序列化字符逃逸关键词变长的情况,形如以下情况:
(1)两个连续的键值对,只有第一个键值对的值可控
(2)先序列化,后过滤,过滤之后关键词变长,导致第一个键值对的值可以逃逸出来
	//比如200个字符长度,变为300个字符串长度
	//那么假如我们一开始传入200长度+2长度的闭合+剩下97长度的自定义序列化字符串+1长度的}抛弃
	//对于最后的1长度}抛弃,视情况而定
<!--以如下代码为例,如何在不直接修改$pass值的情况下间接修改$pass的值-->
<?php
function filter($str){
    return str_replace('bb', 'ccc', $str);
}
class A{
    public $name='aaaa';
    public $pass='123456';
}


$AA=new A();
$res=filter(serialize($AA));
$c=unserialize($res);
echo $c->pass;
?>

2.unserialize3-[EEEEEEEEEEEEEEEEEEEEEasy反序列化]-[传送门->XCTF]

class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=

3.Web_php_unserialize-[CVE-2016-7124]-[传送门->XCTF]

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

4.unserialize-[GIT信息泄露+Easy反序列化]-[本地复现]

点击这里下载GIT信息提权工具

使用git_extract.py,提取网站的git信息:
	python  git_extract.py  http://10.198.99.127:8026/.git/ 

webshell_d5f6d142a4383e40.php

<?php
class site{			
    public $name;	
    public $title;	
    
    function __destruct(){	
       $a = $this->name;	
       $a($this->title);
    }
}

unserialize($_POST['dage']);	
?>

5.easy_serialize_php-[安洵杯 2019]-[反序列化字符逃逸]-[关键词变少]-[传送门->BUUCTF]

/**
 * 先序列化,后过滤,导致关键词变少
 * 利用上面的机制,只要存在两个连续的可控键值对,那么第一个键值对的值可以覆盖第二个键值对的键(或者说二者拼接成为第一个键值对的值),从而形成第一个键值对的值,然后第二个键值对的值就逃逸了出来
 * 如果我们让这个逃逸出来的值,让它在序列化和过滤之前,本身就是一个键值对,那么此时此刻,就从值变成了一个键值对了,假如后面还有键值对,那么我们一开始就构造两个键值对的序列化字符串,然后使用}抛弃即可
 */
<?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']));
}

6.NiZhuanSiWei-[ZJCTF 2019]-[PHP伪协议]-[传送门->BUUCTF]

index.php

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

useless.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");
        }
    }
}

7.BUU CODE REVIEW 1-[传送门->BUUCTF]

<?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']);
        }
    }
}

8.AreUSerialz-[网鼎杯 2020 青龙组]-[传送门->BUUCTF]

linux提供了/proc/self/目录,这个目录比较独特,不同的进程访问该目录时获得的信息是不同的,内容等价于/proc/本进程pid/。进程可以通过访问/proc/self/目录来获取自己的信息。

/proc/self/cmdline 		程序运行的绝对路径
<?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);
    }

}

9.PHP-[极客大挑战 2019]-[传送门->BUUCTF]

git clone https://github.com/maurosoria/dirsearch.git

cd ./dirsearch

python3 dirsearch.py -u xxx -e php

//结果:www.zip

index.php

<?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
?>

class.php

<?php
include 'flag.php';


error_reporting(0);


class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

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

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->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;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>

10.phpweb-[网鼎杯 2020 朱雀组]-[传送门->BUUCTF]

图略

func=file_get_contents&p=index.php
func=highlight_file&p=index.php
func=readfile&p=index.php
 <?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...");
        }
    }
?>

11.duwentao-[本地复现]

<?php
#error_reporting(0);
class SoFun
{
	protected $file = 'index.php';
	public function __construct($file)
	{
		$this->file = $file;
	}
	
	function __destruct()
	{
		if(!empty($this->file))
		{
			if(strchr($this->file,"\\")===false && strchr($this->file,'/')===false)
				show_source(dirname(__FILE__).'/'.$this->file);
			else
 				die('Wrong filename.');
		}
	}
	
	function __wakeup()
	{
		$this->file = 'index.php';
	}
	
	public function __toString()
	{
		return '';
 	}
 }


if(!isset($_GET['file'])){
	show_source('duwentao.php');
}else{
	$file = base64_decode($_GET['file']);
	echo unserialize($file);
}
?>
<!--key in flag.php-->

12.Php_is_the_best_language.php-[ISCC2020]-[本地复现]

<?php
@error_reporting(1);
include 'flag.php';
class baby
{
    public $file;
    function __toString()
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}


if (isset($_GET['data']))
{
    $data = $_GET['data'];
        $good = unserialize($data);
        echo $good;
}else
{
    $url='./index.php';
}

$html='';
if(isset($_POST['test'])){
    $s = $_POST['test'];
    $html.="<p>谢谢参与!</p>";
}
?>

13.ping-[pop链]-[本地复现]

<?php
class getip{                       
    public $ip;                    
    function __construct()        
    {
        $this->ip = "127.0.0.1";    
    }
    function __destruct()          
    {
        echo 'The ip is' .$this->ip;
    }
}

class getresult{                   
    public $obj;                  
    public $ip;                  
    function __construct()       
    {
        $this->ip = "127.0.0.1";   
        $this->obj = null;         
    }
    function __toString()
    {
        $this->obj->execute();
        return $this->ip;
    }
}

class ping{
    private $ip;
    function execute(){
        $str = 'ping '.$this->ip;
        system($str);
    }
}


unserialize(base64_decode($_GET['ip']));
?>
<!--flag.php-->	

14.Ezpop-[MRCTF2020]-[pop链]-[传送门->BUUCTF]

Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}


if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
}
?>

15.serialize1-[传送门->testBugku]

<?php
show_source("index.php");							
//error_reporting(0);							
	
class test{											
    public $username;								
    public $password;								

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

    function __destruct(){				 
        $info = 'your secret is '.$this->password;	
        echo $info;									
    }
}

class exam{											
    public $file;									
    function __toString(){							
        //flag.php									
        echo file_get_contents($this->file);		
        return 'nice';								
    }
}


$text = $_GET['text'];								
$res = unserialize($text);	
?>

16.what_we_can_do.-[反序列化字符串逃逸]-[关键词变长]-[本地复现]

<?php
error_reporting(255);							

class A{									
	public $filename = __FILE__;				
	public function __destruct(){				
		highlight_file($this->filename);		
	}
}

function waf($s){								
	return preg_replace('/flag/i','index',$s);	index
}


if(isset($_REQUEST['x']) && is_string($_REQUEST['x'])){		
	$a = [
		0 => $_REQUEST['x'],								
		1 => "1"
	];
	@unserialize(waf(serialize($a)));						
}else{
	new A();
}
?>
<!--flag.php-->									

17.easytrick-[CISCN2020]-[本地复现]

<?php
class trick{			
    public $trick1;		
    public $trick2;		
    public function __destruct(){	
        $this->trick1 = (string)$this->trick1;	
        if(strlen($this->trick1) > 5 || strlen($this->trick2) > 5){
            die("你太长了");										
        }
        if($this->trick1 !== $this->trick2 && md5($this->trick1) === md5($this->trick2) && $this->trick1 != $this->trick2){
            echo file_get_contents("./flag.php");		
        }
    }
}


highlight_file(__FILE__);							
unserialize($_GET['trick']);	
?>