1 /*************************************************************************** 2 * nmap_dns.h -- Handles parallel reverse DNS resolution for target IPs * 3 * * 4 ***********************IMPORTANT NMAP LICENSE TERMS************************ 5 * * 6 * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap * 7 * Project"). Nmap is also a registered trademark of the Nmap Project. * 8 * * 9 * This program is distributed under the terms of the Nmap Public Source * 10 * License (NPSL). The exact license text applying to a particular Nmap * 11 * release or source code control revision is contained in the LICENSE * 12 * file distributed with that version of Nmap or source code control * 13 * revision. More Nmap copyright/legal information is available from * 14 * https://nmap.org/book/man-legal.html, and further information on the * 15 * NPSL license itself can be found at https://nmap.org/npsl. This header * 16 * summarizes some key points from the Nmap license, but is no substitute * 17 * for the actual license text. * 18 * * 19 * Nmap is generally free for end users to download and use themselves, * 20 * including commercial use. It is available from https://nmap.org. * 21 * * 22 * The Nmap license generally prohibits companies from using and * 23 * redistributing Nmap in commercial products, but we sell a special Nmap * 24 * OEM Edition with a more permissive license and special features for * 25 * this purpose. See https://nmap.org/oem * 26 * * 27 * If you have received a written Nmap license agreement or contract * 28 * stating terms other than these (such as an Nmap OEM license), you may * 29 * choose to use and redistribute Nmap under those terms instead. * 30 * * 31 * The official Nmap Windows builds include the Npcap software * 32 * (https://npcap.org) for packet capture and transmission. It is under * 33 * separate license terms which forbid redistribution without special * 34 * permission. So the official Nmap Windows builds may not be * 35 * redistributed without special permission (such as an Nmap OEM * 36 * license). * 37 * * 38 * Source is provided to this software because we believe users have a * 39 * right to know exactly what a program is going to do before they run it. * 40 * This also allows you to audit the software for security holes. * 41 * * 42 * Source code also allows you to port Nmap to new platforms, fix bugs, * 43 * and add new features. You are highly encouraged to submit your * 44 * changes as a Github PR or by email to the dev@nmap.org mailing list * 45 * for possible incorporation into the main distribution. Unless you * 46 * specify otherwise, it is understood that you are offering us very * 47 * broad rights to use your submissions as described in the Nmap Public * 48 * Source License Contributor Agreement. This is important because we * 49 * fund the project by selling licenses with various terms, and also * 50 * because the inability to relicense code has caused devastating * 51 * problems for other Free Software projects (such as KDE and NASM). * 52 * * 53 * The free version of Nmap is distributed in the hope that it will be * 54 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * 55 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties, * 56 * indemnification and commercial support are all available through the * 57 * Npcap OEM program--see https://nmap.org/oem. * 58 * * 59 ***************************************************************************/ 60 61 #ifndef NMAP_DNS_H 62 #define NMAP_DNS_H 63 64 class Target; 65 66 #include <nbase.h> 67 68 #include <string> 69 #include <list> 70 71 #include <algorithm> 72 #include <sstream> 73 74 75 namespace DNS 76 { 77 78 #define DNS_CHECK_ACCUMLATE(accumulator, tmp, exp) \ 79 do { tmp = exp; if(tmp < 1) return 0 ; accumulator += tmp;} while(0) 80 81 #define DNS_CHECK_UPPER_BOUND(accumulator, max)\ 82 do { if(accumulator > max) return 0; } while(0) 83 84 #define DNS_HAS_FLAG(v,flag) ((v&flag)==flag) 85 86 #define DNS_HAS_ERR(v, err) ((v&DNS::ERR_ALL)==err) 87 88 typedef enum 89 { 90 ID = 0, 91 FLAGS_OFFSET = 2, 92 QDCOUNT = 4, 93 ANCOUNT = 6, 94 NSCOUNT = 8, 95 ARCOUNT = 10, 96 DATA = 12 97 } HEADER_OFFSET; 98 99 typedef enum { 100 ERR_ALL = 0x0007, 101 CHECKING_DISABLED = 0x0010, 102 AUTHENTICATED_DATA = 0x0020, 103 ZERO = 0x0070, 104 RECURSION_AVAILABLE = 0x0080, 105 RECURSION_DESIRED = 0x0100, 106 TRUNCATED = 0x0200, 107 AUTHORITATIVE_ANSWER = 0x0400, 108 OP_STANDARD_QUERY = 0x0000, 109 OP_INVERSE_QUERY = 0x0800, // Obsoleted in RFC 3425 110 OP_SERVER_STATUS = 0x1000, 111 RESPONSE = 0x8000 112 } FLAGS; 113 114 typedef enum { 115 ERR_NO = 0x0000, 116 ERR_FORMAT = 0x0001, 117 ERR_SERVFAIL = 0x0002, 118 ERR_NAME = 0x0003, 119 ERR_NOT_IMPLEMENTED = 0x0004, 120 ERR_REFUSED = 0x0005, 121 } ERRORS; 122 123 typedef enum { 124 A = 1, 125 CNAME = 5, 126 PTR = 12, 127 AAAA = 28, 128 } RECORD_TYPE; 129 130 typedef enum { 131 CLASS_IN = 1 132 } RECORD_CLASS; 133 134 const u8 COMPRESSED_NAME = 0xc0; 135 136 #define C_IPV4_PTR_DOMAIN ".in-addr.arpa" 137 #define C_IPV6_PTR_DOMAIN ".ip6.arpa" 138 const std::string IPV4_PTR_DOMAIN = C_IPV4_PTR_DOMAIN; 139 const std::string IPV6_PTR_DOMAIN = C_IPV6_PTR_DOMAIN; 140 141 class Factory 142 { 143 public: 144 static u16 progressiveId; 145 static bool ipToPtr(const sockaddr_storage &ip, std::string &ptr); 146 static bool ptrToIp(const std::string &ptr, sockaddr_storage &ip); 147 static size_t buildSimpleRequest(const std::string &name, RECORD_TYPE rt, u8 *buf, size_t maxlen); 148 static size_t buildReverseRequest(const sockaddr_storage &ip, u8 *buf, size_t maxlen); 149 static size_t putUnsignedShort(u16 num, u8 *buf, size_t offset, size_t maxlen); 150 static size_t putDomainName(const std::string &name, u8 *buf, size_t offset, size_t maxlen); 151 static size_t parseUnsignedShort(u16 &num, const u8 *buf, size_t offset, size_t maxlen); 152 static size_t parseUnsignedInt(u32 &num, const u8 *buf, size_t offset, size_t maxlen); 153 static size_t parseDomainName(std::string &name, const u8 *buf, size_t offset, size_t maxlen); 154 }; 155 156 class Record 157 { 158 public: 159 virtual Record * clone() = 0; ~Record()160 virtual ~Record() {} 161 virtual size_t parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen) = 0; 162 }; 163 164 class A_Record : public Record 165 { 166 public: 167 sockaddr_storage value; clone()168 Record * clone() { return new A_Record(*this); } ~A_Record()169 ~A_Record() {} 170 size_t parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen); 171 }; 172 173 class PTR_Record : public Record 174 { 175 public: 176 std::string value; clone()177 Record * clone() { return new PTR_Record(*this); } ~PTR_Record()178 ~PTR_Record() {} parseFromBuffer(const u8 * buf,size_t offset,size_t maxlen)179 size_t parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen) 180 { 181 return Factory::parseDomainName(value, buf, offset, maxlen); 182 } 183 }; 184 185 class CNAME_Record : public Record 186 { 187 public: 188 std::string value; clone()189 Record * clone() { return new CNAME_Record(*this); } ~CNAME_Record()190 ~CNAME_Record() {} parseFromBuffer(const u8 * buf,size_t offset,size_t maxlen)191 size_t parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen) 192 { 193 return Factory::parseDomainName(value, buf, offset, maxlen); 194 } 195 }; 196 197 class Query 198 { 199 public: 200 std::string name; 201 u16 record_type; 202 u16 record_class; 203 204 size_t parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen); 205 }; 206 207 class Answer 208 { 209 public: Answer()210 Answer() : record(NULL) {} Answer(const Answer & c)211 Answer(const Answer &c) : name(c.name), record_type(c.record_type), 212 record_class(c.record_class), ttl(c.ttl), length(c.length), 213 record(c.record->clone()) {} ~Answer()214 ~Answer() { delete record; } 215 216 std::string name; 217 u16 record_type; 218 u16 record_class; 219 u32 ttl; 220 u16 length; 221 Record * record; 222 223 // Populate the object reading from buffer and returns "consumed" bytes 224 size_t parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen); 225 Answer& operator=(const Answer &r); 226 }; 227 228 class Packet 229 { 230 public: Packet()231 Packet() : id(0), flags(0) {} ~Packet()232 ~Packet() {} 233 addFlags(FLAGS fl)234 void addFlags(FLAGS fl){ flags |= fl; } removeFlags(FLAGS fl)235 void removeFlags(FLAGS fl){ flags &= ~fl; } resetFlags()236 void resetFlags() { flags = 0; } 237 size_t writeToBuffer(u8 *buf, size_t maxlen); 238 size_t parseFromBuffer(const u8 *buf, size_t maxlen); 239 240 u16 id; 241 u16 flags; 242 std::list<Query> queries; 243 std::list<Answer> answers; 244 }; 245 246 } 247 248 void nmap_mass_rdns(Target ** targets, int num_targets); 249 250 std::list<std::string> get_dns_servers(); 251 252 #endif 253