Path: blob/master/lib/rex/proto/ntp/modes.rb
19758 views
# -*- coding: binary -*-12require 'bindata'34module Rex5module Proto6module NTP::Modes78# A very generic NTP message9#10# Uses the common/similar parts from versions 1-4 and considers everything11# after to be just one big field. For the particulars on the different versions,12# see:13# http://tools.ietf.org/html/rfc958#appendix-B14# http://tools.ietf.org/html/rfc1059#appendix-B15# pages 45/48 of http://tools.ietf.org/pdf/rfc1119.pdf16# http://tools.ietf.org/html/rfc1305#appendix-D17# http://tools.ietf.org/html/rfc5905#page-1918class NTPGeneric < BinData::Record19alias size num_bytes20# 0 1 2 321# 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 122# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+23# |LI | VN | mode| Stratum | Poll | Precision |24# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+25endian :big26bit2 :li27bit3 :version28bit3 :mode29uint8 :stratum30uint8 :poll31uint8 :precision32rest :payload33end3435# An NTP control message. Control messages are only specified for NTP36# versions 2-4, but this is a fuzzer so why not try them all...37class NTPControl < BinData::Record38alias size num_bytes39# 0 1 2 340# 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 141# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+42# |00 | VN | 6 |R E M| op | Sequence |43# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+44# | status | association id |45# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+46# | offset | count |47# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+48endian :big49bit2 :reserved50bit3 :version51bit3 :mode, initial_value: 652bit1 :response53bit1 :error54bit1 :more55bit5 :operation56uint16 :sequence57uint16 :status58uint16 :association_id59# TODO: there *must* be bugs in the handling of these next two fields!60uint16 :payload_offset61uint16 :payload_size62rest :payload63end6465# An NTP "private" message. Private messages are only specified for NTP66# versions 2-4, but this is a fuzzer so why not try them all...67class NTPPrivate < BinData::Record68alias size num_bytes69# 0 1 2 370# 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 171# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+72# |R M| VN | 7 |A| Sequence | Implementation| Req code |73# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+74# | err | Number of data items | MBZ | Size of data item |75# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+76endian :big77bit1 :response78bit1 :more79bit3 :version80bit3 :mode, initial_value: 781bit1 :auth82bit7 :sequence83uint8 :implementation84uint8 :request_code85bit4 :error86bit12 :record_count87bit4 :mbz88bit12 :record_size89rest :payload9091def records92records = []931.upto(record_count) do |record_num|94records << payload[record_size * (record_num - 1), record_size]95end96records97end98end99100def ntp_control(version, operation, payload = nil)101n = NTPControl.new102n.version = version103n.operation = operation104if payload105n.payload_offset = 0106n.payload_size = payload.size107n.payload = payload108end109n110end111112def ntp_private(version, implementation, request_code, payload = nil)113n = NTPPrivate.new114n.version = version115n.implementation = implementation116n.request_code = request_code117n.payload = payload if payload118n119end120121def ntp_generic(version, mode)122n = NTPGeneric.new123n.version = version124n.mode = mode125n126end127128# Parses the given message and provides a description about the NTP message inside129def describe(message)130ntp = NTPGeneric.new.read(message)131"#{message.size}-byte version #{ntp.version} mode #{ntp.mode} reply"132end133end134end135end136137138