HTTP协议(7)HTTP请求头
在HTTP请求报文中,请求头是我们需要重点了解的部分,下面是请求头中的主要内容:
(1) Host,指定被请求资源的URL。
(2) User-Agent,客户端操作系统和浏览器的版本信息。很多网站通过它来判断操作系统和浏览器类型,来展示对应的页面。也有很多通过UA来判断访问是否合法,是用户访问还是程序访问等。
Windows版本与内核的对应关系:
- Windows NT 4.0 = NT 4.0
- Windows 2000 = NT 5.0
- Windows XP = NT 5.1
- Windows Vista = NT 6.0
- Windows 7 = NT 6.1
- Windows 8 = NT 6.2
- Windows 8.1 = NT 6.3
- Windows 10 = NT 10.0
(3) Accept,用于指定客户端可以接收哪些MIME类型的信息,比如Accept:text/html,表示客户端希望接收HTML文本。而如果是Accept:text/plain,则表示客户端只能接收纯文本,服务器不能向它发送图片、视频等。(MIME类型用来设定某种扩展名文件的打开方式,当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开,如jpg图片的MIME为image/jpeg。)
(4) Accept-Language,指定客户端可以接收的语言,如果请求消息中没有设置这个域,默认是任何语言都可以接收。
(5) Referer,Referer包含一个URL,代表当前访问URL的上一个URL,也就是说,用户是从什么地方来到本页面。假如你通过百度搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer属性值就是http://×××w.baidu.com 。如果Referer值就是所访问页面的URL,则表示我们是直接访问的该页面,而不是从别处跳转过来。Referer也被广泛用在防盗链中。
(6) Cookie,客户端发给服务器证明用户状态的信息,用来表示请求者的身份。
(7) Cache-Control,对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一段时间,或不希望被缓存,就可以通过这个报文头达到目的。比如Cache-Control: max-age=3600,就表示让客户端对响应内容缓存3600秒,也即在3600秒内,如果客户再次访问该资源,直接从客户端的缓存中返回内容给客户,不要再从服务端获取。而Cache-Control: no-cache,则表明对返回的响应内容不要在客户端缓存。
有些项目在请求头中不一定会出现,但是对于***又比较重要,下面也介绍一下:
(8) x-forwarded-for,即XFF头,它代表客户端的IP,可以有多个,中间以逗号隔开。
例题:貌似有点难
实验吧 http://ctf5.shiyanbar.com/phpaudit/
打开链接之后,提示"错误!你的IP不在允许列表之内!",并且给出了网站源码。
我们首先来分析一下这段代码。
$_SERVER是一个全局变量,与$_GET、$_POST一样,可用于获取客户端的信息。在这段代码中,使用了三种不同的获取客户端IP的方法,
$_SERVER["REMOTE_ADDR"]获取的是客户端与服务器三次握手建立TCP连接时的IP,这个无法伪造。
$_SERVER['HTTP_CLIENT_IP']和$_SERVER["HTTP_X_FORWARDED_FOR]都是通过HTTP头来获取信息,因而都是可以伪造的。它们分别获取的是HTTP请求头"CLIENT-IP"和"X-FORWARDED-FOR"域的信息,不过"CLIENT-IP"不属于标准的头信息,而"X-FORWARDED-FOR"则是,因而修改该属性更为可取。.
比如我们自己编写下面一个脚本文件:
默认情况下只能获取到$_SERVER["REMOTE_ADDR"],这是因为HTTP请求头中默认并没有那两个值。
我们利用Burpsuite截获报文,然后在其中增加两个头部信息,并发送出去,这时服务器可以通过三种方法来获取到客户端的IP。
搞清楚这些问题之后,这道题目的解法就很简单了,只要将"CLIENT-IP"或是"X-FORWARDED-FOR"修改为1.1.1.1即可。
最后还是需要说明一下,既然$_SERVER["REMOTE_ADDR"]获取的是客户端的真实IP,而且用户无法伪造,那么服务器为什么不用这种方法来获取客户端IP呢?这是因为在局域网环境下,客户端与服务器之间直接通信,通过三次握手建立连接,此时获取的IP自然没问题。但是互联网的网络环境就复杂得多了,在服务器的前面一般会有防火墙,在客户端也可以设置代理服务器,也就是说与服务器三次握手的往往并非是客户端,而是这些中间设备,这都会导致利用$_SERVER["REMOTE_ADDR"]获取的IP不准确。而利用$_SERVER['HTTP_CLIENT_IP']和$_SERVER["HTTP_X_FORWARDED_FOR]获取的IP直接来自客户端发来的消息头,不受中间设备的干扰,因而更为准确,只是这也为***留下了利用的空间。