Host注入小結(jié)及BP插件開發(fā)

初識Http Host:


http版本從開始的1.0到1.1以及以后的1.2經(jīng)歷三個版本穗椅, 在Http請求頭中胁勺,Host頭指定請求資源的Intenet主機和端口號翅雏。在1.1中host標(biāo)頭的主要功能將客戶端請求分發(fā)到內(nèi)部具體的域名中,當(dāng)然如果存在nginx反向代理或負(fù)載均衡等情況下當(dāng)流量到達(dá)服務(wù)器之前可能會更改host的值匣椰。

通常來說一臺服務(wù)器會有多個web應(yīng)用程序板惑,當(dāng)我們配置基于端口的虛擬主機橄镜,不同的web程序可以通過不同的端口來判斷。但當(dāng)我們配置基于域名的虛擬主機時冯乘,一個IP地址可以對應(yīng)多個域名洽胶,比如有幾個不同的域名:a.com、b.com裆馒、c.com姊氓,這幾個域名通過A記錄或者CNAME記錄最終和虛擬主機IP相關(guān)聯(lián),當(dāng)我們訪問這幾個域名最終會解析到同一個IP喷好,但是服務(wù)端該如何區(qū)分不同域名以返回不同的內(nèi)容呢翔横?這時就可以通過Host字段區(qū)分出客戶端具體訪問的站點是哪一個,web服務(wù)器使用該頭部的值來將請求分派到指定的網(wǎng)站或web應(yīng)用程序之上梗搅。

Host被解析的大致流程如下:

客戶端 --》請求 --》URL --》解析IP地址 --》服務(wù)器 --》解析Host值 --》轉(zhuǎn)發(fā)具體域名

漏洞成因:


由于HTTP的Host頭可以由用戶所控制禾唁,如果服務(wù)器充分信任客戶端所提交的數(shù)據(jù),web應(yīng)用程序僅通過Http的Host字段進(jìn)行解讀或者支持X-Forwarded-Host无切、X-Host等標(biāo)頭荡短,就可能會產(chǎn)生一些安全風(fēng)險,包括SSRF哆键、XSS掘托、未授權(quán)訪問、緩存污染和密碼重置等等洼哎。很多應(yīng)用直接把Host值不做html編碼便輸出到了頁面中烫映,比如:

<link href=http://_SERVER["HTTP_HOST"]></link>    //觸發(fā)一個get請求
<form method=”POST”></form>                       //觸發(fā)POST請求

當(dāng)Host字段被修改為攻擊者構(gòu)造的惡意地址沼本,這時噩峦,就會觸發(fā)惡意請求。

安全風(fēng)險:


  • 1. 密碼重置:

在很多實際場景中抽兆,為了獲取網(wǎng)站的域名并拼接令牌作為重置密碼的鏈接识补,獲取正確的域名并不是一件很容易的事情, 而用一個固定的URI來作為域名可能會導(dǎo)致其他問題。

一種普遍的用來實現(xiàn)密碼重置功能的方法是:生成一個密鑰令牌辫红,并且發(fā)送一封包含著該令牌的超級鏈接的電子郵件凭涂。程序員會采用request.getHeader("Host")或者$_SERVER['HTTP_HOST']的方式來獲取域名祝辣。假設(shè)存在這樣一個場景,當(dāng)攻擊者請求一個帶有惡意Domain的Host頭類型的密碼重置切油,web應(yīng)用程序使用攻擊者所偽造的Host頭來生成重置鏈接并發(fā)送給受害者蝙斜,如果受害者點開了郵件中“帶毒”的重置鏈接,那么攻擊者將能獲得密碼重置的令牌澎胡,進(jìn)而可以重置受害者的密碼了孕荠。攻擊者通過一個受他控制的鏈接來污染密碼重置的郵件。

舉個例子:
存在這樣一個情景:訪問目標(biāo)網(wǎng)站xxx.com的忘記密碼功能攻谁,在其中輸入用戶名信息請求獲得重置密碼鏈接:http://xxx.com/user/reset_password
攻擊者從中修改Host字段或者添加X-Forwarded-Host字段的值未攻擊者可控的一臺主機地址稚伍,比如X-Forwarded-Host:evil.com,打開郵箱后發(fā)現(xiàn)重置鏈接為:https://evil.com/user/reset_password/xc456132xDzwE1FjX8RtIUc1DTcm1B5Kqb53j1fLEkzMW2GPgCpuEODDStpRaES戚宦,當(dāng)用戶去點擊鏈接時个曙,攻擊者就可通過web服務(wù)器日志信息獲取令牌,從而實現(xiàn)目標(biāo)賬戶劫持受楼。

  • 2. XSS:

有些網(wǎng)站會根據(jù)HOST字段來進(jìn)行加載css樣式表垦搬。當(dāng)域名發(fā)生改變時,站內(nèi)所有的css即將失效那槽。

