午睡一觉醒来,突然想伪造IP地址。搜了一下,Mark。

源地址:http://www.cnblogs.com/lmule/archive/2010/10/15/1852020.html

-----------------------------------------------------------------------------------------------------------------------------------------------------------

看ecshop的lib_base.php的时候里面获取客户端真实ip的函数(real_ip),有许多情况的判断,主要判断客户端是否使用代理的情况,注意判断顺序,先判断客户端是否使用代理HTTP_X_FORWARDED_FOR

还是把源码附上吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
 * 获得用户的真实IP地址
 *
 * @access  public
 * @return  string
 */
function real_ip()
{
    static $realip = NULL;
    if ($realip !== NULL)
    {
        return $realip;
    }
    if (isset($_SERVER))
    {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
            foreach ($arr AS $ip)
            {
                $ip = trim($ip);
                if ($ip != 'unknown')
                {
                    $realip = $ip;
                    break;
                }
            }
        }
        elseif (isset($_SERVER['HTTP_CLIENT_IP']))
        {
            $realip = $_SERVER['HTTP_CLIENT_IP'];
        }
        else
        {
            if (isset($_SERVER['REMOTE_ADDR']))
            {
                $realip = $_SERVER['REMOTE_ADDR'];
            }
            else
            {
                $realip = '0.0.0.0';
            }
        }
    }
    else
    {
        if (getenv('HTTP_X_FORWARDED_FOR'))
        {
            $realip = getenv('HTTP_X_FORWARDED_FOR');
        }
        elseif (getenv('HTTP_CLIENT_IP'))
        {
            $realip = getenv('HTTP_CLIENT_IP');
        }
        else
        {
            $realip = getenv('REMOTE_ADDR');
        }
    }
    preg_match("/[\d\.]{7,15}/", $realip, $onlineip);
    $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
    return $realip;
}

顺便说下$_SERVER和getenv的区别,getenv不支持IIS的isapi方式运行的php

一、没有使用代理服务器的情况:

REMOTE_ADDR = 您的 IP
      HTTP_VIA = 没数值或不显示
      HTTP_X_FORWARDED_FOR = 没数值或不显示

二、使用透明代理服务器的情况:Transparent Proxies

REMOTE_ADDR = 最后一个代理服务器 IP
      HTTP_VIA = 代理服务器 IP
      HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

这类代理服务器还是将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。

三、使用普通匿名代理服务器的情况:Anonymous Proxies

REMOTE_ADDR = 最后一个代理服务器 IP
      HTTP_VIA = 代理服务器 IP
      HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。

四、使用欺骗性代理服务器的情况:Distorting Proxies

REMOTE_ADDR = 代理服务器 IP
      HTTP_VIA = 代理服务器 IP
      HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。

五、使用高匿名代理服务器的情况:High Anonymity Proxies (Elite proxies)

REMOTE_ADDR = 代理服务器 IP
      HTTP_VIA = 没数值或不显示
      HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

完全用代理服务器的信息替代了您的所有信息,就象您就是完全使用那台代理服务器直接访问对象。

REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。
HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。
$_SERVER['REMOTE_ADDR']; //访问端(有可能是用户,有可能是代理的)IP
$_SERVER['HTTP_CLIENT_IP'];  //代理端的(有可能存在,可伪造)
$_SERVER['HTTP_X_FORWARDED_FOR']; //用户是在哪个IP使用的代理(有可能存在,也可以伪造)

----------------------------------------------------------------------------------------------------

在WEB开发中.我们可能都习惯使用下面的代码来获取客户端的IP地址: 
C#代码

复制代码 代码如下:

//优先取得代理IP 
string IP = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; 
if (string.IsNullOrEmpty(IP)) { 
//没有代理IP则直接取连接客户端IP 
IP = Request.ServerVariables["REMOTE_ADDR"]; 
}

上面代码看来起是正常的.可惜这里却隐藏了一个隐患!!因为"HTTP_X_FORWARDED_FOR"这个值是通过获取HTTP头的"X_FORWARDED_FOR"属性取得.所以这里就提供给恶意破坏者一个办法:可以伪造IP地址!! 
下面是测试代码:

复制代码 代码如下:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://localhost/ip.aspx"); 
request.Headers.Add("X_FORWARDED_FOR", "0.0.0.0"); 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
StreamReader stream = new StreamReader(response.GetResponseStream()); 
string IP = stream.ReadToEnd(); 
stream.Close(); 
response.Close(); 
request = null;

"ip.aspx"文件代码:

复制代码 代码如下:

Response.Clear(); 
//优先取得代理IP 
string IP = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; 
if (string.IsNullOrEmpty(IP)) 

//没有代理IP则直接取客户端IP 
IP = Request.ServerVariables["REMOTE_ADDR"]; 

Response.Write(IP); 
Response.End();

这样.当测试代码中去访问ip.aspx文件时."string IP = stream.ReadToEnd();"这段代码取到的IP数据就是"0.0.0.0"!!!!(呵.在真实情况下.这样的IP地址肯定不是我们想要的结果.而在有些投票系统中限制一个IP只能投1次票时,如果也是用类似的代码取得对方IP然后再判断的话.呵呵.限制就失效咯)...

