LCTF2018-bestphp's revenge
本文最后更新于 2024年10月27日 晚上
前言:今天在学习php的原生类的时候看到的题,学习一下吧。
题目
题目源码
1 |
|
分析
call_user_func()
把第一个参数作为回调函数调用
session反序列化
先看一下3种不同的 session 序列化处理器处理 session 的情况。先看案例代码
1 |
|
当 session.serialize_handler=php 时,session文件内容为: name|s:6:"orange";
当 session.serialize_handler=php_serialize 时,session文件为:a:1:{s:4:"name";s:6:"orange";}
当 session.serialize_handler=php_binary 时,session文件内容为: 二进制字符names:6:"orange";
当session
反序列化和序列化时候使用不同引擎的时候,可以触发漏洞
php引擎会以|
作为key
和value
的分隔符,传入内容时,如下
1 |
|
在使用php_serialize引擎时可以得到序列化内容
1 |
|
然后在进行反序列化的时候|被当做分隔符,于是
1 |
|
这部分会被当做key,然后后面的部分即username
会被当做value
因此传入$_SESSION['name'] = |序列化内容
这样的形式可以构造漏洞
PHP原生类SoapClient
php在安装php-soap拓展后,可以反序列化原生类SoapClient,来发送http post请求。
可以调用其不存在的方法来触发__call
魔术
通过CRLF来添加请求体:SoapClient可以指定请求的user-agent头,通过添加换行符的形式来加入其他请求内容
由于其内置类有__call
方法,当 __call
方法被触发后,它可以发送 HTTP 和 HTTPS 请求。正是这个 __call
方法,使得 SoapClient 类可以被我们运用在 SSRF 中(结合CRLF注入
解题
存在session
反序列化的漏洞,取session的第一项与welcome_to_the_lctf2018
构成数组,进行implode函数拼接
在/flag
下有内容
1 |
|
说明需要我们对ip
进行伪造
思路大体是利用SoapClient
类构造出ssrf的序列化字符串,然后利用call_user_func
修改配置,造成序列化与反序列化引擎不同的漏洞,再调用extract
函数去变量覆盖,调用SoapClient类,从而触发__call
方法
(需要自行在php.ini里把内置类启用)
1 |
|
1 |
|
给f传入session_start
,post传入serialize_handler=serialize
更改session序列化时候的引擎
实现session伪造,然后调用extract函数变量覆盖题目的implode函数,使得再次调用call_user_func函数,构造出下面命令
1 |
|
最后回到index.php里面,改一下cookie