### 简要描述: 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 })) ==...
### 简要描述: 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即可跑出数据