Windows XP Windows 7 Windows 2003 Windows Vista Windows教程綜合 Linux 系統教程
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟件教程
 Windows教程網 >> 電腦軟件教程 >> 服務器技術 >> 關於服務器 >> Web服務器的安全和攻擊防范

Web服務器的安全和攻擊防范

日期:2017/2/8 10:35:55      編輯:關於服務器

本文共分兩個部分,介紹Web服務器所面臨的各種安全威脅以及尋找服務器安全漏洞的各種工具。這是第一部分,主要涉及:端口掃描,NFS安全漏洞尋找,以及lsof的應用。 

   原文出處http://www.devshed.com/Server_Side/Administration/WebSecurityI/ 

   分析一下最近幾個月信用卡號碼被盜和網站被黑所顯示的種種安全問題,可以很清楚地看出,許多Web應用都是湊合著運行,很少有人關注其安全問題或作出安全規劃。那麼,造成服務器缺乏安全保障的常見原因有哪些?如何防范這些不安全因素?作為客戶或者最終用戶,如何才能信任某個服務器符合了基本的安全需求? 

   對於以往安全事故的分析表明,大多數安全問題都屬於下面三種類型之一: 

服務器向公眾提供了不應該提供的服務。 
服務器把本應私有的數據放到了可公開訪問的區域。 
服務器信賴了來自不可信賴數據源的數據。 

   提供不應該提供的服務 

   顯然,許多服務器管理員從來沒有從另一個角度來看看他們的服務器,例如使用端口掃描程序。如果他們曾經這樣做了,就不會在自己的系統上運行那麼多的服務,而這些服務原本無需在正式提供Web服務的機器上運行,或者這些服務原本無需面向公眾開放。 

   與這種錯誤經常相伴的是,為了進行維護而運行某些不安全的、可用於竊取信息的協議。例如,有些Web服務器常常為了收集訂單而提供POP3服務,或者為了上載新的頁面內容而提供FTP服務甚至數據庫服務。在某些地方這些協議可能提供安全認證(比如APOP)甚至安全傳輸(比如POP或者FTP的SSL版本),但更多的時候,人們使用的是這些協議的非安全版本。有些協議,比如msql數據庫服務,則幾乎沒有提供任何驗證機制。 

   從公司外面訪問自己的網絡,完整地檢測、模擬攻擊自己的網站看看會發生些什麼,這對於Web管理者來說是一個很好的建議。有些服務在機器安裝之後的默認配置中已經啟動,或者由於安裝以及初始設置的需要而啟動了某些服務,這些服務可能還沒有正確地關閉。例如,有些系統提供的Web服務器會在非標准的端口上提供編程示范以及系統手冊,它們往往包含錯誤的程序代碼並成為安全隱患所在。正式運行的、可從Internet訪問的Web服務器不應該運行這些服務,請務必關閉這些服務。 

   另外一種攻擊者經常利用的資源是SNMP協議(簡單網絡管理協議,Simple Network Management Protocol)。它可能為攻擊者提供有關系統和網絡布局的極其詳細和寶貴的信息。由於SNMP是一種UDP服務,比較簡單的安全檢查不會發現它。 

   當然,需要保護的不僅僅是Web服務器,在防火牆外面的所有其他機器更必須遵從同樣的安全標准。 

nmap可以http://www.insecure.org/nmap/獲得。 


# nmap -sS -T Agressive -p 1-10000 www.example.server   grep open 
Port State Protocol Service 
21 open tcp ftp 
22 open tcp ssh 
25 open tcp smtp 
80 open tcp http 
111 open tcp sunrpc 
119 open tcp nntp 
3306 open tcp mysql 
4333 open tcp msql 
   www.example.server作為WWW和FTP服務器使用。此外,該服務器還提供了ssh、smtp、sunrpc、nntp、mysql和msql服務。 

   在這些服務中,ssh是一種帶有完善加密和認證機制的協議,如果服務器上運行的ssh是最新版本,那麼使用它應該是安全的。 

   http、ftp、smtp和nntp是www.example.server服務器實際提供的服務,這些服務是必須運行的。只要FTP只用於匿名服務,網絡上也不會因此出現以明文形式傳送的密碼。所有其他文件傳輸都應該用scp工具和ssh協議完成。 

   sunrpc、mysql和msql服務沒有必要從防火牆外面的機器訪問,而且也沒有必要被所有的IP地址訪問。這些端口應該用防火牆或者包過濾器阻隔。 

   對於所有向公眾開放的服務,你應該密切關注其程序的最新版本和安全信息,應該做好一旦發現與這些程序有關的安全問題就立即升級軟件的准備。例如,某些版本的ssh會出現問題,在一些特殊的情形下服務器可能被騙並以非加密方式運行。對於有些FTP服務器、早期的sendmail以及某些版本的INN,已知的安全問題包括緩存溢出等。 

   有些時候端口掃描程序找到了一個打開的端口,但我們卻不知道哪一個程序在操作這個端口,此時就要使用lsof之類的工具了。執行命令“lsof -P -n -i”即可顯示出所有本地打開的端口以及操作這些端口的程序。 


