LCTF bestphp’s revenge
记录一个获得了马师傅肯定的题目
题目源码
index.php
<?php
highlight_file(__FILE__);
$b = 'implode';
call_user_func($_GET['f'], $_POST);
session_start();
if (isset($_GET['name']))
{
$_SESSION['name'] = $_GET['name'];
}
var_dump($_SESSION);
$a = array(reset($_SESSION), 'welcome_to_the_lctf2018');
call_user_func($b, $a);
?>
flag.php
$flag = 'LCTF{*************************}';
if($_SERVER["REMOTE_ADDR"]==="127.0.0.1"){
$_SESSION['flag'] = $flag;
}
only localhost can get flag!
SESSION反序列化
首先需要知道,php中的session中的内容并不是放在内存中的,而是以文件的方式来存储的,PHP的session在存入时会进过序列化,再使用时在通过反序列化,存储方式就是由配置项的session.save_handler来进行确定的,不同的save_hanld存在着不同的序列化反序列化操作,从而引起反序列化漏洞。
php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值
php 键名+竖线(|)+经过serialize()函数处理过的值
php_serialize 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化
PHP一般默认使用php的序列化方式,这里我们可以通过call_user_func
来调用session_start()函数将其序列化方式变为php_serialize方式,而我们构造的数据为|O%3A10%3A%22SoapClient%22%3A3%3A%7Bs%3A3%3A%22uri%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D
注意数据最前端的那个’|’,在以php方式进行反序列化时,’|’作为一个分隔符,将后方的数据作为一个对象进行反序列化,构造出了一个soapclient对象,前方原本为php_serialize序列化的数据全部被作为键名写入了session中。
此时,我们就获得了一个储存在本地的SoapClient对象
SoapClient执行ssrf
SoapClient为PHP的一个内置类,因此我们在题目代码未包含类的情况下也可对该对象进行反序列化,而其拥有一个魔法方法__call(),调用时会发起一次soap请求(大概就是一次访问吧,访问目标可以由其location成员控制),本地测试后发现虽然请求会发出,但是运行时会直接抛出一个fatal error导致程序直接退出,后面部分就没法运行了
这里就通过存储与本地服务器session中的一个SoapClient对象对flag.php发起了访问,实现了SSRF。绕过了对REMOTE_ADDR的限制(实际上REMOTE_ADDR的绕过是非常困难的),这里存在一个var_dump函数,可以直接把SoapClient对象的内容都倒出来,所以我们直接查看SoapClient对本地服务器访问的这个cookie,然后把自己的cookie修改成它的,就可以假装成为本地登录获取flag了
SoapClient扩展内容
实际上SoapClient功能原不止如此,我们可以通过构造其ua数据实现对报文header部分的完全控制,即CRLF
参考N1CTF的Easy&&Hard PHP,该题目环境也是要求绕过REMOTE_ADDR,同样是通过SoapClient进行SSRF,而这里不存在对SoapClient对象的var_dump,我们可以通过构造一个自己的header发起ssrf访问,这样子就可以通过已构造的cookie伪装进行登录。
除此之外,SoapClient可以实现控制整个报文,修改Content-Type实现对特定数据的post
参考链接:
https://xz.aliyun.com/t/3341#toc-22
https://cloud.tencent.com/developer/article/1376384
https://xz.aliyun.com/t/2148