当前位置:首页 » 《随便一记》 » 正文

学习笔记-java代码审计-ssrf

16 人参与  2022年11月13日 17:22  分类 : 《随便一记》  评论

点击全文阅读


java代码审计-ssrf

0x01 漏洞挖掘

java发送http请求的方式还是比较多的,下面是原生的:

String url = request.getParameter("url");URL u = new URL(url);//1.URL,直接打开,可以跨协议InputStream inputStream = u.openStream();//2. URLConnection,使用这种方法发送请求可以跨协议URLConnection urlConnection = u.openConnection();//3. HttpURLConnection,进行类型转换之后,只允许http/httpsHttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection;InputStream inputStream = urlConnection.getInputStream();//处理请求结果BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String inputLine;StringBuilder html = new StringBuilder();while ((inputLine = bufferedReader.readLine()) != null) {  html.append(inputLine);}response.getWriter().println("html:" + html.toString());bufferedReader.close();//4. ImageIO,如果获取到的不是图片,会返回nullBufferedImage img = ImageIO.read(u);

还有一部分第三方类库的:

// Request漏洞示例String url = request.getParameter("url");return Request.Get(url).execute().returnContent().toString();//发起请求// OkHttpClient漏洞示例String url = request.getParameter("url");OkHttpClient client = new OkHttpClient();com.squareup.okhttp.Request ok_http = new com.squareup.okhttp.Request.Builder().url(url).build();client.newCall(ok_http).execute();  //发起请求// HttpClients漏洞示例String url = request.getParameter("url");CloseableHttpClient client = HttpClients.createDefault();HttpGet httpGet = new HttpGet(url);HttpResponse httpResponse = client.execute(httpGet); //发起请求

0x02 漏洞防御

关于ssrf的防御,p牛已经给出了比较完善的解决方案谈一谈如何在Python开发中拒绝SSRF漏洞。

总结下来无非是这么几点:

正确处理302跳转(在业务角度看,不能直接禁止302,而是对跳转的地址重新进行检查)限制协议只能为http/https,防止跨协议设置内网ip黑名单(正确判定内网ip、正确获取host)设置常见web端口白名单(防止端口扫描,可能业务受限比较大)
private static int connectTime = 5 * 1000;public static boolean checkSsrf(String url) {  HttpURLConnection httpURLConnection;  String finalUrl = url;  try {    do {      if(!Pattern.matches("^https?://.*/.*$", finalUrl)) { //只允许http/https协议        return false;      }      if(isInnerIp(url)) { //判断是否为内网ip        return false;      }      httpURLConnection = (HttpURLConnection) new URL(finalUrl).openConnection();      httpURLConnection.setInstanceFollowRedirects(false); //不跟随跳转      httpURLConnection.setUseCaches(false); //不使用缓存      httpURLConnection.setConnectTimeout(connectTime); //设置超时时间      httpURLConnection.connect(); //send dns request      int statusCode = httpURLConnection.getResponseCode();      if (statusCode >= 300 && statusCode <=307 && statusCode != 304 && statusCode != 306) {        String redirectedUrl = httpURLConnection.getHeaderField("Location");        if (null == redirectedUrl)          break;        finalUrl = redirectedUrl; //获取到跳转之后的url,再次进行判断      } else {        break;      }    } while (httpURLConnection.getResponseCode() != HttpURLConnection.HTTP_OK);//如果没有返回200,继续对跳转后的链接进行检查    httpURLConnection.disconnect();  } catch (Exception e) {    return true;  }  return true;}private static boolean isInnerIp(String url) throws URISyntaxException, UnknownHostException {    URI uri = new URI(url);    String host = uri.getHost(); //url转host  //这一步会发送dns请求,host转ip,各种进制也会转化为常见的x.x.x.x的格式    InetAddress inetAddress = InetAddress.getByName(host);     String ip = inetAddress.getHostAddress();    String blackSubnetlist[] = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.0/8"}; //内网ip段    for(String subnet : blackSubnetlist) {      SubnetUtils subnetUtils = new SubnetUtils(subnet); //commons-net 3.6      if(subnetUtils.getInfo().isInRange(ip)) {        return true; //如果ip在内网段中,直接返回      }    }    return false;}

0x03 参考资料

JAVA代码审计之XXE与SSRF

谈一谈如何在Python开发中拒绝SSRF漏洞

点击关注,共同学习!安全狗的自我修养

github haidragon

https://github.com/haidragon


点击全文阅读


本文链接:http://zhangshiyu.com/post/48220.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1