• PHP反序列化字符串逃逸


    php序列化和反序列化概念

    序列化是对象串行化,对象是一种在内存中存储的数据类型,寿命是随生成该对象的程序的终止而终止,为了持久使用对象的状态,将其通过serialize()函数进行序列化为一行字符串保存为文件,使用时再用unserialize()反序列化为对象。

    serialize 将对象格式化成有序的字符串
    unserialize 将字符串还原成原来的对象

    php序列化字符串从短变长

    Php在反序列化时,底层代码是以;作为字段的分隔,以 } 作为结尾,并且是根据长度判断内容的 ,同时反序列化的过程中必须严格按照序列化规则才能成功实现反序列化 。
    先来做个小实验:
    在这里插入图片描述
    序列化lt对象并输出,s代表类型,后边的数字代表长度,当使用正则来替换掉admin时,会发现:
    在这里插入图片描述
    发现只有admin变成了hacker,但长度没变,此时如果再将其反序列化时回因为长度无法匹配而报错。
    在这里插入图片描述
    这个是输出没有替换之前的对象,可以正常输出。
    在这里插入图片描述
    当输出替换之后的数据时回显false,此时猜想一下,如果我们自行让其匹配会发生什么变化。
    在这里插入图片描述
    我们使多出的长度刚好可以与impo后边的字符串长度匹配,需要41个admin。
    在这里插入图片描述
    此时可以发现,md51和md52的值已经改变,逃逸成功。
    字符逃逸CTF例题的思路,改变序列化字符串中某一值的长度,从而导致反序列化漏洞,所以在代码审计时如果发现了正则表达式的搜索和替换,并且需要修改一个序列化字符串中的值时可以往这方面考虑,但要注意几个点:

    1. 正则替换时前后替换字符有长度的差别,一般都是代码中本身就有的正则替换。
    2. 看准需要传进去变量的类型,数组类型和简单的字符类型需要传入的值是不一样的。

    例题:[0CTF 2016]piapiapia

    打开后发现一个登录框,盲猜有注册页面,访问/register.php。
    注册后登录,之后没有其他的提示,尝试sql注入和文件上传无果。
    扫一下目录发现www.zip源码泄露,开始审计。

    发现profile.php中存在任意文件读取。
    在这里插入图片描述
    又发现flag在config.php中。
    在这里插入图片描述
    理清思路,利用任意文件读取漏洞,读取config.php文件即可。
    因为photo是$profile中的值,跟着其走一下。
    在这里插入图片描述首先跳到了show_profile。
    在这里插入图片描述
    然后再到filter,是一个正则匹配替换,匹配之后再返回去。
    在这里插入图片描述
    继续又调用了父类的select函数。
    在这里插入图片描述
    Sql语句,将表中的内容取出来,所以查询有关表的插入语句。
    在这里插入图片描述
    发现了update,继续找哪里有update的利用点,在updata.php中发现其利用点。
    在这里插入图片描述
    Profile的值是通过POST传入,但photo的值是md5哈希编码后的值,无法直接控制。
    最后想到了在中间有一段匹配替换,可以利用字符串逃逸,直接更改profile的值。
    刚好替换的where和hacker长度相差1。
    在这里插入图片描述
    构造后,将需要的地方截取下来,然后计算其长度。
    直接传入后,一直无法成功,之后发现nickname存在过滤。
    在这里插入图片描述
    可以利用数组绕过。
    因为nickname传入为数组,改一下payload。
    "};s:5:“photo”;s:10:“config.php”;}长度变成了34。
    Paylaod:

    wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
    
    • 1

    注意传入时nickname变成数组形式。
    在这里插入图片描述
    最后信息是以图片的形式返回的,所以flag在图片的编码里。
    在这里插入图片描述
    base64解码得到flag。

    字符串由长变短

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    先本地试一下,在这里插入代码片和上边一样。
    在这里插入图片描述
    然后将php变成空格试一下。
    在这里插入图片描述
    在这里可以理解一下,字符串缩短的方法是让本来的前边一部分代替我们删除的字符,然后在让其提前闭合,主要还是前后可以刚好匹配。
    合适的例题没找的,不然就是太简单,不然就是太难,之后再补充。

  • 相关阅读:
    JVM内存模型概述
    每天一个知识点- 线程池中线程执行任务发生异常会怎么样
    Java架构师分析和设计技术架构
    PyTorch深度学习实战(5)——计算机视觉基础
    Java注释:单行、多行和文档注释
    QT DAY2
    python使用python-docx库处理图片白框问题
    【Network】网络编程套接字 —— socket编程
    Android开发APP显示头部Bar
    MySQL(3)
  • 原文地址:https://blog.csdn.net/akxnxbshai/article/details/127430808