# lsof -P -n -i 
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME 
xfstt 46 root 4u IPv4 30 TCP *:7100 (LISTEN) 
httpd 199 root 19u IPv4 99 TCP 192.168.1.12:80 (LISTEN) 
... 
smbd 11741 root 5u IPv4 28694 UDP 127.0.0.1:1180 
smbd 11741 root 6u IPv4 28689 
TCP 192.168.1.3:139-< 192.168.1.2:1044 (ESTABLISHED) 


   增加額外的參數就可以掃描指定的協議和端口: 

# lsof -P -n -i tcp:139 
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME 
smbd 276 root 5u IPv4 175 TCP *:139 (LISTEN) 
smbd 11741 root 6u IPv4 28689 
TCP 192.168.1.3:139-< 192.168.1.2:1044 (ESTABLISHED) 
  運行nmap搜索整個網絡可以列出域之內所有已知服務器。另外,你還可以查看DNS,看看服務器管理員為這個域所設置的內容。 

   再使用前面的example.server域: 

# nslookup 

< set type=ns 
< www.example.server. 
Server: ns.provider.net 
Address: 10.4.3.1 

example.server 
origin = ns.example.server 
mail addr = postmaster.ns.example.server 
serial = 2000032201 
refresh = 10800 (3H) 
retry = 3600 (1H) 
expire = 604800 (1W) 
minimum ttl = 86400 (1D) 
< server ns.example.server 
Default Server: ns.example.server 
Address: 192.168.129.37 

< ls example.server. 
[ns.example.server] 
$ORIGIN example.server. 
@ 1D IN A 192.168.240.131 
wwwtest 1D IN A 192.168.240.135 
news 1D IN A 192.168.240.136 
localhost 1D IN A 127.0.0.1 
listserv 1D IN A 192.168.240.136 
... 
igate 1D IN A 192.168.129.34 


   命令“set type=ns”(名稱服務器)告訴nslookup只查找域的名稱服務器信息,因此本例查詢“www.example.server”將返回該主機的所有名稱服務器。這裡的查找結果只有一個服務器“ns.example.server”。 

   接下來我們用命令“server ns.example.server”把所有以後的查詢直接定向到該服務器。然後,我們用“ls example.server”命令查詢該服務器要求列出“example.server”區域的完整清單,結果就看到了example.server管理員所設定的所有主機名字和IP地址列表。 

   如果一個域有多個名稱服務器,嘗試查詢所有的名稱服務器往往是值得的,這是因為雖然主名稱服務器往往有安全保護,其他名稱服務器卻往往沒有,很容易從這些服務器得到域主機和IP地址信息。 

   注重安全的網絡管理員總是在另外的機器上運行內部DNS服務,而不是在直接接入Internet的機器上運行。沒有必要告訴整個世界自己的辦公室內運行著哪些機器、這些機器怎樣命名。把直接服務於Web網站的機器名字和地址發布出去已經完全足夠了。 
   使用gnome程序Cheopshttp://www.marko.net/cheops)可以生成一個網絡示意圖,清楚地顯示出機器類型和連接。另外這個程序也可以進行端口掃描,但功能不如nmap靈活和強大。 

   使用網絡監測器Etherealhttp://ethereal.zing.org/)可以分析網絡傳輸。Ethereal能夠跟蹤TCP流,對於獲知由telnet、ftp、pop3等協議傳輸的明文密碼很有用。 

   使用rpcinfo和showmount(對於Linux的某些版本,還可以使用kshowmount),你可以查詢自己機器的sunrpc提供了哪些服務。如果NFS正在運行,就有可能從服務器獲得已導出文件系統的清單。 

