天天看点

常见网站漏洞及解决办法

自己最近也刚开始学习网站安全的技术,以下有写的不对的地方还请高手多指点啊.

  网站漏洞主要集中在动态网页中,静态网站基本不存在什么漏洞。

1.sql注入和跨站点脚本攻击

2.上传漏洞

3.文本编辑器漏洞

4.网站目录及密码安全

解决办法:

1.sql注入和跨站点脚本攻击:对这类漏洞来说就是用一些安全扫描工具进行检测,然后修复,以下是我个人总结的一点小知识:

对于asp网站:

一。跨站点攻击

1.在需要用户或管理员输入数据的地方用js去除危险字符

js脚本:

function RemoveBad(strTemp) {

strTemp = strTemp.replace(/[$ <> & % ' ( ) + - = " ; / ]/g, "")

return strTemp;

}

//asp脚本方法

<%

      '过滤掉危险的html和特殊字符,防止跨网站攻击

    function nohtml(str)

             dim re

             Set re=new RegExp

             re.IgnoreCase =true

             re.Global=True

             re.Pattern="(/<.[^/<]*/>)"

             str=re.replace(str," ")

             re.Pattern="(/<//[^/<]*/>)"

             str=re.replace(str,"")

             re.Pattern="([/'/&/-/+/=/(/)/;/[/]/{/}])" '去除特殊符号

             str=re.replace(str,"")            

             nohtml=str

             set re=nothing

       end function

        '对要显示的数据进行编码,防止显示危险字符

        function showdata(str)

               showdata=server.HTMLEncode(nohtml(str))

        end function

%>

对于aspx网站来说,有一个通用的安全检测类是很重要的,以下是个人总结:

namespace DZ.Security

{

    //输入数据安全性相关

    public class Sec

    {

        #region 检测输入的内容是否有攻击的可能性

        /// <summary>

        /// 检测输入的内容是否有攻击的可能性

        /// </summary>

        /// <param name="str"></param>

        /// <returns></returns>

        public static string par_queryString_forStr(string str)

        {

            //大于20很可能是注入攻击

            string str_process = null;

            if (str.Length > 20)

            {

                str_process = str.Substring(0, 20);

            }

            else

            {

                str_process = str;

            }

            return str_process;

        }

        #endregion

        #region 检测int 类型的id号的和法性

        /// <summary>

        /// 检测int 类型的id号的和法性

        /// </summary>

        /// <param name="str">要检测的字符</param>

        /// <returns></returns>

        public static string par_queryString_forId(string str)

        {

            //ID数字 整型 最大值65535 不超过5个数字

            string str_process = null;

            if (str.Length > 5)

            {

                str_process = str.Substring(0, 5);

            }

            else

            {

                str_process = str;

            }

            return str_process;

        }

        #endregion

        #region 硬性过滤脏字符串

        /// <summary>

        /// 硬性过滤脏字符串

        /// </summary>

        /// <param name="str">要处理的字符串</param>

        /// <returns></returns>

        public static string par_filter_forNews(string str)

        {

            //硬性过滤

            //依次为 **竞争对手,拿我的免费产品卖钱的家伙

            string[] filterStr = {

      **

          //领风五年,域名:

   };

            int filterLen = filterStr.Length;

            for (int i = 0; i < filterLen; i++)

            {

                str = str.Replace(filterStr[i], "");

            }

            return str;

        }

        #endregion        

        #region 对危险的html,Sql标记和特殊符号进行过滤

        /// <summary>

        /// 对危险的html,Sql标记和特殊符号进行过滤

        /// </summary>

        /// <param name="strHtml">要过滤的字符串</param>

        /// <returns>过滤后的字符串</returns>

        public static string FilterToTxt(string strHtml)

        {           

            string[] aryReg = {                     

                        @"<script[^>]*?>.*?</script>",

                        @"<(///s*)?!?((/w+:)?/w+)(/w+(/s*=?/s*(([""'])(//[""'tbnr]|[^/7])*?/7|/w+)|.{0})|/s)*?(///s*)?>",

                        @"([/r/n])[/s]+",

                        @"&(quot|#34);",

                        @"&(amp|#38);",

                        @"&(lt|#60);",

                        @"&(gt|#62);",

                        @"&(nbsp|#160);",

                        @"&(iexcl|#161);",

                        @"&(cent|#162);",

                        @"&(pound|#163);",

                        @"&(copy|#169);",

                        @"&#(/d+);",

                        @"-->",

                        @"<!--.*/n",

                        @"select",                                   

                        @"delete",                                    

                         @"update",                                   

                         @"insert into",                                    

                @"Insert",

                         @"Delete",

                         @"update",

                         @"create",

                         @"drop",

                         @"exec",

                         @"dri",

                        @"[^/w/[email protected]]"

                           };

            string strOutput = strHtml;

            for (int i = 0; i < aryReg.Length; i++)

            {

                Regex regex = new Regex(aryReg[i], RegexOptions.IgnoreCase);

                strOutput = regex.Replace(strOutput, string.Empty);

            }

            return strOutput;

        }

        #endregion

    }

    //数据加密,解密

    public class EncAndDec

    {

        public string _QueryStringKey = "logowang"; //URL传输参数加密Key abcdefgh

        public string _PassWordKey = "hgfedcba";   //PassWord加密Key

        #region url 参数加密解密

        public static string UrlDecode(string input)

        {

            return HttpUtility.UrlDecode(input);

        }

        public static string UrlEncode(string input)

        {

            return HttpUtility.UrlEncode(input);

        }

        #endregion

        #region md5字符串加密

        /// <summary>

        /// md5字符串加密

        /// </summary>

        /// <param name="str">要加密字符串</param>

        /// <returns></returns>

        public string MD5Encrypt(string str)

        {

            try

            {

                byte[] hashvalue = (new MD5CryptoServiceProvider()).ComputeHash(Encoding.UTF8.GetBytes(str));

                return BitConverter.ToString(hashvalue);

            }

            catch

            {

                return String.Empty;

            }

        }

        #endregion

        #region 加密解密相关

        /// <summary>

        /// 加密URL传输的字符串

        /// </summary>

        /// <param name="QueryString">要加密的字符串</param>

        /// <returns></returns>

        public string EncryptQueryString(string QueryString)

        {

            return Encrypt(QueryString, _QueryStringKey);

        }

        /// <summary>

        /// 解密URL传输的字符串

        /// </summary>

        /// <param name="QueryString">要解密的字符串</param>

        /// <returns></returns>

        public string DecryptQueryString(string QueryString)

        {

            return Decrypt(QueryString, _QueryStringKey);

        }

        ///

        /// 加密帐号口令

        ///

        ///

        ///

        public string EncryptPassWord(string PassWord)

        {

            return Encrypt(PassWord, _PassWordKey);

        }

        /// <summary>

        /// 解密帐号口令

        /// </summary>

        /// <param name="PassWord"></param>

        /// <returns></returns>

        public string DecryptPassWord(string PassWord)

        {

            return Decrypt(PassWord, _PassWordKey);

        }

        /// <summary>

        /// DEC 加密过程

        /// </summary>

        /// <param name="pToEncrypt">要加密的字符串</param>

        /// <param name="sKey">加密密钥</param>

        /// <returns></returns>

        public string Encrypt(string pToEncrypt, string sKey)

        {

            DESCryptoServiceProvider des = new DESCryptoServiceProvider(); //把字符串放到byte数组中

            byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);

            //byte[] inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); //建立加密对象的密钥和偏移量

            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);   //原文使用ASCIIEncoding.ASCII方法的GetBytes方法

            System.IO.MemoryStream ms = new System.IO.MemoryStream();     //使得输入密码必须输入英文文本

            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);

            cs.Write(inputByteArray, 0, inputByteArray.Length);

            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder();

            foreach (byte b in ms.ToArray())

            {

                ret.AppendFormat("{0:X2}", b);

            }

            ret.ToString();

            return ret.ToString();

        }

        /// <summary>

        /// DEC 解密过程

        /// </summary>

        /// <param name="pToDecrypt">要解密的字符串</param>

        /// <param name="sKey">解密密钥</param>

        /// <returns></returns>

        public string Decrypt(string pToDecrypt, string sKey)

        {

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            byte[] inputByteArray = new byte[pToDecrypt.Length / 2];

            for (int x = 0; x < pToDecrypt.Length / 2; x++)

            {

                int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));

                inputByteArray[x] = (byte)i;

            }

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); //建立加密对象的密钥和偏移量,此值重要,不能修改

            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);

            System.IO.MemoryStream ms = new System.IO.MemoryStream();

            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

            cs.Write(inputByteArray, 0, inputByteArray.Length);

            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder(); //建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象

            return System.Text.Encoding.Default.GetString(ms.ToArray());

        }

        /// <summary>

        /// 检查己加密的字符串是否与原文相同

        /// </summary>

        /// <param name="EnString">加密的url</param>

        /// <param name="FoString">加密的Password</param>

        /// <param name="Mode">1:检测url参数,2:检测Password</param>

        /// <returns></returns>

        public bool ValidateString(string EnString, string FoString, int Mode)

        {

            switch (Mode)

            {

                default:

                case 1:

                    if (Decrypt(EnString, _QueryStringKey) == FoString.ToString())

                    {

                        return true;

                    }

                    else

                    {

                        return false;

                    }

                case 2:

                    if (Decrypt(EnString, _PassWordKey) == FoString.ToString())

                    {

                        return true;

                    }

                    else

                    {

                        return false;

                    }

            }

        }

        #endregion

    }

}

