发布于2022年11月4日3年前 CVE-2021-23017:nginx DNS解析漏洞PoC公开 缝隙评级高危缝隙确认受影响版别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缝隙CVECVE-2021-23017CWE193CVSS评分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; }
创建帐户或登录后发表意见