# rpcinfo -p www.example.server 
program vers proto port 
100000 4 tcp 111 portmapper 
100000 3 tcp 111 portmapper 
100000 2 tcp 111 portmapper 
100000 4 udp 111 portmapper 
100000 3 udp 111 portmapper 
100000 2 udp 111 portmapper 
可以看到,www.example.server的sunrpc服務開放了對外部機器的連接。這是沒有必要的,我們可以安裝帶有訪問控制的rpcbind程序或者配置防火牆阻斷它。 

   由於NFS默認值極不合理,把文件系統完全不受保護地以可讀寫方式顯露給外界就成了一種極為常見的錯誤。下面是一個實例: 


# /usr/sbin/kshowmount -e center2.sample-university.net 
Export list for center2.sample-university.net: 
/usr/lib/cobol (everyone) 
/usr/sys/inst.images (everyone) 
/stadtinf (everyone) 
/var/spool/mail (everyone) 
/usr/lpp/info (everyone) 
/usr/local (everyone) 
/pd-software (everyone) 
/u1 (everyone) 
/user (everyone) 
/fix (everyone) 
/u (everyone) 
/ora rzws01 
/install (everyone) 
/ora-client 192.168.15.20 
   所有注明了“everyone”的目錄都是向公眾開放的,其中包括:保存了數百個用戶郵件的“/var/spool/mail”目錄,以及用戶的主目錄“/u”和“/u1”。另外“/usr/local”和“/usr/lib/cobol”也是允許寫入的,這使得它很容易被安裝上特洛伊木馬。任何人都可以進入這個系統,且不會遇到什麼值得一提的阻力。 我們要討論的第二類安全問題涉及到服務器公用目錄下的私有數據。許多Web空間提供商提供的只有“Web空間”,它們會把用戶FTP目錄的根映射到Web服務器的根。也就是說,用戶可以通過FTP以“/”訪問服務器目錄“/home/www/servers/www.customer.com/”,同時任何人可以通過URLhttp://www.customer.com/”訪問它,用FTP方式保存的“/password”文件可以通過URLhttp://www.customer.com/password”訪問。如果用戶Web應用需要保存一些私有的、不能從Web訪問的數據,則根本無法找到滿足要求的位置。 

   許多Web商店把訂單日志和調試輸出寫入一個或多個日志文件,或者用配置文件來保存密碼和商品數據。如果這些數據保存到頁面文檔根目錄之下,那麼它們就有相應的URL而且可以通過Web訪問。此時攻擊者所要做的只是猜出這些文件的名字。只要了解了20種主流在線商店系統的默認設置並正確地識別出目標網站所用的系統,要猜出這些文件名字是相當簡單的。 

   如果Web服務器既提供私有數據存儲又提供公用頁面目錄,上述問題就不會再出現。例如在這些方案中,FTP根目錄“/”映射到“/home/www/servers/www.customer.com/”,但頁面文檔的根目錄卻在它的下一級目錄“/home/www/servers/www.customer.com/pages”,可以通過FTP以“/pages”形式訪問。在這種目錄配置下,用戶可以另外創建和頁面文檔根目錄平行的目錄,然後把敏感數據放到這些目錄中。由於這些目錄可以通過FTP訪問,但不能通過HTTP訪問,所以它們是無法通過Web訪問的。 

   如果系統沒有采用上述根目錄分離的目錄結構,我們還有一種解決問題的辦法,即在頁面文檔根目錄下創建專用的私有數據存儲目錄,如“/shop”,然後在這個目錄中創建.htaccess文件,通過.htaccess文件拒絕所有HTTP訪問(適用於Apache服務器): 


