Skip to content
JoyChou edited this page Jun 27, 2019 · 5 revisions

1. 漏洞简介

SSRF(Server-side Request Forge, 服务端请求伪造)。 由攻击者构造的攻击链接传给服务端执行造成的漏洞,一般用来在外网探测或攻击内网服务。

2. 支持协议

file ftp mailto http https jar netdoc

如果发起网络请求的类是带HTTP开头,那只支持HTTP、HTTPS协议。

3. 重定向

Java默认会跟随重定向。先在一台vps上写一个302.php,代码如下:

<?php
$url = 'gopher://35.185.163.134:2333/_joy%0achou';
header("location: $url");
?>

访问payload

http://localhost:8080/urlConnection?url=http://joychou.me/302.php

收到异常:

java.net.MalformedURLException: unknown protocol: gopher

跟踪报错代码:

    private boolean followRedirect() throws IOException {
        if(!this.getInstanceFollowRedirects()) {
            return false;
        } else {
            final int var1 = this.getResponseCode();
            if(var1 >= 300 && var1 <= 307 && var1 != 306 && var1 != 304) {
                final String var2 = this.getHeaderField("Location");
                if(var2 == null) {
                    return false;
                } else {
                    URL var3;
                    try {
                        // 该行代码发生异常,var2变量值为`gopher://35.185.163.134:2333/_joy%0achou`
                        var3 = new URL(var2);
                        /* 该行代码,表示传入的协议必须和重定向的协议一致
                         * 即http://joychou.me/302.php的协议必须和gopher://35.185.163.134:2333/_joy%0achou一致
                         */
                        if(!this.url.getProtocol().equalsIgnoreCase(var3.getProtocol())) {
                            return false;
                        }
                    } catch (MalformedURLException var8) {
                        var3 = new URL(this.url, var2);
                    }

从上面的followRedirect方法可以看到:

  • 实际跳转的URL也在限制的协议内
  • 传入的URL协议必须和重定向后的URL协议一致。如果不一致,相当于没有进行重定向,返回空页面。

所以,Java的SSRF利用方式比较局限:

  • 利用file协议任意文件读取
  • 利用http协议探测端口或攻击内网服务

4. DNS Rebinding

先了解下Java应用的TTL机制。Java应用的默认TTL为10s,这个默认配置会导致DNS Rebinding绕过失败。也就是说,默认情况下,Java应用不受DNS Rebinding影响。

Java TTL的值可以通过下面三种方式进行修改:

  1. JVM添加启动参数-Dsun.net.inetaddr.ttl=0

  2. 通过代码进行修改

    java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "0");
    
  3. 修改java.security里的networkaddress.cache.negative.ttl变量为0

5. 总结

  • Java默认跟随重定向;
  • Java默认TTL为10;
  • 是否受DNS Rebinding影响取决于缓存;
  • 传入的URL协议必须和重定向后的URL协议一致。如果不一致,相当于没有进行重定向,返回空页面。

6. Preference

Clone this wiki locally