沙漠綠洲

          ----駱駝之行

           

          轉(zhuǎn) Web應(yīng)用的輸入攻擊及其防范

          來自:http://www.vbyte.com/blog/detail.asp?blog_id=1&content_id=3&cat_id=7

          一、攻擊者繞過身份驗(yàn)證的方法?

            設(shè)想有這樣一個(gè)簡單的用戶登錄程序:它通過表單獲取用戶名字和密碼,然而把這些數(shù)據(jù)發(fā)送到服務(wù)器端,服務(wù)器端程序查找數(shù)據(jù)庫并驗(yàn)

          證用戶身份。這種用戶身份驗(yàn)證方法非常常見。檢查用戶名字和密碼時(shí),許多開發(fā)者使用的是類如下面的代碼:?


          <HTML>
          <%@language=javascript....%>
          <%
          if?(isPasswordOK(Request.form("name"),Request.form("pwd")))?{
          Response.write("身份驗(yàn)證通過!");
          //?其他操作
          }?else?{
          Response.write("拒絕訪問!");
          }

          function?isPasswordOK(strName,?strPwd)?{
          var?fAllowLogon?=?false;
          try?{
          var?oConn?=?new?ActiveXObject("ADODB.Connection");
          var?strConnection="Provider=Microsoft.Jet.OLEDB.4.0;Data
          Source=c:\\auth\\auth.mdb;"
          oConn.Open(strConnection);
          var?strSQL?=?"SELECT?count(*)?FROM?client?WHERE?"?+
          "(name='"?+?strName?+?"')?"?+?
          "?and?"?+
          "(pwd='"?+?strPwd?+?"')";
          var?oRS?=?new?ActiveXObject("ADODB.RecordSet");
          oRS.Open(strSQL,oConn);
          fAllowLogon?=?(oRS(0).Value?>?0)???true?:?false;
          oRS.Close();
          delete?oRS;
          oConn.Close();
          delete?oConn;
          }?catch(e)?{
          fAllowLogon?=?false;
          }

          return?fAllowLogon;
          }
          %>
          </HTML>



            注意,在上面的代碼中,程序從表單數(shù)據(jù)中提取出用戶名字和密碼,然后直接傳遞給了進(jìn)行驗(yàn)證的函數(shù)isPasswordOK。查詢數(shù)據(jù)庫的SQL命

          令直接利用表單輸入數(shù)據(jù)構(gòu)造,這是一個(gè)不安全的過程。假設(shè)用戶名字是“mikey”,密碼是“&y-)4Hi=Qw8”,則實(shí)際查詢數(shù)據(jù)庫的SQL命令是

          :?


          SELECT?count(*)?FROM?client?WHERE?(name='mikey')?and
          (pwd='&y-)4Hi=Qw8')



            當(dāng)查詢結(jié)果中count(*)返回合適的數(shù)值時(shí),用戶“mikey”的身份驗(yàn)證通過。如果count(*)返回的結(jié)果是0,則查詢未能找到匹配的記錄,

          用戶被拒絕訪問。?

            那么,攻擊者如何繞過這個(gè)驗(yàn)證過程呢?首先,攻擊者會(huì)假定驗(yàn)證過程使用上面這種SQL命令進(jìn)行驗(yàn)證,然后他們就發(fā)送偽造的用戶名字和

          密碼,改變SQL命令的判斷邏輯。例如,如果攻擊者輸入的用戶名字是“x'?or?1)?or?('1”,密碼是“anyoldpassword”,則實(shí)際查詢數(shù)據(jù)庫

          的SQL命令將變成:?


          SELECT?count(*)?FROM?client?WHERE?(name='x'?or?1)?or?('1')
          and?(pwd='anyoldpassword')



            可以看出,這個(gè)查詢選出的行數(shù)量總是大于或等于1,即count(*)的返回結(jié)果總是1或者更大。由此,雖然攻擊者并不知道合法的用戶名字

          和密碼,他總是能夠通過身份驗(yàn)證!?

            注意下面5點(diǎn)有助于防止攻擊者繞過Web應(yīng)用的身份驗(yàn)證過程。?

          二、防止錯(cuò)誤信息泄密?


            不要向?yàn)g覽器返回帶有出錯(cuò)SQL命令的錯(cuò)誤信息。出現(xiàn)腳本錯(cuò)誤時(shí),默認(rèn)情況下IIS會(huì)返回一個(gè)500-100錯(cuò)誤信息。事實(shí)上,返回不帶調(diào)試信

          息的錯(cuò)誤信息更有利于安全。例如,當(dāng)我們?cè)诘卿洷韱屋斎雮卧斓挠脩裘趾兔艽a時(shí),服務(wù)器返回的錯(cuò)誤信息可能如下:?


          Error?Type:
          Microsoft?JET?Database?Engine?(0x80040E14)
          Syntax?error?(missing?operator)?in?query?expression?
          '(name='x'?or?1)?or?('1')?and?(pwd=''p')'.
          /login.asp,?line?24



            可以看到,錯(cuò)誤信息中包含了部分SQL命令,它會(huì)幫助攻擊者改正原先的錯(cuò)誤,為攻擊者快速構(gòu)造出雖然偽造、但在SQL命令中合法的用戶

          名字和密碼帶來了方便。?

            要減少服務(wù)器返回的錯(cuò)誤信息量,最簡單的方法是修改%winnt%\help\iisHelp\500-100.asp;或者創(chuàng)建一個(gè)新的文件,同時(shí)設(shè)置IIS,使得

          500.100錯(cuò)誤出現(xiàn)時(shí)服務(wù)器返回這個(gè)新的文件。設(shè)置IIS服務(wù)器的步驟如下:?


          1.打開IIS管理工具?
          2.右擊要設(shè)置的Web服務(wù)器?
          3.選擇“屬性”?
          4.選擇定制錯(cuò)誤的選項(xiàng)卡?
          5.輸入定制的500.100錯(cuò)誤頁面文件的名字?
            對(duì)于安全來說,錯(cuò)誤信息中最好永遠(yuǎn)不要出現(xiàn)服務(wù)器上的物理路徑。例如,返回“不能在c:\wwwroot\secretlocation目錄下找到foo.doc

          文件”這種錯(cuò)誤信息并不有利于安全,一個(gè)簡單的404提示已經(jīng)足夠了。?

          三、確定合法性規(guī)則?

            利用VBscript....、Jscript....以及Perl語言的正則表達(dá)式,我們可以為用戶輸入數(shù)據(jù)定義合法性規(guī)則。不要去分析哪些輸入數(shù)據(jù)非法,因?yàn)楣?br />
          者會(huì)找出繞過非法數(shù)據(jù)檢查規(guī)則的辦法。例如,假設(shè)為了防止用戶向網(wǎng)站發(fā)送HTML數(shù)據(jù),我們要替換輸入數(shù)據(jù)中的“<”和“>”符號(hào):?


          strInput?=?strInput.replace(/[<>]/,"");?



            上面這個(gè)語句把“<”和“>”符號(hào)替換成空字符串。那么,是否這樣一來攻擊者所發(fā)送的HTML就不能再發(fā)送到服務(wù)器上了呢?答案是否定

          的。攻擊者只需把“<”和“>”替換為相應(yīng)的HTML實(shí)體符號(hào),上述分析用戶輸入的代碼就不能再找出HTML。由此我們認(rèn)識(shí)到,正確的方法應(yīng)該

          是先確定什么是合法的,然后驗(yàn)證用戶輸入的合法性,拒絕所有不符合合法性規(guī)則的輸入:?


          if?(strName.search(/[^A-Za-z?0-9]/)?!=?-1)?return?false;?



            這行代碼搜索strName,如果strName包含除了大寫字母、小寫字母、數(shù)字和空白字符之外的(這就是^的含義)字符,則輸入數(shù)據(jù)被拒絕。?


            進(jìn)行輸入檢驗(yàn)時(shí)還要注意偽造的文件名字。攻擊者可能嘗試把數(shù)據(jù)發(fā)送到某些敏感的位置,或者可能發(fā)出請(qǐng)求試圖得到源文件,等等。下

          面這個(gè)正則表達(dá)式對(duì)文件名字作嚴(yán)格的限制。合法文件名字的規(guī)則描述如下:?


          ●一個(gè)或者多個(gè)0-9a-zA-Z或_,再加上?

          ●一個(gè)或者多個(gè)0-9a-zA-Z、-、\、/和_,再加上?

          ●一個(gè)句點(diǎn),再加上?

          ●’’、’txt’、’jpg’、’jpeg’、’gif’、’htm’、’html’、’png’、’bmp’或’zip’?

            所有不符合上述規(guī)則的文件名字都非法。這個(gè)文件名字規(guī)則非常嚴(yán)格,但確實(shí)有效。你可以看到,文件名字不能以斜杠開頭,因?yàn)樾备苁?br />
          磁盤的根目錄。除了攻擊者之外,另外還有誰需要從磁盤的根目錄開始訪問呢?所有對(duì)文件的訪問都應(yīng)該相對(duì)于Web網(wǎng)站的根進(jìn)行:?


          var?strInput?=?Request.form("filename");?

          var?re?=?/^[\w]{1,}[\w\-\/\\]{1,}\.(txt|jpg|jpeg|gif|htm|html|png|bmp|zip)?

          {0,1}$/i;?

          var?fIsFilenameValid?=?(re.test(strInput))???true?:?false;?

          四、正確處理引號(hào)?

            引號(hào)有時(shí)候很難處理,因?yàn)樗鼈儠?huì)干擾SQL命令。如本文開頭的例子,攻擊者利用引號(hào)改變SQL命令的邏輯,使得不具備合法用戶名字和密

          碼的人也能夠登錄系統(tǒng)。防止利用引號(hào)攻擊的另外一種方法是事先轉(zhuǎn)義引號(hào)字符。下面這個(gè)正則表達(dá)式將把所有單引號(hào)和雙引號(hào)分別替換為兩

          個(gè)單引號(hào)和兩個(gè)雙引號(hào)。替換得到的SQL命令完全合乎SQL語法,而且它使得許多攻擊更難進(jìn)行。?


          strPwd?=?strPwd.replace(/([\’\"])/g,"$1$1");?



            這個(gè)語句可以替換前面加上的正則表達(dá)式。但也可以兩者一起使用,加強(qiáng)防衛(wèi)力量!?

          五、檢查SQL查詢返回的數(shù)據(jù)?

            一種完全防止這類攻擊的方法是停止使用只能表示“贊成、反對(duì)”的count(*),改為檢查用戶名字、密碼是否和SQL命令返回的用戶名字、

          密碼匹配。具體代碼如下所示:?


          var?strSQL?=?"SELECT?name,?pwd?FROM?client?WHERE?"?+?

          "(name=’"?+?strName?+?"’)?"?+?

          "?and?"?+?

          "(pwd=’"?+?strPwd?+?"’)";?

          var?oRS?=?new?ActiveXObject("ADODB.RecordSet");?

          oRS.Open(strSQL,oConn);?

          fAllowLogon?=?(oRS(0).Value?==?strName?&&?oRS(1).Value?==?strPwd)?

          ??true?:?false;?



            如果SQL查詢沒有返回?cái)?shù)據(jù),程序?qū)⒂|發(fā)一個(gè)異常,隨后這個(gè)異常就被catch()捕獲。?


          六、禁用父路徑?

            確保文件名字中沒有出現(xiàn)“..”。按照如下步驟禁用父路徑:?


          右擊Web網(wǎng)站的根,從菜單選擇“屬性”。?

          ●選擇“主目錄”選項(xiàng)卡。?

          ●點(diǎn)擊“配置”。?

          ●點(diǎn)擊“應(yīng)用程序選項(xiàng)”。?

          ●取消“啟用父路徑”。?

            如果要從命令行禁用父路徑,請(qǐng)執(zhí)行如下命令:?


          cscript....?adsutil.vbs?set?w3svc/1/root/AspEnableParentPaths?false?



            要真正做到對(duì)輸入攻擊的全面防范,你必須有一切輸入數(shù)據(jù)都可能有危險(xiǎn)的心理準(zhǔn)備。檢查合法的輸入,而不是檢查不合法的輸入,因?yàn)?br />
          攻擊者很快就可以找出突破不合法規(guī)則的辦法。同時(shí),學(xué)習(xí)并正確地運(yùn)用正則表達(dá)式。記住了這幾點(diǎn),你就能夠大大減少Web應(yīng)用被侵入的機(jī)會(huì)。?

          posted on 2006-07-23 17:43 小澗流水 閱讀(242) 評(píng)論(0)  編輯  收藏 所屬分類: 信息安全

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          Free Counter
          Free Web

          常用鏈接

          留言簿(1)

          隨筆分類(43)

          隨筆檔案(48)

          文章檔案(1)

          收藏夾(12)

          網(wǎng)絡(luò)

          計(jì)算機(jī)圖形學(xué)

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 昌宁县| 孙吴县| 若羌县| 汉沽区| 美姑县| 延寿县| 永修县| 通化县| 皋兰县| 吴江市| 句容市| 内江市| 宽城| 博野县| 澄城县| 大名县| 宝清县| 襄樊市| 白朗县| 五台县| 保康县| 平昌县| 贺州市| 山丹县| 青神县| 岐山县| 广东省| 嵊州市| 景宁| 宣威市| 汕尾市| 海门市| 宜君县| 松溪县| 兰州市| 平度市| 镇雄县| 邯郸市| 南安市| 潼南县| 体育|