或者如果你用上面代码获取IP地址后后面又不再进行数据判断的话也许还能更进一步进行数据破坏!! 
比如你用类似上面的代码中获取IP地址就直接有这样的SQL语句: 
string sql = "INSERT INTO (IP) VALUE ('" + IP + "')"; 
那么也许破坏者还可以进行SQL注入进行数据破坏!!

这样看来利用"HTTP_X_FORWARDED_FOR"这个属性获取客户端IP的方法就不再可取了.-_-# 但如果不用这种方法.那么那些真正使用了代理服务器的人.我们又不能再获取到他们的真实IP地址(因为某些代理服务器会在"X_FORWARDED_FOR"这个HTTP头里加上访问用户真正的IP地址).呵.现实就是这样,某种东西都有有得必有失...

------------------------------------------------------------------------------------------------------

看了这两个帖子,终于明白为什么获取ip之后还要对其正则验证了,象我以前那种直接通过REMOTE_ADDR获取客户端ip,并且不对齐进行验证的想法是很傻很天真的,必须严厉打击!

转载于:https://www.cnblogs.com/oDoraemon/p/7509823.html

[转]REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR相关推荐

  1. Thinkphp 获取用户IP

    Thinkphp 获取用户IP php获取客户端IP地址有四种方法,这五种方法分别为 REMOTE_ADDR HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_VIA ...

  2. PHP获取客户端真实IP地址的方法

    php获取客户端IP地址有四种方法,这五种方法分别为 1 2 3 4 REMOTE_ADDR HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_VIA REMOTE_A ...

  3. PHP获得真实客户端的真实IP REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR

    REMOTE_ADDR 是你的客户端跟你的服务器"握手"时候的IP.如果使用了"匿名代理",REMOTE_ADDR将显示代理服务器的IP. HTTP_CLIEN ...

  4. 关于HTTP_CLIENT_IP,HTTP_X_FORWAR

    HTTP_CLIENT_IP:可通过http头伪造 HTTP_X_FORWARDED_FOR:可通过http头伪造 REMOTE_ADDR:可能是用户真实IP也可能是代理IP 服务端获取IP地址 ht ...

  5. HTTP 请求头中的 Remote_Addr,X-Forwarded-For,X-Real-IP

    REMOTE_ADDR 表示发出请求的远程主机的 IP 地址,remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间 ...

  6. 【译】Yii2 0 高级模版编写使用自定义组件(component)

    原文:http://www.yiiframework.com/wiki/760/yii-2-0-write-use-a-custom-component-in-yii2-0-advanced-temp ...

  7. BUU Web[33-36]

    [网鼎杯 2018]Fakebook 解题思路 打开页面就是login和join两个功能,尝试下注入无果,随便注册一个账号,发现blog有格式限制,注册后登陆 发现会有一个the content of ...

  8. PHP获取真实客户端的真实IP

    REMOTE_ADDR 和HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR REMOTE_ADDR 是你的客户端跟你的服务器"握手"时候的IP.如果使用了&q ...

  9. php牛逼的面试题分享

    1.nginx使用哪种网络协议?  nginx是应用层 我觉得从下往上的话 传输层用的是tcp/ip 应用层用的是http  fastcgi负责调度进程 2. <? echo 'hello tu ...

  10. PHPWind 源码解析

    保留关键字  函数  类型  字符串  注释  括号       数字  运算符  预定义变量  PHP 开始结束标签 global.php QUOTE: <?php  /**  *  * Co ...

最新文章

  1. pandas object转float_数据分析篇 | Pandas基础用法6【完结篇】
  2. linux ftrace原理
  3. wxDrawjs循环添加图形后增加标识记录点击的是哪个的另类方法
  4. Linux搭建SVN(CollabNet Subversion)服务器 可视化界面
  5. 如何看linux是32位还是64位--转
  6. Linux网络编程——连接和面向连接的协议之间没有区别
  7. Silverlight实例教程 - Validation验证系列汇总
  8. 怎么能学好Java开发,学好Java一般需要多少钱
  9. [深度学习] 自然语言处理--- 基于Keras Bert使用(上)
  10. 【liferay】6、关于liferay中使用requestMapping映射地址提交表单
  11. 寒假作业3:抓老鼠啊
  12. 极客大佬用什么电脑_极客特惠:笔记本电脑,高清电视和免费应用
  13. 猎豹浏览器怎么设置允许弹出窗口 允许弹窗设置方法详解
  14. SaaS 中 6 种常见 UI 入职模式
  15. Spring之ApplicationContextAware接口详解
  16. 定义cisco设备的log级别
  17. docker如何搭建sftp服务器
  18. laypage ajax,laypage前端分页插件实现ajax异步分页
  19. vue elementui 表格数据 时间格式转换
  20. 用UltraISO制作Ubuntu_18.04U盘启动盘

热门文章

  1. saltstack之远程触发文件备份、回滚
  2. iPad随想:苹果的妙招、谷歌的尴尬和中移动MM的局限
  3. 二次开发基于无线网卡的扫描
  4. Jmeter使用之:高效组织接口自动化用例技巧
  5. 饮冰三年-人工智能-linux-07 硬盘分区、格式化及文件系统的管理
  6. 列表(list)、元组(tuple)、字典(dictionary)、array(数组)-numpy、DataFrame-pandas 、集合(set)...
  7. burpsuite配置指南
  8. 关于MySQL redo log,挖些坑,慢慢填
  9. 博客园里有多少人对企业信息化感兴趣
  10. 记录自己的技术点点滴滴