跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

CVE-2021-23017:nginx DNS解析漏洞PoC公开

精选回复

发布于

CVE-2021-23017:nginx DNS解析漏洞PoC公开

604185ad9f877.png

缝隙评级

高危缝隙

确认受影响版别

0.6.18 - 1.20.0

确认修复版别

1.21.0、1.20.1

厂商

F5, Inc

厂商官网

https://nginx.org/

厂商参考资料

https://mailman.nginx.org/pipermail/nginx-announce/2021/000300.html

缝隙CVE

CVE-2021-23017

CWE

193

CVSS评分

8.1

缝隙概述及影响

在处理DNS呼应时,ngx_resolver_copy()中的一个off-by-one错误将答应网络进犯者在堆分配的缓冲区中写入超出鸿沟的点字符(‘.’, 0x2E)。配置解析程序原语时,呼应nginx服务器DNS恳求的DNS呼应可能会触发该缝隙。

精心结构的数据包能够经过使用0x2E掩盖下一个堆块元数据的最低有效字节,此时,能够向nginx服务器提供DNS呼应的网络进犯者能够实现拒绝服务进犯或长途代码执行进犯。

因为nginx中短少DNS诈骗防御措施,并且在检查DNS业务ID之前调用了易受进犯的函数,因而长途进犯者能够经过在可行的时刻内向方针服务器发送歹意DNS呼应来使用该缝隙施行进犯。

缝隙成因分析

nginx的DNS解析器(core/ngx_resolver.c)能够在设置解析器原语时,经过DNS解析多个模块的主机名。

ngx_resolver_copy()会被调用以验证和解紧缩DNS呼应中包括的每个DNS域名,接纳作为输入的网络包和指向正在处理的域名的指针,并在成功时返回指向包括未紧缩域名的新分配缓冲区的指针。整个过程分为两步执行:

核算未紧缩域名的巨细len并验证输入数据包,丢掉包括128个以上指针或超出输入缓冲区鸿沟指针的域名。

分配一个输出缓冲区,并将未紧缩的域名复制到其中。

第1部分中的巨细核算和第2部分中的域名解压之间的不匹配会导致len中的off-by-one错误,从而答应在name->data数据鸿沟之外写入一个点字符。

当紧缩域名的最终一部分包括指向NULL字节的指针时,就会产生核算错误的状况。尽管核算过程只考虑标签之间的点,但每次处理标签并且下一个字符不是NULL时,解紧缩过程都会写入一个点字符。当标签后跟指向NULL字节的指针时,解紧缩过程将如下:

// 1) copy the label to the output buffer,

 ngx_strlow(dst, src, n);

            dst += n;

            src += n;

 

// 2) read next character,

            n = *src++;

 

// 3) as its a pointer, its not NUL,

            if (n != 0) {

// 4) so a dot character that was not accounted for is written out of bounds

                *dst++ = '.';

            }

 

// 5) Afterwards, the pointer is followed,

        if (n & 0xc0) {

            n = ((n & 0x3f) << 8) + *src;

            src = &buf[n];

 

            n = *src++;

 

        }

 

// 6) and a NULL byte is found, signaling the end of the function

        if (n == 0) {

            name->len = dst - name->data;

            return NGX_OK;

        }

如果核算出的巨细正好与堆块巨细对齐,则写入的点字符超出鸿沟,将掩盖下一个堆块巨细元数据的最低有效字节。这可能会修正下一个堆块的巨细,但也会掩盖3个标志,从而清除PREV_INUSE并设置IS_MMAPPED。

==7863== Invalid write of size 1

==7863==    at 0x137C2E: ngx_resolver_copy (ngx_resolver.c:4018)

==7863==    by 0x13D12B: ngx_resolver_process_a (ngx_resolver.c:2470)

==7863==    by 0x13D12B: ngx_resolver_process_response (ngx_resolver.c:1844)

==7863==    by 0x13D46A: ngx_resolver_udp_read (ngx_resolver.c:1574)

==7863==    by 0x14AB19: ngx_epoll_process_events (ngx_epoll_module.c:901)

==7863==    by 0x1414D4: ngx_process_events_and_timers (ngx_event.c:247)

==7863==    by 0x148E57: ngx_worker_process_cycle (ngx_process_cycle.c:719)

==7863==    by 0x1474DA: ngx_spawn_process (ngx_process.c:199)

==7863==    by 0x1480A8: ngx_start_worker_processes (ngx_process_cycle.c:344)

==7863==    by 0x14952D: ngx_master_process_cycle (ngx_process_cycle.c:130)

==7863==    by 0x12237F: main (nginx.c:383)

==7863==  Address 0x4bbcfb8 is 0 bytes after a block of size 24 alloc'd

==7863==    at 0x483E77F: malloc (vg_replace_malloc.c:307)

==7863==    by 0x1448C*4: ngx_alloc (ngx_alloc.c:22)

==7863==    by 0x137AE4: ngx_resolver_alloc (ngx_resolver.c:4119)

==7863==    by 0x137B26: ngx_resolver_copy (ngx_resolver.c:3994)

==7863==    by 0x13D12B: ngx_resolver_process_a (ngx_resolver.c:2470)

==7863==    by 0x13D12B: ngx_resolver_process_response (ngx_resolver.c:1844)

==7863==    by 0x13D46A: ngx_resolver_udp_read (ngx_resolver.c:1574)

==7863==    by 0x14AB19: ngx_epoll_process_events (ngx_epoll_module.c:901)

==7863==    by 0x1414D4: ngx_process_events_and_timers (ngx_event.c:247)

==7863==    by 0x148E57: ngx_worker_process_cycle (ngx_process_cycle.c:719)

==7863==    by 0x1474DA: ngx_spawn_process (ngx_process.c:199)

==7863==    by 0x1480A8: ngx_start_worker_processes (ngx_process_cycle.c:344)

==7863==    by 0x14952D: ngx_master_process_cycle (ngx_process_cycle.c:130)

考虑到nginx中与用户控制器数据的丰富交互机会以及记录在案的先例,这个缝隙将有可能答应进犯者在某些操作系统和体系结构上执行长途代码。

缝隙使用PoC

缝隙使用PoC下载地址:【poc.py】

广阔研究人员能够经过valgrind并运转nginx来对该缝隙进行测试:

valgrind --trace-children=yes objs/nginx -p ../runtime -c conf/reverse-proxy.conf

接下来,运转DNS服务器(默认监听端口1053):

python poc.py

触发恳求并发送至方针服务器:

curl http://127.0.0.1:8080/

依据缝隙被触发时的堆内存布局,可能会呈现几种不同形式的日志:

corrupted size vs. prev_size

2021/04/16 13:35:15 [alert] 2501#0: worker process 2502 exited on signal 6 (core dumped)

malloc(): invalid next size (unsorted)

2021/04/16 13:35:34 [alert] 2525#0: worker process 2526 exited on signal 6 (core dumped)

不过,valgrind和AdressSanitizer都是能够检测到这种内存溃散事件的。

所使用的nginx配置

daemon off;

 

http{

    access_log logs/access.log;

    server{

        listen 8080;

        location / {

            resolver 127.0.0.1:1053;

            set $dns http://example.net;

            proxy_pass $dns;

        }

    }

}

 

events {

    worker_connections  1024;

}

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。