在 t00ls.net 看到个帖子,内容如下(已删除无用回复):

楼主:原来php的$_SERVER['SERVER_NAME']是可以伪造的:

插,一直以为这个$_SERVER['SERVER_NAME']变量是不能伪造的,事实上它居然可以伪造。。。换句话说这个变量可控!!纠结

路人甲:

怎么伪造啊? 域名也能伪造?

楼主:

是滴,经过测试,可以控制

路人乙:

[图片]

.........
http    header   Host
对不?

路人丙:

那可不可以欺骗 BBS程序后台, 伪装成被允许的 Ip 登录后台?

路人丁:

但是好像只有对默认的host有效
virtual host就找不到文件了

路人戊:

对头,如果配了虚拟主机,那么hostname将会是一个寻址依据,那么就不可以伪造了

本人:

对你们无语了,你们也搞搞清楚,那个根本不叫伪造!!!那个就是可控变量!!!

浏览器 --> IP 发送的 Http 协议数据包如下:

GET / HTTP/1.1
Accept: */*
Host: www.baidu.com
User-Agent: Mozilla/5.0
Connection: Close

你所说的伪造,指的是 HTTP 头中的 Host 值。

我靠,搞搞清楚啊,孩子们,这个本来就是用户指定的!

所有脚本程序统统使用的这个变量,例如 Asp 为:Request.ServerVariables("HTTP_HOST")

因为一台服务器上有很多网站,HTTP协议就有了这个东西,IIS设置里叫主机头,也就是我们所说的域名。

Web 服务器依靠这个值,寻找服务器上的网站,进行匹配,如果没有找到,就返回默认网站(返回内容可以任意指定),也就是IIS中那个建设中……

所以针对这种“伪造”,只有可以直接访问IP浏览的网站(没有设置主机头,或者为任意值,或者干脆用的默认网站),才可以“伪造”。

如果必须需要域名才可以访问,那就无法伪造,为什么???靠,还不明白啊,孩子们……

因为,你所需要的域名就是 Host 值啊,你把这个都改了,根本无法浏览网站了,更别提所谓的“伪造”了。

前后矛盾的东西,这个有点绕口,没有一点HTTP协议知识的同学可能难以理解。

以后多学学啊,孩子们。。。。。。。

说得简单点,这个“伪造”就如同在讨论“GET /fuck.php”的这个 fuck.php 可以“伪造”一样……

PS:我想你发现的条件是,你本地搭建的调试环境,没有设置主机名,直接访问IP,调试了你需要的脚本,才“无意间发现”的。

    我想看完这个,你应该懂了……

2011-11-15 4:23:05 补充:

我发现依然有很多同学无法理解这些内容,或者理解的内容是错误的,这是由于完全不了解HTTP协议导致的,通俗的说就是:你知道得太少了……,囧,我这里用通俗的语言简单的解释一下。

这个非要域名才能访问,不是指的是解析环节。。

而是解析完毕后,用户浏览器向解析的IP发送的http数据包中,必须的一个值:host (主机头,也就是域名)。

当数据包发到该服务器后,该服务器会读取该值,如果没有匹配到服务器上的网站,也就是可以简单的理解为值是错的。

然后服务器就会返回一系列默认的页面,例如 IIS 的建设中……,用户自然无法访问目标网站了。

如果该值正确,也就是匹配到了服务器上的网站,服务器就会返回指定网站的数据,用户的浏览器进行一系列显示操作,从而完成HTTP会话。

再简单一点:

0、解析操作(这个都一样的,就不解释了):

用户对浏览器发出指令:我要浏览网站:[url]https://lcx.cc/[/url]。

用户浏览器询问DNS服务器,这个域名对应的IP是多少啊?

DNS服务器,对应的IP是:8.8.8.8。

用户浏览器:我知道了!我去找这个服务器。

1、正常浏览:

用户浏览器对服务器说:我要访问这个网站:lcx.cc (Http 头中的 host 值,也就是主机名、域名)。

服务器在他的资料中查找这个网站,恩,找到了,对用户浏览器说,我找到了!(http 状态:200 ok),这个网站数据是这样的,我发了,你接好!

用户浏览器回答:我收到了!,同时处理数据进行显示等操作。

2、“伪造”域名:

用户浏览器对服务器说:我要访问这个网站:This is sibada! (Http 头中的 host 值,只不过这里是“伪造”的值)。

服务器在他的资料中找这个网站,没找到,服务器对浏览器说:访问你妹啊,老子这没有这个站!(http 状态:400 bad request),老子给你默认数据(例如 IIS 的: 建设中……,这个值可以自己随便定义),你接好了。

用户浏览器:囧~~~,同时进行一系列显示操作。

3、当服务器不判断HOST头时,也就是输入IP可以直接访问的站:

用户浏览器对服务器说:我要访问这个网站:lcx.cc 或 this is sibada!(正常或者“伪造”的)。

服务器心想:老子的主人说了,不管谁来都给一样的值。然后对用户浏览器说:我找到了!(http 状态:200 ok),这个网站数据是这样的,我发了,你接好!

用户浏览器回答:我收到了!,同时处理数据进行显示等操作。

HTTP 协议就是这样……,这次应该懂了吧。。。。