52AV手機A片王|52AV.ONE

標題: 如何正確的取得使用者 IP? [打印本頁]

作者: IT_man    時間: 2015-7-3 10:46
標題: 如何正確的取得使用者 IP?
本帖最後由 IT_man 於 2015-7-3 10:47 編輯 / z7 {3 p5 h) V1 t' U, B

% ]0 u3 N& F" I/ b1 K. s- a1 }9 G9 c很多網站都會有偵測使用者 IP 的功能,不管是判斷使用者來自哪邊,或者是記錄使用者的位置。但是你知道嗎?網路上大多數的教學全部都是「錯誤」的。正確的程式寫法可以確保知道訪客的 IP,但是錯誤的寫法卻可能讓網站管理者永遠不知道犯罪者的來源。
7 |& B7 t5 v! k. N" c: ^
: l! ?2 b) H$ H- y  N4 {這次我們單就偵測 IP 的議題來探討各種錯誤的寫法。
  W% d8 F) i$ q" T& |6 E. u+ r) V: n! i( C+ z: r* A

2 Y' @% t1 I. Z! G% s, O你知道網路上的教學是不安全的嗎?8 D% x+ n* v! H
我們先來看一下網路上的教學,讓我們 Google 找一下「PHP 取得 IP」,就可以看到許多人熱心的教學,我們隨意挑一個常見的教學來看看。0 I" u- E% |! M
以 PHP 為例:8 q  j2 h3 q& D0 d
  1. <?php$ Y8 X+ T' p. v1 U; W+ G
  2. if(!empty($_SERVER['HTTP_CLIENT_IP'])){
    2 n, N9 R6 V4 Y- l- |3 H
  3.    $myip = $_SERVER['HTTP_CLIENT_IP'];' s$ ]  @) T7 C% e4 W# r
  4. }else if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){- x% S+ m; r- m, n% V' b
  5.    $myip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    5 D) h9 p" J! x/ y. O% T
  6. }else{
    : D* D" G% B% P8 C5 Y$ v
  7.    $myip= $_SERVER['REMOTE_ADDR'];
    ' a1 I# O3 H( _7 f+ r9 @5 U0 D
  8. }
    5 M* `1 L9 p$ U, [  c9 x" S
  9. echo $myip;
    % z, B6 q: q* Y# u- E
  10. ?>
複製代碼
. Z5 V! k9 \# s* |" q

/ N; N! u' ]1 U4 _( Y) K' }7 [" X這是一個很基本的寫法、很正確的想法,如果 HTTP Header 中包含「Client-IP」,就先以他當作真實 IP。若包含「X-Forwarded-For」,則取他當作真實 IP。若兩者都沒有,則取「REMOTE_ADDR」變數作為真實 IP。因為當使用者連線時透過代理伺服器時,REMOTE_ADDR 會顯示為代理伺服器 Proxy 的 IP。部分代理伺服器會將使用者的原始真實 IP 放在 Client-IP 或 X-Forwarded-For header 中傳遞,如果在變數中呼叫則可以取得真實 IP。
( b! P8 E& |. \1 F7 a但是你知道嗎?網路上 80% 的教學寫法全部都是「錯誤」的。! P5 e7 a+ ?2 c2 |* H; E4 W9 w
- b" ^9 d: }# n" T
為什麼這樣說呢?請大家記得一件事情:「任何從客戶端取得的資料都是不可信任的!
  i& r( S3 w7 c: ^, S" }* n" q- E* k1 X) f' s9 L
竄改 HTTP Header「X-Forwarded-For」這個變數雖然「有機會」取得使用者的真實 IP,但是由於這個值是從客戶端傳送過來的,所以「有可能」被使用者竄改。- Q/ E; t" M- S0 b( q
舉例來說,我寫了一個小程式,偵測這些常見的 HTTP Header 判斷 IP。並且使用 Burp Suite 這個工具來修改 HTTP Request。
4 `3 d! ?$ m" X, q5 q6 t3 S; v. c $ c' ?# F: j1 J( I4 z* B
( X* Q* F+ D+ {+ c, m$ N
頁面上顯示目前我目前的 IP「49.50.68.17」,並且其他的 header 是空的。但如果我今天使用 Burp Suite 之類的 Proxy 工具自行竄改封包,加上 X-Forwarded-For 或是 Client-IP header:9 ~% |+ ~9 U5 C0 Y) M! T/ e, I
( p0 L: V$ c+ y- a
修改完畢之後,再到原本的顯示 IP 介面,會發現網頁錯將我竄改的 header 當作正確的資料填入。2 n& m& O/ n8 L% \2 F
% d6 ]& @, E: J9 _7 |# j0 N% ?

/ s) s2 e  Y8 a; b* u! b. }6 o% j使用代理伺服器 Proxy 的情況使用代理伺服器的情況下,HTTP Header 會有不同的行為。例如 Elite Proxy 如何隱藏客戶端的真實 IP。以下簡單介紹幾種常見的狀況給各位參考。
9 B0 k* M) Z0 y4 A直接連線 (沒有使用 Proxy)Transparent ProxyAnonymous ProxyHigh Anonymity Proxy (Elite Proxy)實際情況在我們測試的過程中,通常我們都會讓瀏覽器自帶 X-Forwarded-For,並且自行填入 IP。常常會發現有一些網站出現如下的警告…
. G$ b7 X7 c' E+ u0 @! S- G
8 n2 r4 @' C" h( m% e! P7 d- F有沒有搞錯?「上次登入位置 127.0.0.1」?沒錯,這個是知名論壇套件「Discuz!」的功能,抓取 IP 的功能也是不安全的寫法。也有這樣的經驗,之前開著 X-Forwarded-For 的 header 到一些網站,竟然直接出現管理者後台!
" ^; ]9 H0 [- U& T6 A  B1 t) D你覺得只有一般人撰寫的程式會有這樣的問題嗎?其實大型網站也可能會有類似的問題:) I! k! i5 u6 n
" H; o2 `" z9 C2 \6 [' |; W) j5 F  S
先不論為什麼 127.0.0.1 會在美國,這樣的寫法可能會讓管理者永遠抓不到犯罪者的真實 IP,甚至攻擊者可以竄改 header 插入特殊字元,對網站進行 SQL Injection 或者 Cross-Site Scripting 攻擊。
7 Y5 N* ~+ i1 g, j* p( W! }9 H7 E$ N% f4 t) d* c/ t
正確又安全的方式任何從客戶端取得的資料都是不可信任的!
! E2 W0 a' [0 t0 w2 G2 t請各位開發者、管理者記住這個大原則,雖然這些 Request Header 可能含有真實 IP 的資訊,但是因為他的安全性不高,因此我們絕對不能完全信賴這個數值。
: x+ u+ R# a& C: E0 ~2 m/ G那我們該怎麼處理呢?我的建議是記錄所有相關的 header 欄位存入資料庫,包含「REMOTE_ADDR」「X-Forwarded-For」等等,真正有犯罪事件發生時,就可以調出所有完整的 IP 資訊進行人工判斷,找出真正的 IP。當然從 header 存入的數值也可能會遭到攻擊者竄改插入特殊字元嘗試 SQL Injection,因此存入值必須先經過過濾,或者使用 Prepared Statement 進行存放。
' Z/ Z8 u+ O5 E可以參考的 HTTP Header(依照可能存放真實 IP 的順序)* HTTP_CLIENT_IP* HTTP_X_FORWARDED_FOR* HTTP_X_FORWARDED* HTTP_X_CLUSTER_CLIENT_IP* HTTP_FORWARDED_FOR* HTTP_FORWARDED* REMOTE_ADDR (真實 IP 或是 Proxy IP)* HTTP_VIA (參考經過的 Proxy)
. I- @# ]6 c& \! i+ J" k" R" }「駭客思維」就是找出網站任何可能竄改的弱點,從網頁上的元素到 HTTP Header 都是嘗試的對象。因此身為防禦者一定要清楚的知道哪些數值是不能信賴的,不要再參考網路上錯誤的教學了!2 [4 t- B5 y7 }% X" N1 T

8 X( g3 r$ q5 o9 x- O4 R: L*原文參考 CEO Allen Own 大作  http://devco.re/blog/2014/06/19/client-ip-detection/
8 A. z, f+ a$ ?7 {




歡迎光臨 52AV手機A片王|52AV.ONE (https://www.itech.casa/) Powered by Discuz! X3.2