Python - NTP

In order to learn ntp protocol and protect ntp server against NTP DDOS Attack. We need a vulnable ntp server.

Install a vulnerable NTP Server - NTP 4.2.6

#!/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

NTP Protocol

#!/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

References:

  1. https://samsclass.info/124/proj14/p6x-NTP-DrDOS.htm

你可能感兴趣的:(python,Protocols,GDB)