|
| 1 | +# -*- coding: binary -*- |
| 2 | +# frozen_string_literal: true |
| 3 | + |
| 4 | +require 'bindata' |
| 5 | + |
| 6 | +module Rex::Proto |
| 7 | + module MsDnsp |
| 8 | + # see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/39b03b89-2264-4063-8198-d62f62a6441a |
| 9 | + class DnsRecordType |
| 10 | + DNS_TYPE_ZERO = 0x0000 |
| 11 | + DNS_TYPE_A = 0x0001 |
| 12 | + DNS_TYPE_NS = 0x0002 |
| 13 | + DNS_TYPE_MD = 0x0003 |
| 14 | + DNS_TYPE_MF = 0x0004 |
| 15 | + DNS_TYPE_CNAME = 0x0005 |
| 16 | + DNS_TYPE_SOA = 0x0006 |
| 17 | + DNS_TYPE_MB = 0x0007 |
| 18 | + DNS_TYPE_MG = 0x0008 |
| 19 | + DNS_TYPE_MR = 0x0009 |
| 20 | + DNS_TYPE_NULL = 0x000A |
| 21 | + DNS_TYPE_WKS = 0x000B |
| 22 | + DNS_TYPE_PTR = 0x000C |
| 23 | + DNS_TYPE_HINFO = 0x000D |
| 24 | + DNS_TYPE_MINFO = 0x000E |
| 25 | + DNS_TYPE_MX = 0x000F |
| 26 | + DNS_TYPE_TXT = 0x0010 |
| 27 | + DNS_TYPE_RP = 0x0011 |
| 28 | + DNS_TYPE_AFSDB = 0x0012 |
| 29 | + DNS_TYPE_X25 = 0x0013 |
| 30 | + DNS_TYPE_ISDN = 0x0014 |
| 31 | + DNS_TYPE_RT = 0x0015 |
| 32 | + DNS_TYPE_SIG = 0x0018 |
| 33 | + DNS_TYPE_KEY = 0x0019 |
| 34 | + DNS_TYPE_AAAA = 0x001C |
| 35 | + DNS_TYPE_LOC = 0x001D |
| 36 | + DNS_TYPE_NXT = 0x001E |
| 37 | + DNS_TYPE_SRV = 0x0021 |
| 38 | + DNS_TYPE_ATMA = 0x0022 |
| 39 | + DNS_TYPE_NAPTR = 0x0023 |
| 40 | + DNS_TYPE_DNAME = 0x0027 |
| 41 | + DNS_TYPE_DS = 0x002B |
| 42 | + DNS_TYPE_RRSIG = 0x002E |
| 43 | + DNS_TYPE_NSEC = 0x002F |
| 44 | + DNS_TYPE_DNSKEY = 0x0030 |
| 45 | + DNS_TYPE_DHCID = 0x0031 |
| 46 | + DNS_TYPE_NSEC3 = 0x0032 |
| 47 | + DNS_TYPE_NSEC3PARAM = 0x0033 |
| 48 | + DNS_TYPE_TLSA = 0x0034 |
| 49 | + DNS_TYPE_ALL = 0x00FF |
| 50 | + DNS_TYPE_WINS = 0xFF01 |
| 51 | + DNS_TYPE_WINSR = 0xFF02 |
| 52 | + end |
| 53 | + |
| 54 | + class MsDnspAddr4 < BinData::Primitive |
| 55 | + string :data, length: 4 |
| 56 | + |
| 57 | + def get |
| 58 | + Rex::Socket.addr_ntoa(self.data) |
| 59 | + end |
| 60 | + |
| 61 | + def set(v) |
| 62 | + raise TypeError, 'must be an IPv4 address' unless Rex::Socket.is_ipv4?(v) |
| 63 | + |
| 64 | + self.data = Rex::Socket.addr_aton(v) |
| 65 | + end |
| 66 | + end |
| 67 | + |
| 68 | + class MsDnspAddr6 < BinData::Primitive |
| 69 | + string :data, length: 16 |
| 70 | + |
| 71 | + def get |
| 72 | + Rex::Socket.addr_ntoa(self.data) |
| 73 | + end |
| 74 | + |
| 75 | + def set(v) |
| 76 | + raise TypeError, 'must be an IPv6 address' unless Rex::Socket.is_ipv6?(v) |
| 77 | + |
| 78 | + self.data = Rex::Socket.addr_aton(v) |
| 79 | + end |
| 80 | + end |
| 81 | + |
| 82 | + # see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/6912b338-5472-4f59-b912-0edb536b6ed8 |
| 83 | + class MsDnspDnsRecord < BinData::Record |
| 84 | + endian :little |
| 85 | + |
| 86 | + uint16 :data_length, initial_value: -> { data.length } |
| 87 | + uint16 :record_type |
| 88 | + uint8 :version |
| 89 | + uint8 :rank |
| 90 | + uint16 :flags |
| 91 | + uint32 :serial |
| 92 | + uint32be :ttl_seconds |
| 93 | + uint32 :reserved |
| 94 | + uint32 :timestamp |
| 95 | + choice :data, selection: :record_type do |
| 96 | + ms_dnsp_addr4 DnsRecordType::DNS_TYPE_A |
| 97 | + ms_dnsp_addr6 DnsRecordType::DNS_TYPE_AAAA |
| 98 | + string :default, read_length: :data_length |
| 99 | + end |
| 100 | + end |
| 101 | + end |
| 102 | +end |
0 commit comments