Ueditor 1.4.3 服务器请求伪造分析

偶然挖到的一个ssrf漏洞

Ueditor 1.4.3版本 服务器请求伪造漏洞

漏洞描述

UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码。
在使用抓取图片的功能时,造成SSRF漏洞。
攻击者可利用该漏洞可进行内网探测和部分应用识别,从而进行进一步攻击。

影响范围

Ueditor <= 1.4.3

进入编辑器

http://xxxxx/ueditor

漏洞POC

ueditor/php/controller.php?action=catchimage&source[]=https://xxxxx/xxxx.php

漏洞分析

主要跟踪这段代码: /php/Uploader.class.php:173

private function saveRemote()
{
$imgUrl = htmlspecialchars($this->fileField);
$imgUrl = str_replace("&amp;", "&", $imgUrl);

//http开头验证
if (strpos($imgUrl, "http") !== 0) {
    $this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
    return;
}

preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
$host_with_protocol = count($matches) > 1 ? $matches[1] : '';

// 判断是否是合法 url
if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
    $this->stateInfo = $this->getStateInfo("INVALID_URL");
    return;
}

preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
$host_without_protocol = count($matches) > 1 ? $matches[1] : '';

// 此时提取出来的可能是 ip 也有可能是域名,先获取 ip
$ip = gethostbyname($host_without_protocol);
// 判断是否是私有 ip
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
    $this->stateInfo = $this->getStateInfo("INVALID_IP");
    return;
}

//获取请求头并检测死链
$heads = get_headers($imgUrl, 1);
if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
    $this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
    return;
}
//格式验证(扩展名验证和Content-Type验证)
$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;
}

//打开输出缓冲区并获取远程图片
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();
...省略   
}

整个流程大概如下:

1、判断是否是合法http的url地址
2、利用gethostbyname来解析判断是否是内网IP
3、利用get_headers进行http请求,来判断请求的图片资源是否正确,比如状态码为200、响应content-type是否为image (SSRF漏洞触发处)
4、最终用readfile来进行最后的资源获取,来获取图片内容

所以在利用DNS重绑定时候,我们可以这样做

第一次请求 -> 外网ip
第二次请求 -> 内网ip
第三次请求 -> 内网ip

DNS重绑定利用过程

参考 https://www.cnblogs.com/abubu/p/11794544.html

修复方案:

建议升级Ueditor至1.4.3.1及以上版本。

posted @ 2021-09-30 18:04  LinkPoc  阅读(3245)  评论(0)    收藏  举报