cookie过滤注入脚本攻击与cookie设置加密的类的编写2017年8月17日
cookie(储存在用户本地终端上的数据)
我经常用于比如 1,验证码的校验
2,用户信息校验。
3,限制登陆次数校验。
cookie的脚本注入攻击
通过修改cookie里的值注入恶意代码,破解网站
如下面的案例:
新建一个web网页
1,书写一个设置cookie函数与读取cookie函数
2,写入一个用户名cookie 值为aaa
3,读取cookie
public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Response.Write( getCookie("用户名").Value); } public static HttpCookie getCookie(string cookieName) { HttpRequest request = HttpContext.Current.Request; if (request != null) return request.Cookies[cookieName]; return null; } public static void SetCookie(string cookieName, string value, DateTime? expires) { HttpResponse response = HttpContext.Current.Response; if (response != null) { HttpCookie cookie = response.Cookies[cookieName]; if (cookie != null) { cookie.Value = HttpUtility.UrlEncode(value); if (expires != null) cookie.Expires = expires.Value; response.SetCookie(cookie); } } } }
//按下按钮设置cookie
protected void Button1_Click(object sender, EventArgs e) { SetCookie("name", "aaa", DateTime.Now.AddHours(5)); }
结果如下图所示:(浏览器采用欧鹏)
接着修改cookie
有入侵的<script>文件从cookie中注入 ,(欧鹏浏览器把有注入信息的cookie过滤),如果用http工具完全可以执行,这里就不演示了,讲讲解决方法
解决方法1:特殊字符的过滤:
value = Regex.Replace(value, "[ \\[ \\] \\^ \\-_*×――(^)$%~!@#$…&%¥—+=<>《》!!???::•`·、。,;,.;\"‘’“”-]", "").ToUpper();
将这些特殊的字符通过正则过滤掉
解决方法二加密:Base64加密
value = Base64.Encrypt(value); Base64.Decrypt(HttpUtility.UrlDecode(request.Cookies[cookieName].Value.ToString())); public static string Encrypt(string text) { Rijndael crypt = Rijndael.Create(); byte[] key = new byte[32] { 0X12, 0X70, 0X41, 0X8F, 0X33, 0X02, 0XE5, 0X45, 0X85, 0X05, 0X76, 0XAA, 0X7A, 0XAE, 0X79, 0X98, 0XA7, 0X33, 0X49, 0XFF, 0XE6, 0XAE, 0XBF, 0X8D, 0X8D, 0X20, 0X8A, 0X49, 0X31, 0X3A, 0X12, 0X40 }; byte[] iv = new byte[16] { 0X38, 0X81, 0X41, 0X4B, 0XAA, 0X25, 0X9A, 0X34, 0XB3, 0X46, 0X78, 0X56, 0X03, 0X42, 0XF6, 0X69 }; crypt.Key = key; crypt.IV = iv; MemoryStream ms = new MemoryStream(); ICryptoTransform transtormEncode = new ToBase64Transform(); //Base64编码 CryptoStream csEncode = new CryptoStream(ms, transtormEncode, CryptoStreamMode.Write); CryptoStream csEncrypt = new CryptoStream(csEncode, crypt.CreateEncryptor(), CryptoStreamMode.Write); System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); byte[] rawData = enc.GetBytes(text); csEncrypt.Write(rawData, 0, rawData.Length); csEncrypt.FlushFinalBlock(); byte[] encryptedData = new byte[ms.Length]; ms.Position = 0; ms.Read(encryptedData, 0, (int)ms.Length); return enc.GetString(encryptedData); } /************************************************************************ 解密函数:*/ public static string Decrypt(string text) { Rijndael crypt = Rijndael.Create(); byte[] key = new byte[32] { 0X12, 0X70, 0X41, 0X8F, 0X33, 0X02, 0XE5, 0X45, 0X85, 0X05, 0X76, 0XAA, 0X7A, 0XAE, 0X79, 0X98, 0XA7, 0X33, 0X49, 0XFF, 0XE6, 0XAE, 0XBF, 0X8D, 0X8D, 0X20, 0X8A, 0X49, 0X31, 0X3A, 0X12, 0X40 }; byte[] iv = new byte[16] { 0X38, 0X81, 0X41, 0X4B, 0XAA, 0X25, 0X9A, 0X34, 0XB3, 0X46, 0X78, 0X56, 0X03, 0X42, 0XF6, 0X69 }; crypt.Key = key; crypt.IV = iv; MemoryStream ms = new MemoryStream(); CryptoStream csDecrypt = new CryptoStream(ms, crypt.CreateDecryptor(), CryptoStreamMode.Write); ICryptoTransform transformDecode = new FromBase64Transform(); CryptoStream csDecode = new CryptoStream(csDecrypt, transformDecode, CryptoStreamMode.Write); System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); byte[] rawData = enc.GetBytes(text); csDecode.Write(rawData, 0, rawData.Length); csDecode.FlushFinalBlock(); byte[] decryptedData = new byte[ms.Length]; ms.Position = 0; ms.Read(decryptedData, 0, (int)ms.Length); return (enc.GetString(decryptedData)); }
当然也可以两种都加先过滤在加密