實戰 | 記一次HOST頭中毒導致的密碼重置漏洞挖掘
0x01 前言
暑假的時候發現的一個騷思路。有些網站開發者會提取request包里的host頭來獲取域名信息,但是host頭可以被修改,是不可信的。于是攻擊者可以通過構造host頭來進行投毒攻擊。
例如發送包含受害者網站域名鏈接的功能,像是密碼找回、發送驗證鏈接等,只要業務上利用了類似于域名提取的功能,都可以嘗試利用該攻擊方法。這里以密碼找回為例,進行一次host頭投毒攻擊。
0x02 挖掘過程
某網站存在密碼找回功能,本例使用host頭中毒來實現任意用戶密碼重置。打開密碼找回界面,填寫受害用戶的郵箱,在最后的提交按鈕用burpsuite截斷,把host頭更改成自己的服務器IP:

之后放行數據包,會提示找回密碼郵件發送成功的信息,此時受害者郵箱會收到一封郵件:

可以看到,域名已經改成了我們在host頭填寫的服務器地址。這時受害者如果訪問該鏈接,則會在我們的服務器上留下一條記錄:

在把原域名和日志抓取到的url拼接一下,就能得到受害人的密碼重置鏈接了。
0x03 補充閱讀
這個漏洞是1click的任意密碼重置漏洞,利用了host頭中毒的思路,我個人感覺還是比較新穎的。不過像大廠安防策略都會對request頭數據進行檢驗,遇到不在白名單的域名直接會拒絕訪問。
什么是HTTP Host頭?
從HTTP/1.1開始,HTTP Host頭就是強制性的請求標頭。比如我們要訪問這個URL時 http://www.xxxx.com/web 瀏覽器會編寫個Host標頭的請求,"GET"請求的是頁面的相對路徑,"Host"就是主機頭,請求的是域名或服務器地址:
GET /web HTTP/1.1Host:www.xxxx.com
HTTP Host頭有何用處?
HTTP Host頭的目的是幫助識別客戶端想要與哪個后端組件通訊。
伴隨云和虛擬主機的普及,單個Web服務器可以托管多個網站或應用程序。盡管這些網站都有各自不同的域名,但很有可能共享服務器同一個IP地址,這種情況下就需要通過Host頭來進行區分了。
如何利用Host頭來進行攻擊?
如果網站沒有以安全的方式來處理Host值的話,就極易受到攻擊。一般Web應用程序通常不知道它們部署在哪個域上,當它們需要知道當前域時,很有可能會求助于Host頭。如果服務器完全信任Host頭,沒有驗證或轉義它的值,攻擊者可以把有害的Payload放入其中,當應用程序調用的時候,有害的Payload可能就會傳導進去造成“注入”。
而這種漏洞可以造成包括:
Web緩存中毒、特定功能的業務邏輯缺陷、基于路由的SSRF、SQL注入等
Bypass
通常來說,很少有站點會出現上面這種完全放開的現象,一般或多或少都有些過濾機制,但如果過濾做的不好,就會存在被繞過的可能性。
1.忽略端口的檢驗某些過濾檢查只驗證域名,會忽略Host頭中的端口。如果我們可以在Host頭中寫入非數字端口,就可以通過端口注入惡意Payload。GET /example HTTP/1.1Host:Website.com:bad-stuff-here 2.允許任意子域如果應用系統允許其域名下任意的子域通過,在這種情況下,可以通過子域來繞過驗證。GET /example HTTP/1.1Host:hacked-subdomain.Website.com 3.注入重復的Host頭有的時候我們可以添加多個Host頭,而且一般開發者并沒有預料到這種情況而沒有設置任何處理措施,這就可能導致某個Host頭會覆蓋掉另一個Host頭的值GET /exampleHTTP/1.1Host:Website.comHost:bad-stuff-here如果服務器端將第二個Host頭優先于第一個Host頭,就會覆蓋掉它的值,然后中轉組件會因為第一個Host頭指定了正確的目標而照常轉發這個請求包,這樣就能繞過中間組件將Payload傳遞給服務器。 4.提供絕對URL正常情況下,"GET"的請求航采用的是相對地址,但是也允許使用絕對地址,就是將原本Host的值拼接到相對地址前面構成絕對地址,這樣就可以利用Host頭進行注入。GET http://Website.com/ HTTP/1.1Host:bad-stuff-here 5.添加換行有時候還可以通過使用空格字符縮進HTTP頭來進行混淆,因為有些服務器會將縮進的標頭理解為換行,而將其視為前面頭值的一部分,有些服務器會完全忽略縮進的HTTP頭,因此不同系統處理HTTP頭可能會存在不一致的現象。GET /example HTTP/1.1Host:bad-stuff-hereHost:Website.com如果前端忽略縮進的頭部,這個請求會被作為普通請求來處理。假設后端忽略前導空格優先考慮第一個Host頭,這種不一致性會導致Payload的注入。 6.利用可覆蓋Host的請求頭有一些請求頭的值是可以覆蓋Host的值的,比如X-Forwarded-Host,當我們發出這樣的請求時就會觸發覆蓋GET /exampleHTTP/1.1Host:Website.comX-Forwarded-Host:bad-stuff-here可以達到相同目的的還有這些頭X-HostX-Forwarded-ServerX-HTTP-Host-OverrideForwarded
如何預防Host頭攻擊?
要防止HTTP Host頭攻擊,最簡單的方法就是避免在服務器端代碼中完全使用Host頭,不進行任何引入。如果確實要使用Host值的話,還有些其他的方法:
1.保護絕對URL2.驗證Host頭3.不支持Host覆蓋頭4.白名單允許的域5.小心使用僅限內部訪問的虛擬主機