### 简要描述: LebiShop商城系统最新版设计缺陷及XSS盲打后台 ### 详细说明: LebiShop商城系统最新版验证码存在设计缺陷可无视验证码,及存储型XSS盲打后台 验证码设计缺陷: LebiShop商城系统有两者验证码验证方式 1、直接判断POST提交的验证码已经COOKIE中的验证码是否相等 如前台普通用户登陆时 ``` // Shop.Ajax.Ajax_user public void User_Login() { string verifycode = RequestTool.RequestString("verifycode"); string code = CookieTool.GetCookieString("CheckCodef"); string UserName = RequestTool.RequestSafeString("UserName"); string PWD = RequestTool.RequestSafeString("Password"); if (code != verifycode) { base.Response.Write("{\"msg\":\"" + base.Tag("验证码错误") + "\"}"); return; } ``` 直接判断verifycode和CheckCodef是否相等 这里我们在发送请求时,将POST和COOKIE中的值设置为一样即可绕过 2、判断COOKIE的某值是否为空,然后在进行第1中方式的验证 如后台登陆 ``` // Shop.Admin.Ajax.Ajax_login public void AdminLogin() { string userName = RequestTool.RequestString("userName"); string UserPWD = RequestTool.RequestString("UserPWD"); string code = RequestTool.RequestString("code"); int saveusername = RequestTool.RequestInt("saveusername", 0); int type = RequestTool.RequestInt("type", 0); if...
### 简要描述: LebiShop商城系统最新版设计缺陷及XSS盲打后台 ### 详细说明: LebiShop商城系统最新版验证码存在设计缺陷可无视验证码,及存储型XSS盲打后台 验证码设计缺陷: LebiShop商城系统有两者验证码验证方式 1、直接判断POST提交的验证码已经COOKIE中的验证码是否相等 如前台普通用户登陆时 ``` // Shop.Ajax.Ajax_user public void User_Login() { string verifycode = RequestTool.RequestString("verifycode"); string code = CookieTool.GetCookieString("CheckCodef"); string UserName = RequestTool.RequestSafeString("UserName"); string PWD = RequestTool.RequestSafeString("Password"); if (code != verifycode) { base.Response.Write("{\"msg\":\"" + base.Tag("验证码错误") + "\"}"); return; } ``` 直接判断verifycode和CheckCodef是否相等 这里我们在发送请求时,将POST和COOKIE中的值设置为一样即可绕过 2、判断COOKIE的某值是否为空,然后在进行第1中方式的验证 如后台登陆 ``` // Shop.Admin.Ajax.Ajax_login public void AdminLogin() { string userName = RequestTool.RequestString("userName"); string UserPWD = RequestTool.RequestString("UserPWD"); string code = RequestTool.RequestString("code"); int saveusername = RequestTool.RequestInt("saveusername", 0); int type = RequestTool.RequestInt("type", 0); if (CookieTool.GetCookieString("AdminLoginError") != "") { string ccode = CookieTool.GetCookieString("CheckCodef"); if (ccode != code) { base.Response.Write(Language.Tag("验证码错误", this.CurrentLanguage.Code)); return; } } ``` 先判断COOKIE中的AdminLoginError是否为空,在进行code的判断 这里在发送请求时,直接将COOKIE中的AdminLoginError设置为空即可绕过验证码 XSS盲打后台 很多地方都存在盲打后台的地方,全局只进行了<,>,'三个符号的处理 但是在获取X-Forwarded-For时,没有使用全局处理,直接赋值 如在商家用户登陆处 ``` // Shop.Supplier.Ajax.Ajax_user public void User_Login() { string msg = ""; string userName = RequestTool.RequestSafeString("userName"); string UserPWD = RequestTool.RequestSafeString("UserPWD"); string code = RequestTool.RequestString("code"); string logintype = RequestTool.RequestString("logintype", "supplier"); int saveusername = RequestTool.RequestInt("saveusername", 0); if (CookieTool.GetCookieString("SupplierLoginError") != "") { string ccode = CookieTool.GetCookieString("CheckCodef"); if (ccode != code) { base.Response.Write(Language.Tag("验证码错误", base.CurrentLanguage.Code)); return; } } if (EX_User.UserLogin(userName, UserPWD, true)) { this.CurrentUser = EX_User.CurrentUser(); if (EX_Supplier.Login(this.CurrentUser, logintype, 0, out msg)) { if (saveusername == 1) { CookieTool.SetCookieString("SupplierUserName", userName, 1440); CookieTool.SetCookieString("saveusername", "1", 1440); } else { CookieTool.SetCookieString("SupplierUserName", "", -1); CookieTool.SetCookieString("saveusername", "", -1); } Log.Add("登陆系统", "Login", this.CurrentUser.id.ToString(), this.CurrentUser.UserName); msg = "OK"; } else { msg = Language.Tag("账号状态异常", base.CurrentLanguage.Code); } } else { msg = Language.Tag("用户名或密码错误", base.CurrentLanguage.Code); base.Response.Cookies.Add(new HttpCookie("SupplierLoginError", "1")); Log.Add("登陆系统", "Login", "", this.CurrentUser, "[" + userName + "]用户名或密码错误"); } base.Response.Write(msg); } ``` 这里是否登录成功都会有log记录 跟进Log.Add函数 ``` // Shop.Bussiness.Log public static void Add(string content, string tablename, string keyid, string description) { EX_User.CurrentUser(); EX_Admin.CurrentAdmin(); Log.Add(content, tablename, keyid, null, null, null, description); } ``` 继续跟进 ``` // Shop.Bussiness.Log public static void Add(string content, string tablename, string keyid, Lebi_User user, Lebi_Administrator admin, Lebi_Supplier supplier, string description) { Lebi_Log log = new Lebi_Log(); if (admin != null) { log.Admin_id = admin.id; log.AdminName = admin.UserName; } if (user != null) { log.User_id = user.id; log.UserName = user.UserName; } if (supplier != null) { log.Supplier_id = supplier.id; log.Supplier_SubName = supplier.SubName; } if (keyid.Length > 500) { keyid = keyid.Substring(0, 500); } log.Content = content; log.Keyid = keyid; log.TableName = tablename; log.URL = RequestTool.GetRequestUrlNonDomain(); log.RefererURL = RequestTool.GetUrlReferrerNonDomain(); if (description.Length > 500) { log.Description = description.Substring(0, 500); } else { log.Description = description; } log.IP_Add = RequestTool.GetClientIP(); B_Lebi_Log.Add(log); } ``` 到最后,注意这里log.IP_Add = RequestTool.GetClientIP(); ``` // Shop.Tools.RequestTool public static string GetClientIP() { string result2; try { string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (result == null || result == string.Empty) { result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } if (result == null || result == string.Empty) { result = HttpContext.Current.Request.UserHostAddress; } result2 = result; } catch { result2 = ""; } return result2; } ``` 这里直接从HTTP_X_FORWARDED_FOR获取了内容,然后进入了log中 ### 漏洞证明: 将X-Forwarded-For设置为:<img src=1 onerror=alert(1)> 然后随便登录 [<img src="https://images.seebug.org/upload/201501/201849019b3e51adb52997eb12d7c6e8c3caa596.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/201849019b3e51adb52997eb12d7c6e8c3caa596.png) 此时log中已经记录的登陆信息 在后台配置,操作日志中: [<img src="https://images.seebug.org/upload/201501/201849557969f777532b7169a37c5f2c8873d38a.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/201849557969f777532b7169a37c5f2c8873d38a.png) 成功跨入后台