另外悼沿,由于系統(tǒng)沒有對 HTTP 頭進(jìn)行任何的特殊符號以及敏感字符串的過濾,攻擊者可以利用此漏洞往 Web 頁面里插入惡意 HTML 代碼骚灸,當(dāng)用戶瀏覽該頁之時糟趾,嵌入其中 Web 里面的 HTML 代碼會被執(zhí)行,從而達(dá)到惡意攻擊用戶的特殊目的甚牲,例如網(wǎng)絡(luò)釣魚攻擊义郑。

  • 3. Web緩存投毒:

先簡單介紹下web緩存的概率:通過減少延遲來加速頁面加載,降低應(yīng)用程序服務(wù)器上的負(fù)載丈钙。每當(dāng)緩存服務(wù)收到對資源的請求時非驮,它需要確定它是否已經(jīng)保存了這個指定資源的副本,并且可以使用該副本進(jìn)行響應(yīng)雏赦,或者是否需要將請求轉(zhuǎn)發(fā)給應(yīng)用程序服務(wù)器劫笙。

Web緩存投毒的目的是發(fā)送導(dǎo)致有害響應(yīng)的請求,將該響應(yīng)將保存在緩存服務(wù)中并提供給其他用戶星岗。一般的緩存服務(wù)器都會識別hsot,所以一般直接替換host字段會被攔截填大,我們可以通過尋找由非緩存鍵導(dǎo)致的差異化響應(yīng),但是緩存的響應(yīng)也有可能會掩蓋住非緩存鍵的輸入俏橘,因此我們需要去進(jìn)行手動檢測或發(fā)現(xiàn)非緩存鍵的輸入允华,另外在輸入非緩存鍵的同時可以配合XSS等輔助漏洞進(jìn)一步造成危害。

另外,當(dāng)web服務(wù)器的中間件為Nginx時靴寂,它只看最后一個請求磷蜀,從而我們可以繞過緩存服務(wù)器的檢查,形如:

GET / HTTP/1.1
Host: test.com
Host: vuln.com

感興趣的師傅可以去閱讀下面兩篇文章:
實戰(zhàn)web緩存中毒
淺談http中的Cache-Control

  • 補充:

當(dāng)Host頭部被修改為無效Host頭時百炬,大多數(shù)web服務(wù)器配置為將無法識別的Host頭傳送給列表中的第一臺虛擬主機或者返回錯誤信息褐隆。因此,這使得把攜帶有任意Host頭的請求發(fā)送到第一臺虛擬主機上是可能的剖踊。
如果Apache接收到一個帶有非法host header的請求妓灌,它會將此請求轉(zhuǎn)發(fā)給在 httpd.conf 里定義的第一個虛擬主機。因此蜜宪,Apache很有可能將帶有任意host header的請求轉(zhuǎn)發(fā)給應(yīng)用

防范建議:


  • 不要信任host頭虫埂,只要是能被客戶端修改的值,都是不可信任的圃验。
  • 當(dāng)必須使用host頭作為一種識別web服務(wù)器位置的機制的話掉伏,在web框架中以白名單方式驗證,只允許在白名單中的域
  • 在后端配置文件中結(jié)合業(yè)務(wù)情況禁用絕對路徑的url澳窑,采用相對路徑如/test/1.php
  • 如必須絕對路徑斧散,應(yīng)手動添加絕對路徑并指定域名如https://xxxx.com/test/1.php,在配置文件中引用此值摊聋,而不是host值
  • 禁用不需要的標(biāo)頭如XFH鸡捐,XH等,一些中間件默認(rèn)可能支持XFH標(biāo)頭

burp被動檢測插件設(shè)計思路:


1.利用Burp的CollaboratorClient麻裁,使用generatePayload方法生成了一個dnslog的地址
2.監(jiān)聽響應(yīng)包箍镜,過濾掉狀態(tài)碼為403和404的數(shù)據(jù)包
3.獲取請求頭部,將Host字段替換為第一步生成的dnslog地址
4.構(gòu)造請求包并發(fā)送煎源,獲取其響應(yīng)包的請求頭部色迂、body和狀態(tài)碼
5.當(dāng)狀態(tài)碼為301或者302時,判斷第一步生成的dnslog地址是否在響應(yīng)包的Location
6.判斷第一步生成的dnslog地址是否在響應(yīng)包的body部分
7.利用fetchCollaboratorInteractionsFor()方法判斷是否有接收到dns或者h(yuǎn)ttp請求

IBurpExtender接口類是Burp插件的入口手销,所有Burp的插件均需要實現(xiàn)此接口歇僧,并且類命名為 BurpExtender。

class BurpExtender(IBurpExtender, IScannerCheck, IBurpCollaboratorClientContext):
    # registerExtenderCallbacks 方法在插件被加載后會被調(diào)用锋拖,在所有擴展插件中必須實現(xiàn)這個接口
    def registerExtenderCallbacks(self, callbacks):
        # Required for easier debugging:
        sys.stdout = callbacks.getStdout()
        
        # keep a reference to our callbacks object (Burp Extensibility Feature)
        self._callbacks = callbacks
        
        # 用于獲取IExtensionHelpers對象诈悍,擴展可以使用該對象執(zhí)行許多有用的任務(wù)。返回:包含許多幫助器方法的對象兽埃,用于構(gòu)建和分析HTTP請求等任務(wù)侥钳。
        self._helpers = callbacks.getHelpers()
        
        # 設(shè)置當(dāng)前擴展的顯示名稱
        callbacks.setExtensionName('Host Scan')
        
        # 利用Burp的CollaboratorClient,使用generatePayload方法生成了一個dnslog的地址
        self.collaboratorContext = callbacks.createBurpCollaboratorClientContext()
        self.payload = self.collaboratorContext.generatePayload(True)
        print str(self.payload)
        
        # 注冊掃描
        callbacks.registerScannerCheck(self)
