在文件 register.aspx.cs 中 protected void Page_Load(object sender, EventArgs e) { string str = string.Empty; str = base._Request.Get("active", Method.Get); if (!string.IsNullOrEmpty(str)) { if (BOBase<UserBO>.Instance.ActivingUser(str)) //激活用户 { base.ShowSuccess("恭喜!您的账号" + base.My.Username + "已成功激活。", BbsRouter.GetUrl("default")); } 在激活用户的过程代码如下: public bool ActivingUser(string activeSerial) { int userID = 0; userID = this.GetUserIdByActiveSerial(activeSerial); User user = null; if (userID > 0) { user = BOBase<UserBO>.Instance.GetUser(userID); } if (user != null) { DaoBase<UserDao>.Instance.ActivingUsers(new int[] { userID }, true); DaoBase<UserDao>.Instance.ValidateUserEmail(userID, user.Email); user.EmailValidated = true; this.SetUserLogin(user, null, user.Password, false); return true; } return false; } 对传入的字符串进行解密,取得用户ID,然后根据ID直接登陆。 解密代码如下: public int GetUserIdByActiveSerial(string serial) { Regex regex = new...
在文件 register.aspx.cs 中 protected void Page_Load(object sender, EventArgs e) { string str = string.Empty; str = base._Request.Get("active", Method.Get); if (!string.IsNullOrEmpty(str)) { if (BOBase<UserBO>.Instance.ActivingUser(str)) //激活用户 { base.ShowSuccess("恭喜!您的账号" + base.My.Username + "已成功激活。", BbsRouter.GetUrl("default")); } 在激活用户的过程代码如下: public bool ActivingUser(string activeSerial) { int userID = 0; userID = this.GetUserIdByActiveSerial(activeSerial); User user = null; if (userID > 0) { user = BOBase<UserBO>.Instance.GetUser(userID); } if (user != null) { DaoBase<UserDao>.Instance.ActivingUsers(new int[] { userID }, true); DaoBase<UserDao>.Instance.ValidateUserEmail(userID, user.Email); user.EmailValidated = true; this.SetUserLogin(user, null, user.Password, false); return true; } return false; } 对传入的字符串进行解密,取得用户ID,然后根据ID直接登陆。 解密代码如下: public int GetUserIdByActiveSerial(string serial) { Regex regex = new EmailActiveCodeRegex(); string s = ""; if (!string.IsNullOrEmpty(serial)) { try { serial = SecurityUtil.DesDecode(serial); } catch { return 0; } if (!string.IsNullOrEmpty(serial) && regex.IsMatch(serial)) { DateTime time; int num; GroupCollection groups = regex.Match(serial).Groups; string str = groups[1].Value; s = groups[2].Value; if (!DateTime.TryParse(s, out time)) { return 0; } TimeSpan span = (TimeSpan) (DateTimeUtil.Now - time); double totalHours = span.TotalHours; int.TryParse(str, out num); return num; } } return 0; } 是先通过SecurityUtil.DesDecode 解密我们传入的str后,再用正则取得用户ID。问题主要出在解密代码那里。我们来看一下: public static string DesDecode(string data) { byte[] buffer3; byte[] bytes = Encoding.ASCII.GetBytes("!bbsmax!"); byte[] rgbIV = Encoding.ASCII.GetBytes("!zzbird!"); try { buffer3 = Convert.FromBase64String(data); } catch { return null; } DESCryptoServiceProvider provider = new DESCryptoServiceProvider(); MemoryStream stream = new MemoryStream(buffer3); CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(bytes, rgbIV), CryptoStreamMode.Read); StreamReader reader = new StreamReader(stream2); return reader.ReadToEnd(); } 通过FromBase64String 转换,然后对转换后的字符串进行3DES解密,但问题就是出在这里。3DES的密码居然是固定在程序里的。 因此,我们可直接复制他的解密程序来构造我们的 active 字符串,从而达到登陆任意用户账号的目的。 取得用户密码信息的原理也是一样,BBSMAX的Cookie信息也是通过那个函数进入加解密,我们通过解密用户登陆后的Cookie后,取得用户密码。 BBSMAX 4.x 厂商补丁: BBSMAX ----------- 目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载: http://bbs.bbsmax.com/products_release/list-1.html