一個比欺騙表單更進階和複雜的攻擊方式是HTTP請求欺騙。這給了攻擊者完全的控制權與靈活性,它進一步證明了不能盲目信任用戶提交的任何資料。
為了示範這是如何進行的,請看下面位於//m.sbmmt.com/的表單:
#CODE:
<form action="process.php" method="POST"> <p>Please select a color: <select name="color"> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select><br /> <input type="submit" value="Select" /></p> </form>
#如果使用者選擇了Red並且點選了Select按鈕後,瀏覽器會發出下面的HTTP請求:
CODE:
#
POST /process.php HTTP/1.1 Host: example.org User-Agent: Mozilla/5.0 (X11; U; Linux i686) Referer: //m.sbmmt.com/ Content-Type: application/x-www-form-urlencoded Content-Length: 9 color=red
##.
看到大多數瀏覽器會包含一個來源的URL值,你可能會試著使用$_SERVER['HTTP_REFERER']變數去防止欺騙。確實,這可以用來對付利用標準瀏覽器發動的攻擊,但攻擊者是不會被這個小麻煩給擋住的。透過編輯HTTP請求的原始訊息,攻擊者可以完全控制HTTP頭部的值,GET和POST的數據,以及所有在HTTP請求的內容。
攻擊者如何更改原始的HTTP請求?過程非常簡單。透過在大多數系統平台上都提供的Telnet實用程序,你就可以透過連接網站伺服器的偵聽連接埠(典型的連接埠為80)來與Web伺服器直接通訊。以下就是使用這個技巧請求//m.sbmmt.com/頁面的範例:
CODE:
#
$ telnet example.org 80 Trying 192.0.34.166... Connected to example.org (192.0.34.166). Escape character is '^]'. GET / HTTP/1.1 Host: example.org HTTP/1.1 200 OK Date: Sat, 21 May 2005 12:34:56 GMT Server: Apache/1.3.31 (Unix) Accept-Ranges: bytes Content-Length: 410 Connection: close Content-Type: text/html <html> <head> <title>Example Web Page</title> </head> <body> <p>You have reached this web page by typing "example.com", "example.net", or "example.org" into your web browser.</p> <p>These domain names are reserved for use in documentation and are not available for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 2606</a>, Section 3.</p> </body> </html> Connection closed by foreign host. $
上例中所顯示的請求是符合HTTP/1.1規範的最簡單的請求,這是因為Host資訊是頭部信息中所必須有的。一旦你輸入了表示請求結束的連續兩個換行符,整個HTML的回應即顯示在螢幕上。
Telnet實用程式不是與Web伺服器直接通訊的唯一方法,但它常常是最方便的。可是如果你用PHP編碼同樣的請求,你可以就可以實現自動操作了。前面的請求可以用下面的PHP程式碼實作:
CODE:
<?php $http_response = ''; $fp = fsockopen('example.org', 80); fputs($fp, "GET / HTTP/1.1\r\n"); fputs($fp, "Host: example.org\r\n\r\n"); while (!feof($fp)) { $http_response .= fgets($fp, 128); } fclose($fp); echo nl2br(htmlentities($http_response, ENT_QUOTES, 'UTF-8')); ?>
當然,還有很多方法去達到上面的目的,但其要點是HTTP是一個廣為人知的標準協議,稍有經驗的攻擊者都會對它非常熟悉,並且對常見的安全漏洞的攻擊方法也很熟悉。
相對於欺騙表單,欺騙HTTP請求的做法並不多,對它不應該關注。我講述這些技巧的原因是為了更好的演示一個攻擊者在向你的應用程式輸入惡意訊息時是如何地方便。這再次強調了過濾輸入的重要性和HTTP請求提供的任何資訊都是不可信的這個事實。