• 初步学习http请求走私


    前言

    最先开始接触到http请求走私是在今年的iscc线上赛的一道题目,当时因为没有题目环境等种种原因没有复现这道题目,所以这次通过这篇文章了解什么是http请求走私攻击。

    漏洞成因

    先解释一下什么是长连接以及content-length和transfer-encoding这三个名词。

    什么是长连接

    学过计算机网络原理都知道,http是无状态的,什么是无状态,http请求是建立在tcp连接之上的,每一个http请求发出响应后就会断开tcp连接,而在下一个http请求发出前又重新三次握手建立连接。这么做很明显很明显导致了http请求效率低下,所以发明者们就引入了长连接的概念。在http请求头部添加Connection: keep-alive这个字段,在客户端或者服务器使用这个字段后,在以后对相同服务器发出的请求后,会重用上次的tcp连接,不需要再次握手,这么做大大节约了服务器资源,这个特性在http1.1默认开启。

    CL(Content-Length)

    在建立长连接的基础上,服务器并不清楚一个http请求是否已经发送完毕,所以就引入了Content-Length字段,这个内容就表示了请求体的长度,就比如一个简单的http请求。

    1. POST / HTTP/1.1
    2. Host: example.com
    3. Content-Type: application/x-www-form-urlencoded
    4. Content-Length:8
    5. a\r\n
    6. abc\r\n
    7. b

    这个Content-Length设置为8,这里的\r\n是一个换行,代表两个字节,在这个http请求发出后,经过服务器处理,在服务器识别了CL后,它会认为abc以上的内容是一个完整的http请求,而这个b就是非法的,就被滞留到缓存区内。

    TE(transfer-encoding)

    Transfer-Encoding是指定用于传输请求主体的编码方式。我们不需要具体知道它是什么,当我们的TE设置为chunk的时候,就会把0当作终止块结束本次的http请求。看一个http请求。

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

    我的burpsuite官方靶场抓不了包,我也没有深究是什么问题。用靶场例子说一下,在后端服务器接收到请求时,它会优先处理TE,也就是0以上的部分是一个正常的http请求,也就把G丢在了缓存区。

    漏洞原理

    在如今的web架构中,客户端-服务端这种一对一的模式已经很少见了,服务端被分为了前端服务器和后端服务器。前端服务器主要做的事情就是限制一些错误的以及非法访问的http请求,而后端服务器就没必要做安全检测,直接处理http请求。那么,如果前后端服务器判断请求包边界的规则不一致的话,攻击者可能会精心构造一个数据包来绕过前端的服务器而去访问禁止访问的服务或者端口。

    还是看上一个的例子,当CL和TE字段同时存在,前端服务器优先处理CL字段。

    1. 0\r\n
    2. \r\n
    3. G

    加上换行正好是六个字节,也就是说在前端服务器看来,这就是一个正常的http请求。而后端服务器处理时,它会忽略掉CL,优先处理TE字段,那么0就是http请求的结束标志,这个G丢在缓存区,待下一次请求来临,就拼接上去。

    1. GPOST / HTTP/1.1
    2. Host: your-lab-id.web-security-academy.net
    3. Connection: keep-alive
    4. Content-Type: application/x-www-form-urlencoded
    5. Content-Length: 0

    这就导致了请求方式成了GPOST了。这就是前后端处理数据包边界不一致所带来的问题。也就是http请求走私漏洞。

    当然,前端服务器还可能优先级处理TE,而后端服务器优先级处理CL,要根据前后端服务器处理字段的优先级构造恶意数据包。

    CTF实战

    [RoarCTF 2019]Easy Calc

    我们直接查看源码。

    1. error_reporting(0);
    2. if(!isset($_GET['num'])){
    3. show_source(__FILE__);
    4. }else{
    5. $str = $_GET['num'];
    6. $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
    7. foreach ($blacklist as $blackitem) {
    8. if (preg_match('/' . $blackitem . '/m', $str)) {
    9. die("what are you want to do?");
    10. }
    11. }
    12. eval('echo '.$str.';');
    13. }
    14. ?>

    这里直接上payload,

    1. calc.php? num=1;
    2. var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

    当然,这里前端服务器存在waf,而预期解是在num变量前加上空格,从而使服务器无法解析绕过waf。然而我们还可以利用http请求走私来直接绕过前端服务器。

    我们在数据包中添加两个CL字段,返回400的同时还把flag给带出来了。

    这是为什么呢? 如果服务器不严格按照规范,当数据包中存在两个CL,那么前端服务器就会按照第一个CL字段处理,而后端服务器就会按照第二个CL处理,虽然会返回400,但是请求也交给了后端服务器处理,所以也就将flag的值一并返回给了客户端。

    而这种CL-TE的走私类型也是可以得出flag的。

     结语

    通过此篇文章只是基础的认识到什么是http请求走私,而在今后会通过相关ctf题目更加深入理解http请求走私的攻击方式以及思路。

    相关文章:协议层安全相关《http请求走私与CTF利用》_合天网安实验室的博客-CSDN博客

  • 相关阅读:
    生命 周期
    operator简介
    内存泄漏定位工具之 valgrind 使用
    springboot心理咨询管理系统
    Papers about Anomaly Detection (Reconstruction-based and Restoration-based)
    毕业设计怎么做--看这里
    数据可视化【原创】vue+arcgis+threejs 实现流光边界线效果
    《Principles of Model Checking》 Chapter 3 Linear time properties (线性时间特性)
    上采样方式(反卷积、插值、反池化)
    python 压缩与解压文件
  • 原文地址:https://blog.csdn.net/m0_62422842/article/details/126663722