Skip to content

SSRF(服务器端请求伪造)

en0th edited this page Jul 26, 2024 · 4 revisions

简介

SSRF漏洞(Server-Side Request Forgery)指的是攻击者在Web应用程序中发起恶意请求,让服务器端向指定的地址发送网络请求,而这个地址是由攻击者控制的,攻击者可以通过该漏洞访问到应用程序无权访问的资源,比如内部网络中的其他服务、系统文件等。SSRF漏洞很危险,因为攻击者可以利用它来窃取敏感数据、发起攻击、甚至直接获取服务器的控制权。 SSRF漏洞通常是由于Web应用程序在处理输入时,没有对用户输入进行充分的验证和过滤,导致攻击者可以构造恶意的请求。攻击者可以通过修改HTTP请求中的URL参数或POST请求中的数据来触发SSRF漏洞,例如修改请求中的域名或IP地址,或者使用URL编码、IP地址转换等技术来绕过过滤。 防范SSRF漏洞的措施包括:

  1. 对用户输入的URL参数或POST数据进行严格的验证和过滤,包括对协议、域名、IP地址等进行白名单限制。
  2. 对Web应用程序中发起的网络请求进行安全配置,例如限制请求的目标范围、禁用危险的协议等。
  3. 对Web应用程序进行安全漏洞扫描和渗透测试,及时发现和修复漏洞。
  4. 在服务器端进行安全配置,例如限制网络端口、禁用危险的系统命令等。

攻略

1)远程拉取图片

考察:Java 下 SSRF 的运用

尝试获取https://www.baidu.com/img/flexible/logo/pc/result.png图片。

image-20240726152447923

发现我们填写的地址被填充到了imageURL字段。

image-20240726152507072

参考payload:file:///C:\Windows\win.ini

image-20240726153144340

解码之后可以看到文件内容。

image-20240726153420789

开发思路

SSRF漏洞主要有以下几个危害:

  1. 获取内网主机、端口和banner信息。
  2. 对内网的应用程序进行攻击,例如 Redis、jboss 等。
  3. 利用 file 协议读取文件。
  4. 可以攻击内网程序造成溢出。

Java 中我们不能像 PHP 那样使用 gopher 协议来拓展攻击面。我们可以从sun.net.www.protocol下看到支持的协议。 image.png 我们可以通过 file 进行文件读取操作,对于无回显的文件也可以通过利用 FTP 协议进行外带攻击。一般来说,我们想要使用以上所有的协议,我们需要用到URLConnectionURL方法。 SSRF漏洞通常出现在社交分享、远程图片加载或下载、图片或文章收藏、转码、通过网址在线翻译、网站采集、从远程服务器请求资源等功能点。 我这里实现了远程图片采集的功能,将获取到的数据进行base64编码并返回,没有限制请求的URL,从而导致SSRF漏洞的产生。 代码来源:com/pika/electricrat/ssrf/SSRFServlet.java

public void getRemoteImage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String url = request.getParameter("imageURL");
    try {
        URL u = new URL(url);
        URLConnection urlConnection = u.openConnection();
        BufferedInputStream in = new BufferedInputStream(urlConnection.getInputStream());
        List<Byte> buffer = new ArrayList<>();
        int length = -1;
        while ((length = in.read()) != -1){
            buffer.add((byte) length);
        }
        in.close();
        byte[] image2 = new byte[buffer.size()];
        for (int i = 0; i < buffer.size(); i++){
            image2[i] = buffer.get(i);
        }
        response.getWriter().append("data:image/jpeg;base64,").append(
                new String(Base64.getEncoder().encode(image2)));
    } catch (Exception e){
        response.setStatus(400);
    }
}
Clone this wiki locally