$ cat /shop/.htaccess 
order deny, allow 
deny from all 

   該目錄中的文件只能通過FTP傳輸,因為FTP傳輸忽略.htaccess文件。但與前面采用頁面文檔根目錄之外獨立目錄的方法相比,這種方法的風險更多一點,因為如果服務器管理員在服務器主配置文件中意外地關閉了該目錄必不可少的“AllowOverride Limit”優先權,這種保護將不再有效。 

   上述問題還有各種變化形式。如果一台機器上運行著多個客戶網站,那麼客戶就能夠欺騙機器,訪問在其自己目錄層次之外的路徑,例如“/home/www/servers/www.customer.com”目錄之外的文件。通常,只需創建各種符號鏈接(指向保存在用戶虛擬服務器之外的文件)就有可能實現這一點。最有可能成為鏈接目標的是包含文件和私有密匙,這是為了獲取數據庫密碼和其他必須保密的信息(為了讓應用能夠正常運行這些信息往往以明文形式保存在這類文件中)。其他可能的攻擊目標還包括保存在非公用目錄中的訂單記錄和其他有用數據。 

   把盡可能多的服務隔離運行可以部分地解決這個問題,例如用Apache suexec程序的sbox讓所有的CGI在隔離的環境以客戶的用戶ID而不是Web服務器的用戶ID運行。另外,許多服務器上運行著FTP服務,例如wu-ftpd,該服務的所有文件傳輸都是隔離進行的,同樣也保護了善意客戶的資料避免被其他人偷看。 

   然而,惡意的客戶仍舊能夠用CGI程序創建符號鏈接指向其他用戶的存儲區域,然後通過它自己的Web服務器查看其他人的文件,這是因為在一個運行多個網站的環境中,Web服務器無法簡單地以隔離方式以及用它為之應答請求的客戶的用戶ID運行。管理員應該配置Web服務器以及其他文件傳輸程序使其不再使用符號鏈接。在Apache上,這可以通過關閉最頂層的“FollowSymLinks”選項實現(不要在較低的層次上把它重新打開),配置代碼示例如下: 

< directory / > 
Options -FollowSymLinks 
< /directory > 
  第三類常見的安全問題是CGI程序或PHP腳本的質量低下,它們信任了來源不可靠的參數,未經嚴格的檢查就立即使用CGI參數。 

   Web應用一般包含位於防火牆之內的和防火牆之外的兩部分,防火牆之內的如本地的腳本程序、數據庫、Web服務器以及本地數據文件等。由於這些部件都由管理員直接管理和控制,因此可以認為它們都是可以信任的。Web應用的其他組成部分位於防火牆之外,是不可信任的。這主要是指用戶的浏覽器——如果用戶使用浏覽器,而且沒有為了更方便地控制輸入Web應用的數據和發現Web應用中可能存在的問題而直接在telnet會話中輸入Web請求。 

   防火牆是可信任的Intranet和不可信任的Internet之間的分界線。 

   所有來自信任分界線之外的數據未經檢查就不應該進入Web應用,這包括所有傳遞給CGI腳本的參數,比如:GET、POST和COOKIE變量,HTTP_REFERER、HTTP_USER_AGENT和所有HTTP_*變量,以及所有其他遠程生成的變量值。在CGI腳本使用所有這些變量之前,都必須對它們進行合法性檢查,這種檢查可以確保變量的值確實在預期的范圍內。 

   例如,有些腳本在請求的HTTP_REFERER正確時就接受表單輸入,這是一種常見但錯誤的編程習慣。腳本用這種機制來防范偽造的請求是徒勞的。毫無疑問,對於攻擊者來說,掌握必需的HTTP_REFERER並將它並入請求的其余部分一起發送是輕而易舉的,因此這種保護是沒有用的。這種腳本的錯誤在於:在這類調用中必須檢查的不僅僅是HTTP_REFERER值,所有其他值都必須進行檢查。 

   下面這個簡單的PHP程序將輸出CGI參數b的值以及HTTP_REFERER的值: 

kris@valiant:~/www < cat test.php 
< ?php 
print "The value of b is $bn"; 
print "The value of HTTP_REFERER is $HTTP_REFERERn"; 
? > 

   用telnet連接到80端口,我們能夠向上述腳本提供任意的參數值b,同時還可以任意提供HTTP_REFERER值。我們把下面的幾行發送到服務器: 

GET /~kris/test.php?b=this+is+a+test HTTP/1.0 
Host: valiant.koehntopp.de 
Referer: http://www.attacker.com/die_sucker_die.html 
   下面是完整的會話過程: 
