In order to learn ntp protocol and protect ntp server against NTP DDOS Attack. We need a vulnable ntp server.
#!/bin/bash
wget -c https://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-4.2.6p4.tar.gz
tar xvf ntp-4.2.6p4.tar.gz
cd ntp-4.2.6p4.tar
./configure && make
#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import struct
import logging
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__)
def int2ip(addr):
return socket.inet_ntoa(struct.pack('!I', addr))
def parse_ntp_response(data):
responses = []
if len(data) < 8: return responses
(
flags,
implementation,
request_code,
number_of_data_items,
size_of_data_items
) = struct.unpack('!HbbHH', data[0:8])
ml = data[8:]
if len(ml) < 72: return responses
ml_bytesize = 72
monlists = [
ml[i:i+ml_bytesize]
for i in range(0, len(ml), ml_bytesize)
]
for monlist in monlists:
# a avaiable mon: 72 bytes
if len(monlist) % 72 != 0: continue
_ = monlist[:36]
(
avgint,
lsint,
restr,
count,
remote_address,
local_address,
flags,
port,
mode,
version,
ipv6
) = struct.unpack('!LLLLLLLHBBL', _)
info = {
'avgint': avgint,
'lsint': lsint,
'restr': restr,
'count': count,
'remote_address': int2ip(remote_address),
'local_address': int2ip(local_address),
'flags': flags,
'port': port,
'mode': mode,
'version': version,
'ipv6': ipv6
}
if info not in responses: responses.append(info)
return responses
def send_ntp_request(src, srcport, dst, dstport=123):
ntpclient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ntpclient.settimeout(4.0)
responses = []
buffersize = 1024
try:
# ntpclient.bind((src, int(srcport)))
# Network Time Protocol (NTP Version 2, private)
protocol = {
'Flags': 0x1700,
'Implementation': 0x03,
'Request_code': 0x2a,
'Number_of_data_items': 0x0000,
'Size_of_data_item': 0x0000
}
payload = struct.pack(
'!HBBHH',
protocol['Flags'],
protocol['Implementation'],
protocol['Request_code'],
protocol['Number_of_data_items'],
protocol['Size_of_data_item']
)
payload += '\x00' * 184
# send ntp monlist request: ntpdc -n -c monlist 127.0.0.1
ntpclient.sendto(payload, (dst, dstport))
while True:
data, addr = ntpclient.recvfrom(buffersize)
if not data: break
if data not in responses: responses.append(data)
except Exception as err:
log.debug(err)
finally:
ntpclient.close()
responses = map(parse_ntp_response, responses)
return responses
src = '127.0.0.1'
srcport = 20000
dst = '127.0.0.1'
dstport = 123
from pprint import pprint
pprint(send_ntp_request(src, srcport, dst, dstport))
# References
# 1. https://blog.cloudflare.com/understanding-and-mitigating-ntp-based-ddos-attacks/
# 2. https://samsclass.info/124/proj14/p6x-NTP-DrDOS.htm