2.在需要显示数据的地方用Html.encode()方法进行编码,如下:

在执行页中我们加入:

strUserName =server.HTMLEncode(Request.QueryString("userName"))

strUserName =server.HTMLEncode(Request.Form("userName"))

二。sql输入攻击

主要是在数据查询页面,对传过来的参数进行安全检测,避免不符合要求的参数进行数据库查询。如下:

if(Not IsNumeric(id)) then

      Response.write("没有相关数据")

else

      进行数据查询并显示数据

end if

2.上传漏洞:主要是对用户上传的文件进行检测,这个特别是在编写程序时特别重要,以下是我用到的aspx。上传检测代码:

 #region 实现图片上传lblhasPic,FileUpload1 lbladdArtic

    protected void upLoadPic(Label lblp, Label lblisSuccess, FileUpload fileload)

    {

        lblisSuccess.Text = "";

        lblp.ForeColor = System.Drawing.Color.Red;

        if (fileload.HasFile)

        {

            string fileContentType = fileload.PostedFile.ContentType;

            #region 获取上传文件的文件名并判断文件的合法性

            bool fileOk = true;

            string name = fileload.PostedFile.FileName; // 客户端文件路径

            FileInfo file = new FileInfo(name);

            string fileName = file.Name; // 文件名称

            if (fileName.Contains(";"))//上传文件含有分号,很有能是上传图片木马的前兆

            {

                fileOk = false;

            }

            #endregion

            if (fileOk)

            {

                if (fileContentType == "image/bmp" || fileContentType == "image/gif" || fileContentType ==

    "image/pjpeg")

                {

                    int isHasPic;//视频图片是否存在            

                    string relImgPath = "/hqvideo/advancedusers/VideoPictures/" + Session["username"].ToString() + "/" + Request.QueryString["ID"].ToString() + "/";

                    String path = Server.MapPath(relImgPath);//保存上传文件的文件夹upload虚拟路径对应的实际路径

                    string pt = path;

                    // picFileName = fileName;

                    if (!Directory.Exists(pt)) //如果文件夹不存在则创建

                    {

                        Directory.CreateDirectory(pt);

                    }

                    string webFilePath = pt + fileName; // 服务器端文件路径

                    //向数据库中添加视频信息

                    isHasPic = addVideoPic(fileName, relImgPath + fileName, txbpicinfo.Text, 0);

                    if (isHasPic != -1)

                    {

                        try

                        {

                            fileload.SaveAs(webFilePath); // 使用 SaveAs 方法保存文件

                            //最后一部高级验证,图片上传后的操作,判断是否真的是图片

                            StreamReader sr = new StreamReader(webFilePath, Encoding.Default);

                            string img = "";

                            string strContent = sr.ReadToEnd();

                            sr.Close();

                            string str = "request|script|.getfolder|.createfolder|.deletefolder|.createdirectory|.deletedirectory|.saveas|wscript.shell|script.encode|server.|.createobject|execute|activexobject|language=|public|dim";

                            foreach (string s in str.Split('|'))

                                if (strContent.IndexOf(s) != -1)

                                {

                                    File.Delete(webFilePath);

                                    img = "No";

                                    break;

                                }

                            //删除源文件

                            if (img == "No" && File.Exists(webFilePath))

                            {

                                File.Delete(webFilePath);//如果文件已经存在就删除

                                lblp.ForeColor = System.Drawing.Color.Red;

                                lblp.Text = "提示:文件格式不正确";

                            }

                            else

                            {

                                lblp.ForeColor = System.Drawing.Color.Green;

                                lblp.Text = "提示:文件“" + fileName + "”成功上传";

                            }

                            txbpicinfo.Text = "";

                        }

                        catch (Exception ex)

                        {

                            lblp.Text = "提示:文件上传失败,失败原因:" + ex.Message;

                        }

                    }

                    else

                    {

                        lblp.Text = "提示:文件已经存在,请重命名后上传";

                    }

                }

                else

                {

                    lblp.Text = "提示:文件类型不符";

                }

            }

            else

            {

                lblp.Text = "请先选择要上传的图片";

            }

        }

        else

        {

            lblp.Text = "提示:文件类型不符";

        }

    }

    #endregion

 3.对文本编辑器漏洞来说主要的还是上传漏洞,如果再自己的项目中没有用到上传的功能还是把上传功能关闭,对新下载的文本编辑器,删除里面的实例程序一般都会以_开头,最好对文本编辑器所在的目录进行用户身份的验证。

4.

网站目录不要采取带有明显管理员信息的目录,如:admin,manager,等。采取自定义的命名方式。。可有效提高安全性,黑客在想进入你的后台时要先找到登陆地址,如果用上述的目录来说,就少了一份安全性,还有的网站为了方便管理,干脆把后台登陆地址放到了前台页面上,这样不是给黑客提供了方便吗?

有些网站后台密码太简单,这种问题很多是在一些企业网站里,由于企业用户缺乏安全知识,往往密码很简单,增加网站密码的安全性也是很重要的。