天天看點

常見網站漏洞及解決辦法

自己最近也剛開始學習網站安全的技術,以下有寫的不對的地方還請高手多指點啊.

  網站漏洞主要集中在動态網頁中,靜态網站基本不存在什麼漏洞。

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,等。采取自定義的命名方式。。可有效提高安全性,黑客在想進入你的背景時要先找到登陸位址,如果用上述的目錄來說,就少了一份安全性,還有的網站為了友善管理,幹脆把背景登陸位址放到了前台頁面上,這樣不是給黑客提供了友善嗎?

有些網站背景密碼太簡單,這種問題很多是在一些企業網站裡,由于企業使用者缺乏安全知識,往往密碼很簡單,增加網站密碼的安全性也是很重要的。