kris@valiant:~/www < telnet valiant 80 
Trying 193.102.57.3... 
Connected to valiant.koehntopp.de. 
Escape character is '^]'. 
GET /~kris/test.php?b=this+is+a+test HTTP/1.0 
Host: valiant.koehntopp.de 
Referer: http://www.attacker.com/die_sucker_die.html 
HTTP/1.1 200 OK 
Date: Sat, 08 Apr 2000 06:44:02 GMT 
Server: Apache/1.3.9 (Unix) (SuSE/Linux) PHP/4.0RC2-dev mod_ssl/2.4.7 OpenSSL/0.9.4 
X-Powered-By: PHP/4.0RC2-dev 
Connection: close 
Content-Type: text/html 

The value of b is this is a test 
The value of HTTP_REFERER is http://www.attacker.com/die_sucker_die.html 
Connection closed by foreign host. 
   注意b的值必須以URL編碼格式輸入。要將字符串進行URL編碼,可以使用一個簡單的PHP程序,例如: 


kris@valiant:~/www < cat urlencode.php 
#! /home/kris/bin/php -q 
< ?php 
print urlencode($argv[1])."n"; 
? > 
kris@valiant:~/www < ./urlencode.php "this is a test" 
this+is+a+test 
   發送HTTP POST請求只是稍微復雜一點:現在應該在這個請求中包含一個合法的Content-Type頭以及正確的內容長度字節數。下面是具體過程: 

kris@valiant:~/www < telnet valiant 80 
Trying 193.102.57.3... 
Connected to valiant.koehntopp.de. 
Escape character is '^]'. 
POST /~kris/test.php HTTP/1.0 
Host: valiant.koehntopp.de 
Referer: http://www.attacker.com/die_sucker_die.html 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 16 
b=this+is+a+test 
HTTP/1.1 200 OK 
Date: Sat, 08 Apr 2000 06:55:11 GMT 
Server: Apache/1.3.9 (Unix) (SuSE/Linux) PHP/4.0RC2-dev 
mod_ssl/2.4.7 OpenSSL/0.9.4 
X-Powered-By: PHP/4.0RC2-dev 
Connection: close 
Content-Type: text/html 
The value of b is this is a test 
The value of HTTP_REFERER is 
http://www.attacker.com/die_sucker_die.html 
Connection closed by foreign host. 

   另外一種常見的錯誤是把內部應用的狀態數據通過< INPUT TYPE="HIDDEN" >標記從一個頁面傳遞到另一個頁面。把內部應用的狀態放到信任界限之外就如把應用的心髒挖出來放到了攻擊者的面前。對於如此缺乏安全保障的應用,任何想要摧毀它的攻擊者都可以輕易地引導該應用並得到任何想要的效果。應用的狀態應該通過會話變量保存在服務器上,永遠不應該跨越信任界限。所有的Web應用開發平台都有這種機制。例如在PHP3中,PHPLIB可用於保存會話數據,PHP4使用的是session_*()調用,ASP提供Session對象,Cold Fusion提供幾種不同的會話變量。 
   Web應用不應該把任何來自信任界線之外的數據直接保存為會話變量:會話變量是可信任的變量,不應該用來保存不可信任的數據。通常,來自外面的數據(比如表單變量的數據)應該先傳入檢驗其合法性的函數。只有當檢驗函數表示表單提供的數據是安全的,才可以把表單數據復制到會話變量。Web應用應該把這種檢查集中到一起進行,應用的所有其余部分永遠不應該直接接觸表單變量,而是應該使用經過檢查且確認安全的會話數據。 

   參考: 

http://www.koehntopp.de/kris/artikel/webtune/ 
"Webserver verstehen und tunen" (德語) 
http://www.koehntopp.de/php/ 
"de.comp.lang.php - H‰ufig gestellte Fragen" (德語) 
http://www.insecure.org/nmap/ 
"NMAP Port Scanner" (英語) 
http://ethereal.zing.org/ 
"Ethereal Network Monitor" (英語) 
http://www.marko.net/cheops 
"Ceops Network Mapper" (英語) 
http://freshmeat.net/appindex/1998/04/06/891857252.html 
"lsof - list open files" (英語) 

"TCP/IP Illustrated, Volume 1: The Protocols" (英語) 
W. Richard Stevens 
Addison-Wesley 

"Hacking Exposed - Network Security Secrets & Solutions" (英語) 
McClure, Scambray and Kurtz 
http://phplib.netuse.de/ 
"A library for PHP application development" (英語)

Copyright © Windows教程網 All Rights Reserved