Skip to content

Commit

Permalink
Merge pull request #19749 from zeroSteiner/fix/mod/ntp_nak_to_the_future
Browse files Browse the repository at this point in the history
Fix ntp_nak_to_the_future
  • Loading branch information
jheysel-r7 authored Jan 7, 2025
2 parents dac7c39 + e5e0657 commit f475b9d
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
## Vulnerable Application

## Verification Steps

1. Use the supplied Dockerfile to start a vulnerable instance of the application
1. Build it with: `docker build -t ntpd:4.2.8p3 .`
1. Run it with: `docker run --rm -it --name ntp-server -p 123:123/udp ntpd:4.2.8p3`
1. Start `msfconsole` and use the module
1. Set the `RHOSTS` value as necessary
1. Run the module and see that the target is vulnerable

### Dockerfile
Use this as `ntp.conf`:

```
# Basic NTP configuration
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst
driftfile /var/lib/ntp/ntp.drift
# Enable authentication for secure associations
enable auth
# Define trusted keys
trustedkey 1
# Open restrictions for all clients on the local network (example: 192.168.0.0/16)
restrict default kod nomodify notrap
restrict 127.0.0.1
restrict ::1
restrict 192.168.0.0 mask 255.255.0.0 autokey
# Uncomment to allow all clients (use cautiously)
# restrict default kod nomodify notrap
```

Use this as `Dockerfile`:

```
ARG version=4.2.8p3
FROM ubuntu:16.04
ARG version
# Install dependencies
RUN apt-get update && apt-get install -y \
wget \
build-essential \
libcap-dev \
libssl-dev && \
apt-get clean
# Download and build NTPD
WORKDIR /tmp
RUN wget https://web.archive.org/web/20240608062853/https://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-$version.tar.gz && \
tar -xzf ntp-$version.tar.gz && \
cd ntp-$version && \
./configure --prefix=/usr/local --enable-linuxcaps && \
make && \
make install && \
cd .. && \
rm -rf ntp-$version*
# Add configuration file
COPY ntp.conf /etc/ntp.conf
# Expose NTP port (123)
EXPOSE 123/udp
# Run ntpd
ENTRYPOINT ["/usr/local/bin/ntpd"]
CMD ["-g", "-d", "-d"]
```

## Options

## Scenarios

### Ubuntu 16.04 NTPd 4.2.8p3

```
metasploit-framework (S:0 J:0) auxiliary(scanner/ntp/ntp_nak_to_the_future) > set RHOSTS 192.168.159.128, 192.168.159.10
RHOSTS => 192.168.159.128, 192.168.159.10
metasploit-framework (S:0 J:0) auxiliary(scanner/ntp/ntp_nak_to_the_future) > run
[+] 192.168.159.128:123 - NTP - VULNERABLE: Accepted a NTP symmetric active association
[*] Scanned 1 of 2 hosts (50% complete)
[*] Scanned 1 of 2 hosts (50% complete)
[*] Scanned 1 of 2 hosts (50% complete)
[*] Scanned 1 of 2 hosts (50% complete)
[*] Scanned 1 of 2 hosts (50% complete)
[*] Scanned 2 of 2 hosts (100% complete)
[*] Auxiliary module execution completed
metasploit-framework (S:0 J:0) auxiliary(scanner/ntp/ntp_nak_to_the_future) >
```
19 changes: 0 additions & 19 deletions lib/rex/proto/ntp/modes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,6 @@ def records
end
end

class NTPSymmetric < BinData::Record
alias size num_bytes
endian :big
bit2 :li
bit3 :version, initial_value: 3
bit3 :mode
uint8 :stratum
uint8 :poll
uint8 :precision
uint32 :root_delay
uint32 :root_dispersion
uint32 :reference_id
uint64 :reference_timestamp
uint64 :origin_timestamp
uint64 :receive_timestamp
uint64 :transmit_timestamp
rest :payload
end

def ntp_control(version, operation, payload = nil)
n = NTPControl.new
n.version = version
Expand Down
34 changes: 13 additions & 21 deletions modules/auxiliary/scanner/ntp/ntp_nak_to_the_future.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
include Msf::Exploit::Remote::Udp
include Msf::Auxiliary::NTP

SYMMETRIC_ACTIVE_MODE = Rex::Proto::NTP::Constants::Mode::SYMMETRIC_ACTIVE
SYMMETRIC_PASSIVE_MODE = Rex::Proto::NTP::Constants::Mode::SYMMETRIC_PASSIVE

def initialize(info = {})
super(
Expand Down Expand Up @@ -39,26 +41,16 @@ def initialize(info = {})
]
)
)

register_options(
[
OptInt.new('OFFSET', [true, "Offset from local time, in seconds", 300])
])
end

def build_crypto_nak(time)
probe = Rex::Proto::NTP::NTPSymmetric.new
probe = Rex::Proto::NTP::Header::NTPHeader.new
probe.version_number = 3
probe.stratum = 1
probe.poll = 10
probe.mode = 1
probe.mode = SYMMETRIC_ACTIVE_MODE
unless time
now = Time.now
# compute the timestamp. NTP stores a timestamp as 64-bit unsigned
# integer, the high 32-bits representing the number of seconds since era
# epoch and the low 32-bits representing the fraction of a second. The era
# epoch in this case is Jan 1 1900, so we must add the number of seconds
# between then and the ruby era epoch, Jan 1 1970, which is 2208988800
time = ((now.to_i + 2208988800 + datastore['OFFSET']) << 32) + now.nsec
time = Time.now
end

# TODO: use different values for each?
Expand All @@ -67,24 +59,24 @@ def build_crypto_nak(time)
probe.receive_timestamp = time
probe.transmit_timestamp = time
# key-id 0
probe.payload = "\x00\x00\x00\x00"
probe.key_identifier = 0
probe
end

def check
connect_udp

# pick a random 64-bit timestamp
canary_timestamp = rand((2**32)..((2**64) - 1))
canary_timestamp = Time.now.utc - (60 * 5)
probe = build_crypto_nak(canary_timestamp)
udp_sock.put(probe)
udp_sock.put(probe.to_binary_s)

expected_length = probe.to_binary_s.length - probe.payload.length
expected_length = probe.offset_of(probe.key_identifier)
response = udp_sock.timed_read(expected_length)
disconnect_udp
if response.length == expected_length
ntp_symmetric = Rex::Proto::NTP::NTPSymmetric.new.read(response)
if ntp_symmetric.mode == 2 && ntp_symmetric.origin_timestamp == canary_timestamp
ntp_symmetric = Rex::Proto::NTP::Header::NTPHeader.read(response)
if ntp_symmetric.mode == SYMMETRIC_PASSIVE_MODE && ntp_symmetric.origin_timestamp == nil
vprint_good("#{rhost}:#{rport} - NTP - VULNERABLE: Accepted a NTP symmetric active association")
report_vuln(
host: rhost,
Expand Down

0 comments on commit f475b9d

Please sign in to comment.