当前位置 博文首页 > 一个很酷的人:HTTP协议详解

    一个很酷的人:HTTP协议详解

    作者:[db:作者] 时间:2021-08-08 16:14

    Web安全基础是渗透测试工程师需要掌握的主题知识内容之一,通过本部分的学习,应当掌握:

    l? 了解HTTP协议的基础知识,掌握HTTP协议在实际工作中的使用

    l? 掌握注入漏洞相关知识以及相关的漏洞修复方法

    l? 掌握XSS漏洞的多种形式和防御方法

    l? 掌握请求伪造漏洞的危害和相应的检测方法

    l? 掌握文件处理漏洞的分类和代码审计方法l 掌握访问控制漏洞的分类和漏洞防御方法

    l? 掌握会话管理漏洞的特性和防护方法?

    1 HTTP协议

    知识体:WEB安全基础

    ?

    ? ? HTTP协议,即超文本传输协议(Hypertexttransfer protocol)。?是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议 。

    ?

    1.1 HTTP请求方法

    HTTP1.0的请求方法

    (1)HTTP1.0三种请求方法

    HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

    GET:请求指定的页面信息,并返回实体主体。

    POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。

    HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。

    (2)GET请求的标准格式

    ? ? GET是最常用的方法,它的作用是获取服务器中的某个资源.下图显示了一个例子,在这个例子中,客户端用GET方法发起了一次HTTP请求,然后服务端将对应的资源返回给客户端.

    GET Request-URI HTTP/1.1

    上图中客户端请求的资源是www.devtf.cn/articles路径下的123.html,服务端将123.html返回给客户端.需要注意的是,GET请求的参数都需要放到请求的URL中,第一个参数之前有一个”?”,参数的格式为: 参数名=参数值,参数之间通过”&”连接. 例如,我们在请求 www.devtf.cn/articles/123.html 时希望传递用户名和用户id两个参数,那么格式应该是这样的: www.devtf.cn/articles/123.html?username=myname&userid=123 .


    (3)POST请求提交表单,上传文件的方法?

    ? ? 服务端通常是根据请求头(headers)中的?Content-Type?字段来获知请求中的消息主体是用何种方式*编码*,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。

    ?

    application/x-www-form-urlencoded

    ?

    ? ? 最基本的form表单结构,用于传递字符参数的键值对,请求结构如下

    1

    POST? HTTP/1.1Host: www.demo.comCache-Control: no-cachePostman-Token: 81d7b315-d4be-8ee8-1237-04f3976de032Content-Type: application/x-www-form-urlencodedkey=value&testKey=testValue

    ? ? 请求头中的Content-Type设置为application/x-www-form-urlencoded; 提交的的数据,请求body中按照 key1=value1&key2=value2 进行编码,key和value都要进行?urlEncode;

    ?

    multipart/form-data

    ?

    ? ? 这是上传文件时,最常见的数据提交方式,看一下请求结构

    1

    2

    3

    4

    POST? HTTP/1.1Host: www.demo.comCache-Control: no-cachePostman-Token: 679d816d-8757-14fd-57f2-fbc2518dddd9Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW------WebKitFormBoundary7MA4YWxkTrZu0gW

    Content-Disposition: form-data; name="key"value------WebKitFormBoundary7MA4YWxkTrZu0gW

    Content-Disposition: form-data; name="testKey"testValue------WebKitFormBoundary7MA4YWxkTrZu0gW

    Content-Disposition: form-data; name="imgFile"; filename="no-file"Content-Type: application/octet-stream<data in here>------WebKitFormBoundary7MA4YWxkTrZu0gW--

    首先请求头中的Content-Type?是multipart/form-data; 并且会随机生成一个boundary, 用于区分请求body中的各个数据; 每个数据以 –boundary 开始, 紧接着换行,下面是内容描述信息, 接着换2行, 接着是数据; 然后以 –boundary– 结尾, 最后换行;

    文本数据和文件,图片的内容描述是不相同的?
    文本参数:

    1

    Content-Disposition: form-data; name="key"Content-Type: text/plain; charset=UTF-8Content-Transfer-Encoding: 8bit

    文件参数:

    1

    Content-Disposition: form-data; name="imgFile"; filename="no-file"Content-Type: application/octet-streamContent-Transfer-Encoding: binary

    ?


    (4)HEAD请求与GET请求的区别

    HEAD方法与GET方法的行为很类似,但服务器在响应中只返回首部. 不会返回实体的主体部分. 这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查. 使用HEAD可以在不获取资源的情况下了解资源的情况(比如,判断其类型); 通过查看响应中的状态码,看看某个对象是否存在; 通过查看首部,测试资源是否被修改了. 服务器开发者必须确保返回的首部与GET请求所返回的首部完全相同. 遵循HTTP/1.1规范,就必须实现HEAD方法. 如下图所示.


    HTTP1.1新增的请求方法

    (1)HTTP1.1新增了五种请求方法

    OPTIONS, PUT, DELETE,TRACE 和 CONNECT 方法的基本概念?

    OPTIONS:允许客户端查看服务器的性能。

    PUT: 从客户端向服务器传送的数据取代指定的文档的内容。

    DELETE:请求服务器删除指定的页面。

    TRACE:回显服务器收到的请求,主要用于测试或诊断。

    CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    (2)HTTP1.1新增的五种请求的基本方法和产生的请求结果?

    ?

    PUT请求:与GET从服务器读取资源相反,PUT方法会向服务器写入资源. 有些发布系统允许用户创建Web页面,并用PUT直接向其传输到Web服务器中,如下图所示

    PUT方法的语义就是让服务器用请求的主体部分来创建一个由所请求的URL命名的新文档,如果那个URL已经存在的话,就用这个资源来替代它. 例如, 在上图的请求中会在www.devtf.cn的网站根目录下创建一个new-art.txt的文件,文件内容为”This is file content”。

    DELETE请求:顾名思义,DELETE方法所做的事情就是请服务器删除请求URL所指定的资源. 但是,客户端应用程序无法保证删除操作一定会被执行. 因为,HTTP规范允许服务器在不通知客户端的情况下撤销请求. 下图显示了一个DELETE方法实例

    DELETE方式与GET请求一样,参数都需要放在请求的URL中。

    ?

    TRACE请求:客户端发起一个请求时,这个请求可能要穿过防火墙,代理,网关或其他一些应用程序. 每个中间节点都可能会修改原始的HTTP请求. TRACE方法允许客户端在最终将请求发送给服务器时,看看他变成了什么样子.?
    TRACE请求会在目的服务器端发起一个”环回”诊断. 行程最后一站的服务器会弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文. 这样客户端就可以查看在所有中间HTTP应用程序组成的请求/响应链上,原始报文是否以及如何被毁坏或修改过,如下图所示

    ? ? TRACE方法主要用于诊断,也就是说,用于验证请求是否如愿穿过了请求/响应链. 它也是一种很好的工具,可以用来查看代理和其他应用程序对用户请求所产生效果。

    ?

    OPTIONS请求:OPTIONS方法请求Web服务器告知其支持的各种功能. 可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法(有些服务器可能只支持对一些特殊类型的对象使用特定的操作). 这对客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各种资源的最优方式. 下图显示了一个使用OPTIONS方法的请求,如下图

    1.2 HTTP的状态码

    HTTP状态码的分类

    (1)HTTP状态码的规范

    ? ? HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。

    (2)HTTP状态码的作用

    ? ? http状态码的核心作用是Web Server服务器用来告诉客户端,当前的网页请求发生了什么事,或者说当前Web服务器的响应状态。所以HTTP状态码常用来判断和分析当前Web服务器的运行状况。
    (3)常见的HTTP状态码

    200 OK 服务器成功处理了请求(这个是我们见到最多的);
    301/302 Moved Permanently(重定向)请求的URL已移走。Response中应该包含一个Location URL, 说明资源现在所处的位置;
    404 Not Found(页面丢失)未找到资源;

    501 Internal Server Error服务器遇到一个错误,使其无法对请求提供服务。

    ?

    HTTP状态码的含义

    (1)HTTP状态码2**,3**,4**,5** 代表的含义

    1开头:(被接受,需要继续处理。)
    这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。

    2开头 (请求成功)
    这一类型的状态码,代表请求已成功被服务器接收、理解、并接受

    3开头 (请求被重定向)
    这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明。

    4开头:(请求错误)
    这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个 HEAD 请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。

    5开头:(服务器错误)
    这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD 请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。

    (2)获取HTTP状态码的方法

    1.浏览器的F12调试(或者右键检查),network查看Status,如下图所示,status就是http返回的状态码;

    2.各种在线输入网址查询HTTP状态的工具;

    3.计算机语言,如python、java等。

    1.3 HTTP协议响应头信息

    HTTP响应头的含义

    HTTP消息头是在,客户端请求(Request)或服务器响应(Response)时传递的,位请求或响应的第一行,HTTP消息体(请求或响应的内容)是其后传输。HTTP消息头,以明文的字符串格式传送,是以冒号分隔的键/值对,如:Accept-Charset: utf-8,每一个消息头最后以回车符(CR)和换行符(LF)结尾。HTTP消息头结束后,会用一个空白的字段来标识,这样就会出现两个连续的CR-LF。

    (1)常见的HTTP响应头

    响应头说明示例状态
    Access-Control-Allow-Origin指定哪些网站可以跨域源资源共享Access-Control-Allow-Origin: *临时
    Accept-Patch指定服务器所支持的文档补丁格式Accept-Patch: text/example;charset=utf-8固定
    Accept-Ranges服务器所支持的内容范围Accept-Ranges: bytes固定
    Age响应对象在代理缓存中存在的时间,以秒为单位Age: 12固定
    Allow对于特定资源的有效动作;Allow: GET, HEAD固定
    Cache-Control通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒Cache-Control: max-age=3600固定
    Connection针对该连接所预期的选项Connection: close固定
    Content-Disposition对已知MIME类型资源的描述,浏览器可以根据这个响应头决定是对返回资源的动作,如:将其下载或是打开。Content-Disposition: attachment; filename="fname.ext"固定
    Content-Encoding响应资源所使用的编码类型。Content-Encoding: gzip固定
    Content-Language响就内容所使用的语言Content-Language: zh-cn固定
    Content-Length响应消息体的长度,用8进制字节表示Content-Length: 348固定
    Content-Location所返回的数据的一个候选位置Content-Location: /index.htm固定
    Content-MD5响应内容的二进制 MD5 散列值,以 Base64 方式编码Content-MD5: IDK0iSsgSW50ZWd0DiJUi==已淘汰
    Content-Range如果是响应部分消息,表示属于完整消息的哪个部分Content-Range: bytes 21010-47021/47022固定
    Content-Type当前内容的MIME类型Content-Type: text/html; charset=utf-8固定
    Date此条消息被发送时的日期和时间(以RFC 7231中定义的"HTTP日期"格式来表示)Date: Tue, 15 Nov 1994 08:12:31 GMT固定
    ETag对于某个资源的某个特定版本的一个标识符,通常是一个 消息散列ETag: "737060cd8c284d8af7ad3082f209582d"固定
    Expires指定一个日期/时间,超过该时间则认为此回应已经过期Expires: Thu, 01 Dec 1994 16:00:00 GMT固定: 标准
    Last-Modified所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)Last-Modified: Dec, 26 Dec 2015 17:30:00 GMT固定
    Link用来表示与另一个资源之间的类型关系,此类型关系是在RFC 5988中定义Link:?; rel="alternate"固定
    Location用于在进行重定向,或在创建了某个新资源时使用。Location: http://www.itbilu.com/nodejs固定
    P3PP3P策略相关设置P3P: CP="This is not a P3P policy!固定
    Pragma与具体的实现相关,这些响应头可能在请求/回应链中的不同时候产生不同的效果Pragma: no-cache固定
    Proxy-Authenticate要求在访问代理时提供身份认证信息。Proxy-Authenticate: Basic固定
    Public-Key-Pins用于防止中间攻击,声明网站认证中传输层安全协议的证书散列值Public-Key-Pins: max-age=2592000; pin-sha256="……";固定
    Refresh用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。Refresh: 5; url=http://itbilu.com?
    Retry-After如果某个实体临时不可用,那么此协议头用于告知客户端稍后重试。其值可以是一个特定的时间段(以秒为单位)或一个超文本传输协议日期。
    • 示例1:Retry-After: 120
    • 示例2: Retry-After: Dec, 26 Dec 2015 17:30:00 GMT

    固定

    Server服务器的名称Server: nginx/1.6.3固定
    Set-Cookie设置HTTP cookieSet-Cookie: UserID=itbilu; Max-Age=3600; Version=1固定: 标准
    Status通用网关接口的响应头字段,用来说明当前HTTP连接的响应状态。Status: 200 OK?
    TrailerTrailer用户说明传输中分块编码的编码信息Trailer: Max-Forwards固定
    Transfer-Encoding用表示实体传输给用户的编码形式。包括:chunkedcompress、?deflategzipidentityTransfer-Encoding: chunked固定
    Upgrade要求客户端升级到另一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
    Vary告知下游的代理服务器,应当如何对以后的请求协议头进行匹配,以决定是否可使用已缓存的响应内容而不是重新从原服务器请求新的内容。Vary: *固定
    Via告知代理服务器的客户端,当前响应是通过什么途径发送的。Via: 1.0 fred, 1.1 itbilu.com (nginx/1.6.3)固定
    Warning一般性警告,告知在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定
    WWW-Authenticate表示在请求获取这个实体时应当使用的认证模式。WWW-Authenticate: Basic固定


    (2)HTTP响应头的作用

    相应的响应头用来描述服务器回给你对所返回的content的一些一些描述,服务器类型信息,编码类型,内容长度等等呢个。

    ?

    HTTP响应头的格式

    HTTP应答与HTTP请求相似,HTTP响应也由3个部分构成,分别是:

    1. 状态行
    2. 响应头(Response Header)
    3. 响应正文

    在接收和解释请求消息后,服务器会返回一个HTTP响应消息。?
    状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔。?
    格式:?HTTP-Version Status-Code Reason-Phrase CRLF?
    例如:?HTTP/1.1 200 OK \r\n

    状态代码:状态代码由3位数字组成,表示请求是否被理解或被满足。?
    状态描述:状态描述给出了关于状态代码的简短的文字描述。

    响应头可能包括:?

    Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源。当我们在JSP中使用重定向语句的时候,服务器端向客户端发回的响应报头中,就会有Location响应报头域。?
    Server:Server响应报头域包含了服务器用来处理请求的软件信息。它和User-Agent请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和操作系统的信息。下面是Server响应报头域的一个例子:Server: Apache-Coyote/1.1?
    WWW-Authenticate:WWW-Authenticate响应报头域必须被包含在401(未授权的)响应消息中,这个报头域和前面讲到的Authorization请求报头域是相关的,当客户端收到401响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了 Authorization报头域的请求,下面是WWW-Authenticate响应报头域的一个例子:WWW-Authenticate: Basic realm="Basic Auth Test!"?
    从这个响应报头域,可以知道服务器端对我们所请求的资源采用的是基本验证机制。?
    Content-Encoding:Content-Encoding实体报头域被使用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容编码,因而要获得Content- Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding主要用语记录文档的压缩方法,下面是它的一个例子: Content-Encoding: gzip。如果一个实体正文采用了编码方式存储,在使用之前就必须进行解码。?
    Content-Language:Content-Language实体报头域描述了资源所用的自然语言。Content-Language允许用户遵照自身的首选语言来识别和区分实体。如果这个实体内容仅仅打算提供给丹麦的阅读者,那么可以按照如下的方式设置这个实体报头域:Content-Language: da。?
    如果没有指定Content-Language报头域,那么实体内容将提供给所以语言的阅读者。?
    Content-Length: Content-Length实体报头域用于指明正文的长度,以字节方式存储的十进制数字来表示,也就是一个数字字符占一个字节,用其对应的ASCII码存储传输。?
    Content-Type?
    Content-Type实体报头域用语指明发送给接收者的实体正文的媒体类型。例如:

    Content-Type: text/html;charset=ISO-8859-1
    Content-Type: text/html;charset=GB2312
    • 1
    • 2

    Last-Modified:Last-Modified实体报头域用于指示资源最后的修改日期及时间。?
    Expires?
    Expires实体报头域给出响应过期的日期和时间。通常,代理服务器或浏览器会缓存一些页面。当用户再次访问这些页面时,直接从缓存中加载并显示给用户,这样缩短了响应的时间,减少服务器的负载。为了让代理服务器或浏览器在一段时间后更新页面,我们可以使用Expires实体报头域指定页面过期的时间。当用户又一次访问页面时,如果Expires报头域给出的日期和时间比Date普通报头域给出的日期和时间要早(或相同),那么代理服务器或浏览器就不会再使用缓存的页面而是从服务器上请求更新的页面。不过要注意,即使页面过期了,也并不意味着服务器上的原始资源在此时间之前或之后发生了改变。?
    Expires实体报头域使用的日期和时间必须是RFC 1123中的日期格式,例如:

    Expires: Thu, 15 Sep 2005 16:00:00 GMT
    • 1
    下一篇:没有了