實驗吧-貌似有點難-http頭部ip地址偽造
首先,先來看這道題的原始碼:
<?php function GetIP(){ if(!empty($_SERVER["HTTP_CLIENT_IP"])) $cip = $_SERVER["HTTP_CLIENT_IP"]; else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) $cip = $_SERVER["HTTP_X_FORWARDED_FOR"]; else if(!empty($_SERVER["REMOTE_ADDR"])) $cip = $_SERVER["REMOTE_ADDR"]; else $cip = "0.0.0.0"; return $cip; } $GetIPs = GetIP(); if ($GetIPs=="1.1.1.1"){ echo "Great! Key is *********"; } else{ echo "錯誤!你的IP不在訪問列表之內!"; } ?>
即是不懂PHP語言,也能看出來程式碼的意思是如果IP是“1.1.1.1”,name就能獲取key值。所以,在我們ip不是“1.1.1.1”的時候,怎麼做到這個呢?
再根據上面的GetIP()程式碼提示,判斷我們IP會經過三步,首先檢測是HTTP_CLIENT_IP,它對應的是header中的client-ip,然後是HTTP_X_FORWARDED_FOR,它對應的header中的x-forwarded-for,伺服器端HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2其中的值通過一個 逗號+空格 把多個IP地址區分開, 最左邊(client1)是最原始客戶端的IP地址, 代理伺服器每成功收到一個請求,就把請求來源IP地址新增到右邊。
最後檢測的是REMOTE_ADDR,這個引數不是客戶端能夠操作的引數,它屬於TCP/IP的網路層的東西,所以很難偽造(但不是不可以呀,中轉器中比如路由器中是可以實現的)。但是!!!前面都是客戶端提交http請求的頭部的內容啊,是可以偽造的,所以此題就迎刃而解了。
解法一:
http頭部中新增:X-forwarded-for:1.1.1.1
解法二:
http頭部中新增:Client-IP:1.1.1.1
兩種方法均可順利獲取key值。
深入——怎麼防止IP偽造呢?
既然這麼輕鬆就可以偽造IP地址了,伺服器通過什麼方法獲取真實客戶端IP呢,REMOTE_ADDR雖然難以偽造,是伺服器根據客戶端ip指定的,代表了真實的客戶端IP,但是經過代理伺服器,或者負載均衡,CDN等裝置之後,到達伺服器,伺服器會把REMOTE_ADDR值設為這些中轉裝置的ip,此時伺服器就失去了真實的ip了。HTTP_CLIENT_IP 在經過代理後,也代表了代理伺服器IP。
此時想到可以在轉發時主動將X-forwarded-for配置為正確的ip地址,將REMOTE_ADDR的值賦值給X-forwarded-for,這樣在離開了客戶端之後,便儲存了真實的客戶端ip。
參考文獻:
1、https://blog.csdn.net/smilefyx/article/details/52120461
2、https://segmentfault.com/a/1190000007407810?utm_source=tag-newest