BBSMAX 4.x 论坛程序登陆任意用户,取得用户密码信息漏洞
来源:岁月联盟
时间:2010-05-19
影响版本:
BBSMAX 4.x
程序介绍:
BBSMAX 是国内发展最早的基于.net技术构建的bbs,在leobbs独步天下、微软.net刚刚诞生的时 候,BBSMAX就开始发展了(当时名为 nowboard),历经多年发展,从个人开发到团队开发,从业余开发到全职开发,BBSMAX经历了质的蜕变。
漏洞分析:
在文件 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
-----------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
http://bbs.bbsmax.com/products_release/list-1.html