CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/ntp/modes.rb
Views: 11704
1
# -*- coding: binary -*-
2
3
require 'bindata'
4
5
module Rex
6
module Proto
7
module NTP::Modes
8
9
# A very generic NTP message
10
#
11
# Uses the common/similar parts from versions 1-4 and considers everything
12
# after to be just one big field. For the particulars on the different versions,
13
# see:
14
# http://tools.ietf.org/html/rfc958#appendix-B
15
# http://tools.ietf.org/html/rfc1059#appendix-B
16
# pages 45/48 of http://tools.ietf.org/pdf/rfc1119.pdf
17
# http://tools.ietf.org/html/rfc1305#appendix-D
18
# http://tools.ietf.org/html/rfc5905#page-19
19
class NTPGeneric < BinData::Record
20
alias size num_bytes
21
# 0 1 2 3
22
# 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
23
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24
# |LI | VN | mode| Stratum | Poll | Precision |
25
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26
endian :big
27
bit2 :li
28
bit3 :version
29
bit3 :mode
30
uint8 :stratum
31
uint8 :poll
32
uint8 :precision
33
rest :payload
34
end
35
36
# An NTP control message. Control messages are only specified for NTP
37
# versions 2-4, but this is a fuzzer so why not try them all...
38
class NTPControl < BinData::Record
39
alias size num_bytes
40
# 0 1 2 3
41
# 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
42
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43
# |00 | VN | 6 |R E M| op | Sequence |
44
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45
# | status | association id |
46
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
# | offset | count |
48
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49
endian :big
50
bit2 :reserved
51
bit3 :version
52
bit3 :mode, initial_value: 6
53
bit1 :response
54
bit1 :error
55
bit1 :more
56
bit5 :operation
57
uint16 :sequence
58
uint16 :status
59
uint16 :association_id
60
# TODO: there *must* be bugs in the handling of these next two fields!
61
uint16 :payload_offset
62
uint16 :payload_size
63
rest :payload
64
end
65
66
# An NTP "private" message. Private messages are only specified for NTP
67
# versions 2-4, but this is a fuzzer so why not try them all...
68
class NTPPrivate < BinData::Record
69
alias size num_bytes
70
# 0 1 2 3
71
# 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
72
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73
# |R M| VN | 7 |A| Sequence | Implementation| Req code |
74
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
# | err | Number of data items | MBZ | Size of data item |
76
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
endian :big
78
bit1 :response
79
bit1 :more
80
bit3 :version
81
bit3 :mode, initial_value: 7
82
bit1 :auth
83
bit7 :sequence
84
uint8 :implementation
85
uint8 :request_code
86
bit4 :error
87
bit12 :record_count
88
bit4 :mbz
89
bit12 :record_size
90
rest :payload
91
92
def records
93
records = []
94
1.upto(record_count) do |record_num|
95
records << payload[record_size * (record_num - 1), record_size]
96
end
97
records
98
end
99
end
100
101
class NTPSymmetric < BinData::Record
102
alias size num_bytes
103
endian :big
104
bit2 :li
105
bit3 :version, initial_value: 3
106
bit3 :mode
107
uint8 :stratum
108
uint8 :poll
109
uint8 :precision
110
uint32 :root_delay
111
uint32 :root_dispersion
112
uint32 :reference_id
113
uint64 :reference_timestamp
114
uint64 :origin_timestamp
115
uint64 :receive_timestamp
116
uint64 :transmit_timestamp
117
rest :payload
118
end
119
120
def ntp_control(version, operation, payload = nil)
121
n = NTPControl.new
122
n.version = version
123
n.operation = operation
124
if payload
125
n.payload_offset = 0
126
n.payload_size = payload.size
127
n.payload = payload
128
end
129
n
130
end
131
132
def ntp_private(version, implementation, request_code, payload = nil)
133
n = NTPPrivate.new
134
n.version = version
135
n.implementation = implementation
136
n.request_code = request_code
137
n.payload = payload if payload
138
n
139
end
140
141
def ntp_generic(version, mode)
142
n = NTPGeneric.new
143
n.version = version
144
n.mode = mode
145
n
146
end
147
148
# Parses the given message and provides a description about the NTP message inside
149
def describe(message)
150
ntp = NTPGeneric.new.read(message)
151
"#{message.size}-byte version #{ntp.version} mode #{ntp.mode} reply"
152
end
153
end
154
end
155
end
156
157