### 简要描述:
LebiShop商城系统最新版SQL注入一,同一文件多处,官方demo演示
### 详细说明:
LebiShop商城系统最新版V3.1.00,多处存在SQL注入漏洞,可拖库
更多案例:
使用关键字搜索:powered by LebiShop
可搜索大量使用用户
反编译/bin/shop.dll,在SHop.Ajax中的Ajax_order文件中存在多处SQL注入漏洞
[<img src="https://images.seebug.org/upload/201501/19160519715218cfabc4690d798c48ac7f36befb.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/19160519715218cfabc4690d798c48ac7f36befb.png)
SHop.Ajax.Ajax_order即根目录下的Ajax目录,Ajax_order文件
第一处SQL注入
我们来看看Ajax_order文件中的Address_Del方法:
```
// Shop.Ajax.Ajax_order
public void Address_Del()
{
string id = RequestTool.RequestString("id");
if (id == "")
{
base.Response.Write("{\"msg\":\"" + base.Tag("请选择要删除的信息") + "\"}");
return;
}
B_Lebi_User_Address.Delete(string.Concat(new object[]
{
"User_id = ",
this.CurrentUser.id,
" and id in(",
id,
")"
}));
if (B_Lebi_User_Address.GetModel(string.Concat(new object[]
{
"User_id = ",
this.CurrentUser.id,
" and id = ",
this.CurrentUser.User_Address_id
})) == null)
{
Lebi_User_Address models = B_Lebi_User_Address.GetModel("User_id = " + this.CurrentUser.id);
if (models != null)
{
this.CurrentUser.User_Address_id = B_Lebi_User_Address.GetMaxId("User_id=" + this.CurrentUser.id);
}
B_Lebi_User.Update(this.CurrentUser);
}
base.Response.Write("{\"msg\":\"OK\"}");
}
```
参数通过RequestTool.RequestString获取,跟进RequestTool.RequestString方法
```
// Shop.Tools.RequestTool
public static string RequestString(string nKey, string def)
{
string ojb = HttpContext.Current.Request.QueryString[nKey];
if (ojb != null)
{
return StringTool.InjectFiltrate(ojb.Trim());
}
ojb = HttpContext.Current.Request.Form[nKey];
if (ojb != null)
{
return StringTool.InjectFiltrate(ojb.Trim());
}
return def;
}
```
id参数又通过StringTool.InjectFiltrate过滤处理:
```
// Shop.Tools.StringTool
public static string InjectFiltrate(string str)
{
if (!StringTool.IsSafeSqlString(str))
{
str = str.Replace("'", "´");
}
return str;
}
```
这里的过滤只是转义了单引号
再回到我们的Address_Del方法中
id通过处理后,进入了B_Lebi_User_Address.Delete方法中
而且这里的id进入了in条件中,没有使用单引号保护,继续跟进B_Lebi_User_Address.Delete方法
```
public void Delete(string strWhere)
{
if (strWhere.IndexOf("}") > 0)
{
SQLPara para = new SQLPara(strWhere, "", "");
this.Delete(para);
}
StringBuilder strSql = new StringBuilder();
strSql.Append("delete from [Lebi_User_Address] ");
strSql.Append(" where " + strWhere);
SqlUtils.SqlUtilsInstance.TextExecuteNonQuery(strSql.ToString());
}
```
可以看到这里的条件strWhere也没有加处理,直接进入了delete sql语句中,导致注入
第二处SQL注入
order_save方法:
```
// Shop.Ajax.Ajax_order
public void order_save()
{
if (this.CurrentUserLevel.BuyRight != 1)
{
base.Response.Write("{\"msg\":\"" + base.Tag("您所在的分组不允许下单") + "\"}");
return;
}
int pay_id = RequestTool.RequestInt("pay_id", 0);
int onlinepay_id = RequestTool.RequestInt("onlinepay_id", 0);
decimal Money_UserCut = RequestTool.RequestDecimal("Money_UserCut", 0m);
int usermoneytype = RequestTool.RequestInt("usermoneytype", 0);
string Pay_Password = RequestTool.RequestString("Pay_Password");
......
string pay2 = RequestTool.RequestString("pay312");
if (pay2 != "")
{
List<Lebi_Card> cs = B_Lebi_Card.GetList(string.Concat(new object[]
{
"User_id=",
this.CurrentUser.id,
" and id in (",
pay2,
")"
}), "id asc");
int flag = cs.FirstOrDefault<Lebi_Card>().IsCanOtherUse;
if (flag == 0 && cs.Count > 1)
{
base.Response.Write("{\"msg\":\"" + base.Tag("代金券异常") + "\"}");
return;
}
foreach (Lebi_Card c in cs)
{
if (flag != c.IsCanOtherUse)
{
base.Response.Write("{\"msg\":\"" + base.Tag("代金券异常") + "\"}");
return;
}
if (!Basket.CheckCard(basket, c))
{
base.Response.Write("{\"msg\":\"" + base.Tag("代金券异常") + "\"}");
return;
}
}
}
```
可以看到这里的pay2通过RequestTool.RequestString获取
然后没有加单引号保护,进入了in条件语句
最后进入了Getlist函数,跟进:
```
public List<Lebi_Card> GetList(string strWhere, string strFieldOrder)
{
if (strWhere.IndexOf("}") > 0)
{
SQLPara para = new SQLPara(strWhere, strFieldOrder, "");
return this.GetList(para);
}
StringBuilder strSql = new StringBuilder();
strSql.Append("select * ");
strSql.Append(" FROM [Lebi_Card] ");
if (strWhere.Trim() != "")
{
strSql.Append(" where " + strWhere);
}
if (strFieldOrder.Trim() != "")
{
strSql.Append(" order by " + strFieldOrder);
}
List<Lebi_Card> list = new List<Lebi_Card>();
using (IDataReader dataReader = SqlUtils.SqlUtilsInstance.TextExecuteReader(strSql.ToString()))
{
while (dataReader.Read())
{
list.Add(this.ReaderBind(dataReader));
}
}
return list;
}
```
在GetList函数中,strWhere也没有进行处理,至今进入了select sql语句,导致sql注入产生
第三处SQL注入
torder_save方法:
```
// Shop.Ajax.Ajax_order
public void torder_save()
{
int order_id = RequestTool.RequestInt("order_id", 0);
string opid = RequestTool.RequestString("opid");
if (opid == "")
{
base.Response.Write("{\"msg\":\"" + base.Tag("未选择任何商品") + "\"}");
return;
}
int count = 0;
Lebi_Order order = B_Lebi_Order.GetModel(order_id);
if (order == null)
{
base.Response.Write("{\"msg\":\"" + base.Tag("参数错误") + "\"}");
return;
}
if (order.User_id != this.CurrentUser.id)
{
base.Response.Write("{\"msg\":\"" + base.Tag("参数错误") + "\"}");
return;
}
List<Lebi_Order_Product> ops = B_Lebi_Order_Product.GetList("id in (" + opid + ")", "");
```
同样opid通过RequestTool.RequestString获取
然后opid进入了GetList函数,并且在in条件中,没有引号包含
进入GetList函数后,直接带入查询语句select中,没有处理,导致sql注入
### 漏洞证明:
以第一处sql注入为例
官方demo演示
[<img src="https://images.seebug.org/upload/201501/191632543c46a2398b2643a35a35f34d50cb561c.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/191632543c46a2398b2643a35a35f34d50cb561c.png)
[<img src="https://images.seebug.org/upload/201501/19163302d860f412a900ceb00bd34359867e4ff3.png" alt="3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/19163302d860f412a900ceb00bd34359867e4ff3.png)
使用SQLmap即可跑出数据
暂无评论