# 獲取請求頭部
self.baseRequestResponse = baseRequestResponse
request = self.baseRequestResponse.getRequest()
analyzedRequest = self._helpers.analyzeRequest(request)
request_header = analyzedRequest.getHeaders()
# 構(gòu)造請求并發(fā)送讲仰,對響應(yīng)包的頭部和body進(jìn)行匹配
newMessage = self._helpers.buildHttpMessage(new_req_header, request_bodys)
newIHttpRequestResponse = self._callbacks.makeHttpRequest(httpService, newMessage)
newResponse = newIHttpRequestResponse.getResponse()
newResponseInfo = self._helpers.analyzeResponse(newResponse)
newResponseBody = newResponse[newResponseInfo.getBodyOffset():].tostring()
newResponseStatus = newResponseInfo.getStatusCode()
newResponseHeader = newResponseInfo.getHeaders()
match_result = re.search(r'(http|https)(://|%3A%2F%2F)' + str(self.payload).strip(), newResponseBody)
if str(newResponseStatus) in ['301', '302'] and str(self.payload).strip() in str(newResponseHeader):
    issues.append(CustomScanIssue(
        newIHttpRequestResponse.getHttpService(),
        self._helpers.analyzeRequest(newIHttpRequestResponse).getUrl(),
        [newIHttpRequestResponse],
        "Host injection in Header!",
        "Found Fake Host In Header",
        "Medium"))
match_result = re.search(r'(http|https)(://|%3A%2F%2F)' + str(self.payload).strip(), newResponseBody)
if match_result:
    issues.append(CustomScanIssue(
        newIHttpRequestResponse.getHttpService(),
        self._helpers.analyzeRequest(newIHttpRequestResponse).getUrl(),
        [newIHttpRequestResponse],
        "Host injection in Body!",
        "Found Fake Host In Body",
        "Medium"))
    # return issues
if self.collaboratorContext.fetchCollaboratorInteractionsFor(self.payload):
    issues.append(CustomScanIssue(
        newIHttpRequestResponse.getHttpService(),
        self._helpers.analyzeRequest(newIHttpRequestResponse).getUrl(),
        [newIHttpRequestResponse],
        "Host injection!",
        "Found HTTP Request/DNS Query!",
        "High"))
return issues

最終實現(xiàn)效果如下慕趴,當(dāng)發(fā)現(xiàn)生成的dnslog地址出現(xiàn)在響應(yīng)包頭或者body中時:

當(dāng)發(fā)現(xiàn)服務(wù)端主動發(fā)送dns或者h(yuǎn)ttp請求到dnslog時(SSRF):

另外還可以在請求頭中添加X-Forwarded-Host、X-Host等標(biāo)頭進(jìn)一步進(jìn)行測試鄙陡。

參考如下:


http host頭攻擊風(fēng)險分析
重新認(rèn)識被人遺忘的HTTP頭注入
技術(shù)干貨 | Web漏洞:Host頭部攻擊
在密碼重置請求包中添加X-Forwarded-Host實現(xiàn)受害者賬戶完全劫持

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載冕房,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末趁矾,一起剝皮案震驚了整個濱河市耙册,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毫捣,老刑警劉巖详拙,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蔓同,居然都是意外死亡饶辙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門斑粱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弃揽,“玉大人,你說我怎么就攤上這事则北】笪ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵尚揣,是天一觀的道長涌矢。 經(jīng)常有香客問我,道長快骗,這世上最難降的妖魔是什么娜庇? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮方篮,結(jié)果婚禮上思灌,老公的妹妹穿的比我還像新娘。我一直安慰自己恭取,他們只是感情好泰偿,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜈垮,像睡著了一般耗跛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上攒发,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天调塌,我揣著相機與錄音,去河邊找鬼惠猿。 笑死羔砾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姜凄,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼政溃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了态秧?” 一聲冷哼從身側(cè)響起董虱,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎申鱼,沒想到半個月后愤诱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡捐友,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年淫半,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匣砖。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡撮慨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脆粥,到底是詐尸還是另有隱情砌溺,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布变隔,位于F島的核電站规伐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏匣缘。R本人自食惡果不足惜猖闪,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肌厨。 院中可真熱鬧培慌,春花似錦、人聲如沸柑爸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽表鳍。三九已至馅而,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間譬圣,已是汗流浹背瓮恭。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厘熟,地道東北人屯蹦。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓维哈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親登澜。 傳聞我的和親對象是個殘疾皇子阔挠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容