【W(wǎng)EB開(kāi)發(fā)】偽造X-Forwarded-For繞過(guò)服務(wù)器IP地址過(guò)濾
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
在正常的TCP/IP 通信中,是可以偽造數(shù)據(jù)包來(lái)源 IP 的,但這會(huì)讓發(fā)送出去的數(shù)據(jù)包返回到偽造的IP上,無(wú)法實(shí)現(xiàn)正常的通信。 實(shí)現(xiàn)TCP/IP層級(jí)別的偽造很難,因?yàn)楹茈y實(shí)現(xiàn)正常的TCP連接;但是在應(yīng)用層協(xié)議HTTP上的實(shí)現(xiàn)較容易,通過(guò)偽造IP,能欺騙多數(shù)服務(wù)器應(yīng)用程序?qū)崿F(xiàn)通信。對(duì)于繞過(guò)服務(wù)器的IP地址過(guò)濾或者偽造來(lái)源IP特別有用,導(dǎo)致的后果就是非授權(quán)IP能訪問(wèn)服務(wù)器,甚至能鉆服務(wù)器的漏洞。 這其中的關(guān)鍵就是偽造X-Forwarded-For。 一、X-Forwarded-For介紹 我們知道 HTTP 連接基于 TCP 連接,HTTP 協(xié)議中沒(méi)有 IP 的概念,只能通過(guò)X-Forwarded-For來(lái)實(shí)現(xiàn)。 X-Forwarded-For位于HTTP協(xié)議的請(qǐng)求頭, 是一個(gè) HTTP 擴(kuò)展頭部。HTTP/1.1(RFC 2616)協(xié)議并沒(méi)有對(duì)它的定義,它最開(kāi)始是由 Squid 這個(gè)緩存代理軟件引入,用來(lái)表示 HTTP 請(qǐng)求端真實(shí) IP。如今它已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn),被各大 HTTP 代理、負(fù)載均衡等轉(zhuǎn)發(fā)服務(wù)廣泛使用,并被寫(xiě)入RFC 7239(Forwarded HTTP Extension)標(biāo)準(zhǔn)之中。 X-Forwarded-For 請(qǐng)求頭格式非常簡(jiǎn)單:
可以看到,XFF 的內(nèi)容由「英文逗號(hào) + 空格」隔開(kāi)的多個(gè)部分組成,最開(kāi)始的是離服務(wù)端最遠(yuǎn)的設(shè)備 IP,然后是每一級(jí)代理設(shè)備的 IP。 如果一個(gè) HTTP 請(qǐng)求到達(dá)服務(wù)器之前,經(jīng)過(guò)了三個(gè)代理 Proxy1、Proxy2、Proxy3,IP 分別為 IP1、IP2、IP3,用戶真實(shí) IP 為 IP0,那么按照 XFF 標(biāo)準(zhǔn),服務(wù)端最終會(huì)收到以下信息: X-Forwarded-For: IP0, IP1, IP2 Proxy3 直連服務(wù)器,它會(huì)給 XFF 追加 IP2,表示它是在幫 Proxy2 轉(zhuǎn)發(fā)請(qǐng)求。列表中并沒(méi)有 IP3,IP3 可以在服務(wù)端通過(guò) Remote Address 字段獲得。Remote Address來(lái)自 TCP 連接,表示與服務(wù)端建立 TCP 連接的設(shè)備 IP,在這個(gè)例子里就是 IP3。 Remote Address 無(wú)法偽造,因?yàn)榻?TCP 連接需要三次握手,如果偽造了源 IP,無(wú)法建立 TCP 連接,更不會(huì)有后面的 HTTP 請(qǐng)求。不同語(yǔ)言獲取Remote Address的方式不一樣,例如Node.js 是req.connection.remoteAddress,原理都一樣。 一般的客戶端(例如:瀏覽器)在發(fā)送HTTP請(qǐng)求時(shí),并不會(huì)設(shè)置X-Forwarded-For頭,當(dāng)請(qǐng)求在到達(dá)第一個(gè)代理服務(wù)器時(shí),代理服務(wù)器會(huì)在請(qǐng)求字段中加上X-Forwarded-For這個(gè)字段,并將其值設(shè)置為客戶端的IP地址,后面如果還有更多的代理服務(wù)器,會(huì)依次將Ip地址追加到X-Forwarded-For這個(gè)字段中,最終當(dāng)請(qǐng)求到達(dá)了Web應(yīng)用服務(wù)器,應(yīng)用會(huì)通過(guò)獲取X-Forwarded-For頭取出最左邊的IP地址,即為客戶端的真實(shí)IP地址。 如果客戶端在發(fā)起請(qǐng)求時(shí),請(qǐng)求頭上帶上一個(gè)偽造的X-Forwarded-For,由于后續(xù)每層代理只會(huì)追加而不會(huì)覆蓋,那么最終到達(dá)應(yīng)用服務(wù)器時(shí),最左邊的IP地址就是客戶端偽造的IP地址。 這個(gè)利用方法可以繞過(guò)一些針對(duì)IP地址進(jìn)行限制的應(yīng)用,例如:投票等應(yīng)用 一般在nginx中會(huì)進(jìn)行如下的配置
這種如果沒(méi)有X-Forwarded-For消息頭會(huì)添加消息頭,如果存在該消息頭則會(huì)在后面追加一個(gè)IP。 二、X-Forwarded-For偽造 下面就是一種常見(jiàn)的獲取客戶端真實(shí)IP的方式
可以通過(guò)抓包的方式偽造X-Forwarded-For頭,如下 三、修復(fù)方式 目前很多Web 應(yīng)用(例如獲取用戶所在地區(qū),基于 IP 做訪問(wèn)頻率控制,禁止某些IP訪問(wèn)等等),為了獲取用戶真正的 IP,從 HTTP 請(qǐng)求頭中獲取 IP地址。這些情況下,必須確保獲取到的IP地址是真實(shí)可靠的。 經(jīng)過(guò)前面的分析和測(cè)試, 1.對(duì)于直接使用的 Web 應(yīng)用,必須使用從TCP連接中得到的 Remote Address,才是用戶真實(shí)的IP; 2.對(duì)于使用 nginx 反向代理服務(wù)器的Web應(yīng)用,nginx必須使用Remote Address正確配置set Headers,后端服務(wù)器則使用nginx傳過(guò)來(lái)的相應(yīng)IP地址作為用戶真實(shí)IP。 正確配置nginx的方式,就是在最外層的代理服務(wù)器強(qiáng)制設(shè)定X-Forwarded-For的值為REMOTE ADDRESS。配置如下
在最外層Nginx(即直接對(duì)外提供服務(wù)的Nginx)使用$remote_addr代替上面的$proxy_add_x_forwarded_for,可以防止偽造X-Forwarded-For。$proxy_add_x_forwarded_for會(huì)在原有X-Forwarded-For上追加IP,這就相當(dāng)于給了偽造X-Forwarded-For的機(jī)會(huì)。而$remote_addr是獲取的是直接TCP連接的客戶端IP,這個(gè)是無(wú)法偽造的,即使客戶端偽造也會(huì)被覆蓋掉,而不是追加。 其它一下相似的消息頭,也可以嘗試使用這些消息頭進(jìn)行繞過(guò)
閱讀原文:原文鏈接 該文章在 2025/5/14 9:29:40 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |