Web协议详解与抓包实战之HTTP1.1 学习笔记【一】

Web协议详解与抓包实战之HTTP1.1【一】

前言

《Web协议详解与抓包实战》课程学习,陶辉老师主讲

学习内容:

  1. HTTP–TLS/SSL–TCP/IP自上而下根据应用学习web协议HTTP1.1详细知识

  2. 结合抓包工具实践验证:chrome下的network面板、Tcpdump、Wireshark

HTTP协议

定义:一种无状态的、应用层的、以请求/应答方式运行的协议,它使用可扩展的语义自描述消息格式,与基于网络的超文本信息系统灵活的互动

a stateless application-level request/response protocol that uses extensible semantics and self-descriptive message payloads for flexible interaction with network-based hypertext information systems (RFC7230 2014.6)

ABNF规则

HTTP协议格式:ABNF(扩充巴科斯-瑙尔范式)核心规则,如果不严格遵守ABNF规则,日常工作中则会遇到很多错误~

  • 操作符

    image-20201113165225611

  • 核心规则

    image-20201113165253131

HTTP协议格式

image-20201113165450290

OSI概念模型

概念,就是没真正实现,但是必须参考

image-20201110111737150

TCP/IP模型

OSI实际上在互联网的实现就是TCP/IP模型

image-20201110112244295

好处:每一层隔离,只与相邻的层进行交互,其他不用管

缺点:数据处理影响性能

Web架构

本小节等学完等个课程之后在进行补充~

评估Web架构的关键属性

  • 性能 Performance
  • 可伸缩性 Scalability
  • 简单性 Simplicity
  • 可见性 Visiable
  • 可移植性 Portability
  • 可靠性 Reliability
  • 可修改性 Modifiability:对系统做出修改的难易程度

5种架构风格

  • 数据流风格 Data-flow Styles
    • 优点:简单性、可进化性、可扩展性
  • 复制风格 Replication Styles
  • 分层风格 Hierarchical Styles
  • 移动代码风格 Mobile Code Styles
  • 点对点风格 Peer-to-Peer Styles

使用Chrome的Network面板

URI格式

URI定义

image-20201113170518870

URI格式

  • 组成:scheme, user information, host, port, path, query, fragment

image-20201113170928916

  • URI的ABNF定义

    • 四部分组成:scheme, hier-part, query, fragment

      image-20201113171027008

      • 其中hier-part格式中的authority

        image-20201113171554442

      • 其中hier-part格式中的path

        image-20201113171800861

  • URI与相对URI

    image-20201113171953040

URI与URL的关系

image-20201113165909012

HTTP响应码

响应码规范 RFC6585(2012.4)、RFC7231(2014.6)

  • 1xx:请求已接收到,需要进一步处理才能完成,HTTP1.0不支持
  • 2xx:成功处理请求
  • 3xx:重定向使用Location指向的资源或者缓存中的资源。RFC规范中规定客户端重定向次数不应超过5次,以防止死循环
  • 4xx:客户端出现错误
  • 5xx:服务器端出现错误
  • 5xx:服务器端出现错误

后续课程学习中罗列表格进行详细分类!

传输HTTP包体

定长包体:

Content-Length头部明确指明包体长度

  • 用10进制表示包体中的字节个数,且必须与实际传输的包体长度一致

使用python socket建立server环境:

'''
Author: f4ke
Date: 2020-11-11 11:00:31
LastEditTime: 2020-11-11 11:32:40
LastEditors: Please set LastEditors
Description: python server_test content-length
FilePath: \python\http_test\testsvr.py
'''

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_address = ("127.0.0.1", 12345)

sock.bind(server_address)

sock.listen(100)

while True:
    conn,client_address = sock.accept()
    print(conn,client_address)
    try:
        data = conn.recv(4096)
        response = 'HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHelloWorld'
        conn.send(response.encode())
    finally:
        conn.close()

Content-Length小于实际传输包体长度HTTP协议会进行截断

Content-Length大于实际传输包体长度浏览器报错,wireshark抓包如下图

image-20201111114035410

PS: 一般情况下waf是基于Content-Length进行处理,当不使用Content-Length方式时可绕过waf直接访问服务器或数据库

非定长包体

  • 发送HTTP消息时不能确定包体的全部长度

    • 使用Transfer-Encoding头部指明使用Chunk传输方式
      • 含Transfer-Encoding头部后Content-Length头部将被忽略
  • 优点:

    • 基于长连接持续推送动态内容
    • 压缩体积较大的包体时,不必完全压缩完在发送,可边发送边压缩
    • 传递必须在包体传输完才能计算出的Trailer头部
  • chunk传输的格式

    image-20201113173138126

待更新:这里延伸出一种漏洞利用方式,分块传输绕过waf直接对数据库进行访问

HTML FORM表单

  • HTML并非变成语言,本身没有交互能力与HTTP协议无关
  • FORM表单:HTML中的元素,提供了交互控制元件用来向服务器通过HTTP协议提交信息
    • 常见控件:
      • Text Input Controls:文本输入文件
      • Checkboxes Controls:复选框控件
      • Radio Box Controls:单选按钮控件
      • Select Box Controls:下拉列表控件
      • File Select boxes:选取文件控件
      • Clickable Buttons:可点击的按钮控件
      • Submit直接发起HTTP请求) and Reset Buttons:提交或重置按钮控件
    • 三个核心属性
      • action:提交时发起HTTP请求的URI
      • method:提交时发起HTTP请求的http方法
        • GET
        • POST
      • enctype:在POST方法下,对表单内容在请求包体中的编码方式
        • application/x-www-form-urlencoded(默认)
          • 数据被编码成以’&‘分隔的键值对,同时以’='分隔键和值,字符以URL编码方式编码
        • multipart(一个包体中多个资源表述)/form-data
          • header
            • image-20201111154137187
          • multipart包体格式
            • image-20201111154042112

断点续传/多线程下载

HTTP Range规范:RFC7233

  • 允许服务器基于客户端的请求只发送响应包体的一部分给到客户端,而客户端自动将多个片段的包体组合成完整的体积更大的包体
    • 支持断点续传
    • 支持多线程下载
    • 支持视频播放器实时拖动
  • 服务器通过Accept-Range头部表示是否支持Range请求
    • Accept-Ranges = acceptable-ranges
      • Accept-Ranges: bytes(支持)
      • Accept-Ranges: none(不支持)

使用burp抓包进行实验:

image-20201111162329532

  • 如果客户端已经获得Range响应的一部分,想在这部分响应未过期的情况下,获取其他部分的响应
    • 常与if-Unmodified-Since或者If-Match头部共同使用

若与之前的ETag字段的值不同,则如下图,服务器返回412条件匹配失败

image-20201111162849730

  • 服务器响应

    • 206 Partial Content

      • Content-Range头部:显示当前片段包体在完整包体中的位置

      • 正好结合B站的视频,在network面板中查看响应包

        image-20201111163436430

    • 多重范围与multipart(与form表单中的多资源表述类似

      • 请求
        • Range: bytes=0-50,60-100
      • 响应
        • Content-Type: multipart/byteranges; boundary=…

      image-20201111164112357

Cookie与Session

RFC6265,HTTP的状态管理机制,保存在客户端,由浏览器维护、表示应用状态的HTTP头部

  • 存放在内存或磁盘中
  • 服务器端生成Cookie在响应中通过Set-Cookie头部告知客户端
  • 客户端得到Cookie后,后续请求会自动携带进请求头中

Cookie与Set-Cookie头部的格式

image-20201112141736336

image-20201112141801456

Cookie使用的限制

  • RFC规范对浏览器使用Cookie的要求
    • 每条Cookie的长度支持要达到4KB
    • 每个域名下至少支持50个Cookie
    • 至少要支持3000个Cookie

登录场景下的常见用法

  • cookie保存在客户端
  • session保存在服务端

image-20201112144003316

第三方Cookie

浏览器允许对于不安全域(非当前访问域)下的资源响应中的Set-Cookie字段进行保存,并在后续访问该域时自动使用Cookie

因为这个浏览器机制常见场景:偷取用户的浏览信息,例如在社交平台发布的内容涉及物品很容易在电商平台上被推荐

由此,为了避免这个问题,浏览器有了同源策略,在其基础上又因为正常服务的访问需求产生了跨域访问

同源策略

限制了从同一个源加载的文档或脚本与来自另一个源的资源进行交互

  • 协议、主机、端口必须完全相同

同源策略在可用性和安全性寻找平衡点

  • 可用性:HTML的创作者决定跨域请求是否对本站点安全

    • <script><img><iframe><link><video><audio>
      // 带有src属性浏览器允许进行跨域访问
      
    • 浏览器允许跨域写操作:表单提交或者重定向请求

      • CSRF攻击
        • 防护方式:浏览器的referrer字段或者下图CSRF token

      image-20201112153521941

  • 安全性:浏览器需要防止站点A的脚本向站点B发起危险动作

    • Cookie、LocalStorage和IndexDB无法读取
    • DOM无法获得
    • AJAX请求不能发送

通过CORS跨域访问

实现跨域访问有很多解决方案,RFC规范或HTTP架构中推荐CORS方案

CORS:Cross-Origin Resource Sharing

  • 浏览器同源策略下的跨域访问解决方案

    • 如果站点A允许站点B的脚本访问其资源,必须在HTTP响应中显式的告知浏览器:站点B是被允许的

    • 两类HTTP请求

      image-20201112155706675

简单请求的跨域访问

  • 请求中携带Origin头部告知来自哪个域
  • 响应中携带Access-Control-Allow-Origin头部表示允许 哪些域
  • 浏览器放行并进行渲染展示,(不在Access-Control-Allow-Origin头部中的域名浏览器拦截

image-20201112155613102

预检请求

先进行预检请求,在进行实际的请求

image-20201112174303690

跨域资源访问:请求头部

image-20201112174444208

跨域资源访问:响应头部

image-20201112174428506

Precondition条件请求

目的:

  • 客户端携带条件判断信息,而服务器预执行条件验证过程成功后,在返回资源的表述

常见应用场景

  • 缓存的更新更有效率
  • 断点续传时对之前内容的验证
  • 多个客户端并行修改同一资源时,防止某一客户端的更新被错误丢弃

验证器 validator

根据客户端请求中携带的相关头部,以及服务器资源的信息,执行两端的资源验证

  • 强验证器:服务器上的资源表述只要有变动,以旧的验证头部访问一定会导致验证不过
  • 弱验证器:服务器上资源变动时,允许一定程度上仍然可以验证通过

验证器响应头部

  • Etag响应头部:用来帮助服务器控制Web端的缓存验证

    • image-20201113094709284
  • Last-Modified响应头部

    • image-20201113094744533

条件请求头部

  • If-None-Match
    • 对于GETHEAD 请求方法来说,当且仅当服务器上没有任何资源的 ETag 属性值与这个首部中列出的相匹配的时候,服务器端会才返回所请求的资源,响应码为 200 。对于其他方法来说,当且仅当最终确认没有已存在的资源的 ETag 属性值与这个首部中所列出的相匹配的时候,才会对请求进行相应的处理。
    • 个人理解就是服务器没有对应的值相匹配时验证成功(成功的响应码即为200),否则响应304

image-20201113095839309

验证请求与响应

image-20201113164526429

Nginx处理条件请求的规则

image-20201113102808409

缓存

HTTP缓存:为当前请求复用前请求的响应

  • 目标:减少时延,降低带宽消耗
  • 可选但却必要

分类

私有缓存:仅供一个用户使用的缓存,通常只存在如浏览器这样的客户端上

共享缓存:可以供多个用户使用的缓存,存在于网络中负责转发消息的代理服务器

  • Authentication响应不可被代理服务器缓存
  • 正向代理
  • 反向代理

浏览器中抓包查看响应包头中是否有age字段,来区分响应资源来自缓存还是源服务器

代理服务器原理

image-20201113113157725

缓存原理图

image-20201113112316635

计算缓存过期的四种方式

判断缓存是否过期

image-20201113114923043

常见的预估过期时间:RFC7234 (DownloadTime - LastModified)* 10%

  • Age头部及current_age的计算

image-20201113141514576

  • 代理服务器缓存中的age头部

image-20201113141854734

Cache-Control头部

  • Cache-Control头部格式

image-20201113143957899

  • Cache-Control头部在请求中的值

    image-20201113143605568

  • Cache-Control头部在响应中的值

    image-20201113144049233

    image-20201113144107652

重定向

为什么需要URI重定向

  • 提交FORM表单成功后需要显示的页面
  • 站点从HTTP迁移到HTTPS
  • 站点部分URI发生了变化,搜索引擎或流量入口站点只收录老URI
  • 站点维护中,需要给用户展示不一样的内容
  • 站点更换了新域名
  • ,…

重定向流程

  • 当浏览器接收到重定向响应码时,需要读取响应头部Location的值,获取到新的URI再跳转访问该页面

重定向响应返回码

  • 概念
    • 原请求:接收到重定向响应码的请求
    • 重定向请求:浏览器接收到重定向响应码发起的新请求
重定向响应返回码分类 使用GET方法 必须使用原请求的方法和包体
永久重定向(会缓存) 301 308
临时重定向(不缓存) 302,303 307
  • 特殊重定向
    • 300:告知客户端有多种资源表述,要求客户端选择
    • 304:服务器端验证过期缓存有效,要求客户端使用该缓存

重定向循环:浏览器会报错ERR_TOO_MANY_REDIRECTS

HTTP Tunnel隧道

  • 用于通过HTTP连接传输非HTTP协议格式的消息,常用于穿越防火墙
    • 隧道建立后,不需要遵循HTTP格式,变为双向传输
  • 第一步就是CONNECT方法,例如 CONNECT www.example.com:80 HTTP/1.1
  • 看到CONNECT方法就知道后续流量都基于隧道传输

HTTP基本认证

  • RFC7235,一种基本的验证框架,被绝大部分浏览器所支持
  • 明文传输,若不使用TLS/SSL传输则有安全问题

image-20201116144137252

  • 认证请求

    • 在请求中传递认证信息: Authorization = credentials
    • 代理服务器认证: Proxy-Authorization = credentials
  • 认证响应

    image-20201116145504989

猜你喜欢

转载自blog.csdn.net/weixin_39664643/article/details/109679416