PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ronin/ip_address.rb

http://github.com/postmodern/ronin
Ruby | 350 lines | 112 code | 37 blank | 201 comment | 3 complexity | d8bedabefc1bb2bbc9eb1e82ab961bc5 MD5 | raw file
Possible License(s): GPL-3.0
  1. #
  2. # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
  3. #
  4. # This file is part of Ronin.
  5. #
  6. # Ronin is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Ronin is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. require 'ronin/extensions/ip_addr'
  20. require 'ronin/extensions/resolv'
  21. require 'ronin/model/importable'
  22. require 'ronin/address'
  23. require 'ronin/host_name'
  24. require 'ipaddr'
  25. module Ronin
  26. #
  27. # Represents IP addresses that can be stored in the {Database}.
  28. #
  29. class IPAddress < Address
  30. include Model::Importable
  31. # The IP Address
  32. property :address, IPAddress, :required => true,
  33. :unique => true
  34. # Type of the address
  35. property :version, Integer, :set => [4, 6],
  36. :default => lambda { |ip_addr,version|
  37. if ip_addr.address
  38. if ip_addr.address.ipv6?
  39. 6
  40. else
  41. 4
  42. end
  43. end
  44. }
  45. # The MAC Addresses associations
  46. has 0..n, :ip_address_mac_addresses, :model => 'IPAddressMACAddress'
  47. # The MAC Addresses associated with the IP Address
  48. has 0..n, :mac_addresses, :through => :ip_address_mac_addresses,
  49. :model => 'MACAddress'
  50. # The host-names that the IP Address serves
  51. has 0..n, :host_name_ip_addresses, :model => 'HostNameIPAddress'
  52. # The host-names associated with the IP Address
  53. has 0..n, :host_names, :through => :host_name_ip_addresses
  54. # Open ports of the host
  55. has 0..n, :open_ports
  56. # Ports of the host
  57. has 0..n, :ports, :through => :open_ports
  58. # Any OS guesses against the IP Address
  59. has 0..n, :os_guesses, :model => 'OSGuess'
  60. # Any OSes that the IP Address might be running
  61. has 0..n, :oses, :through => :os_guesses,
  62. :model => 'OS',
  63. :via => :os
  64. #
  65. # Extracts and parses IP addresses from text.
  66. #
  67. # @param [String] text
  68. # The text to parse.
  69. #
  70. # @param [Symbol, Integer] version
  71. # Specifies whether to parse IPv4 or IPv6 addresses.
  72. #
  73. # @yield [ip]
  74. # The given block will be passed each extracted IP address.
  75. #
  76. # @yieldparam [IPAddress] ip
  77. # An extracted IP Address from the text.
  78. #
  79. # @see http://ronin-ruby.github.com/docs/ronin-support/IPAddr.html#extract-class_method
  80. #
  81. # @since 1.3.0
  82. #
  83. # @api public
  84. #
  85. def self.extract(text,version=nil)
  86. return enum_for(:extract,text,version).to_a unless block_given?
  87. IPAddr.extract(text,version) do |ip|
  88. yield parse(ip)
  89. end
  90. return nil
  91. end
  92. #
  93. # Searches for all IPv4 addresses.
  94. #
  95. # @return [Array<IPAddress>]
  96. # The IPv4 addresses.
  97. #
  98. # @since 1.0.0
  99. #
  100. # @api public
  101. #
  102. def self.v4
  103. all(:version => 4)
  104. end
  105. #
  106. # Searches for all IPv6 addresses.
  107. #
  108. # @return [Array<IPAddress>]
  109. # The IPv6 addresses.
  110. #
  111. # @since 1.0.0
  112. #
  113. # @api public
  114. #
  115. def self.v6
  116. all(:version => 6)
  117. end
  118. #
  119. # Searches for all IP addresses associated with specific MAC addresses.
  120. #
  121. # @param [Array<String>, String] macs
  122. # The MAC address(es) to search for.
  123. #
  124. # @return [Array<IPAddress>]
  125. # The matching IP addresses.
  126. #
  127. # @since 1.0.0
  128. #
  129. # @api public
  130. #
  131. def self.with_macs(macs)
  132. all('mac_addresses.address' => macs)
  133. end
  134. #
  135. # Searches for IP addresses associated with the given host names.
  136. #
  137. # @param [Array<String>, String] names
  138. # The host name(s) to search for.
  139. #
  140. # @return [Array<IPAddress>]
  141. # The matching IP addresses.
  142. #
  143. # @since 1.0.0
  144. #
  145. # @api public
  146. #
  147. def self.with_hosts(names)
  148. all('host_names.address' => names)
  149. end
  150. #
  151. # Searches for IP addresses with the given open ports.
  152. #
  153. # @param [Array<Integer>, Integer] numbers
  154. # The port number(s) to search for.
  155. #
  156. # @return [Array<IPAddress>]
  157. # The matching IP addresses.
  158. #
  159. # @since 1.0.0
  160. #
  161. # @api public
  162. #
  163. def self.with_ports(numbers)
  164. all('ports.number' => numbers)
  165. end
  166. #
  167. # Looks up the host name to multiple IP addresses.
  168. #
  169. # @param [String] name
  170. # The host name to look up.
  171. #
  172. # @param [String] nameserver
  173. # Optional nameserver to query.
  174. #
  175. # @return [Array<IPAddress>]
  176. # The new or previously saved IP Addresses for the host name.
  177. #
  178. # @since 1.0.0
  179. #
  180. # @api public
  181. #
  182. def self.lookup(name,nameserver=nil)
  183. host = HostName.first_or_new(:address => name)
  184. resolver = Resolv.resolver(nameserver)
  185. ips = begin
  186. resolver.getaddresses(name)
  187. rescue
  188. []
  189. end
  190. ips.map! do |addr|
  191. IPAddress.first_or_create(
  192. :address => addr,
  193. :host_names => [host]
  194. )
  195. end
  196. return ips
  197. end
  198. #
  199. # Performs a reverse lookup on the IP address.
  200. #
  201. # @param [String] nameserver
  202. # Optional nameserver to query.
  203. #
  204. # @return [Array<HostName>]
  205. # The host-names associated with the IP Address.
  206. #
  207. # @since 1.0.0
  208. #
  209. # @api public
  210. #
  211. def lookup!(nameserver=nil)
  212. resolver = Resolv.resolver(nameserver)
  213. hosts = begin
  214. resolver.getnames(self.address.to_s)
  215. rescue
  216. []
  217. end
  218. hosts.map! do |name|
  219. HostName.first_or_create(
  220. :address => name,
  221. :ip_addresses => [self]
  222. )
  223. end
  224. return hosts
  225. end
  226. #
  227. # The MAC Address that was most recently used by the IP Address.
  228. #
  229. # @return [MacAddress]
  230. # The MAC Address that most recently used the IP Address.
  231. #
  232. # @since 1.0.0
  233. #
  234. # @api public
  235. #
  236. def recent_mac_address
  237. self.ip_address_mac_addresses.all(
  238. :order => [:created_at.desc]
  239. ).mac_addresses.first
  240. end
  241. #
  242. # The host-name that was most recently used by the IP Address.
  243. #
  244. # @return [HostName]
  245. # The host-name that most recently used by the IP Address.
  246. #
  247. # @since 1.0.0
  248. #
  249. # @api public
  250. #
  251. def recent_host_name
  252. self.host_name_ip_addresses.all(
  253. :order => [:created_at.desc]
  254. ).host_names.first
  255. end
  256. #
  257. # The Operating System that was most recently guessed for the IP
  258. # Address.
  259. #
  260. # @return [OS]
  261. # The Operating System that most recently was guessed.
  262. #
  263. # @since 1.0.0
  264. #
  265. # @api public
  266. #
  267. def recent_os_guess
  268. self.os_guesses.all(:order => [:created_at.desc]).oses.first
  269. end
  270. #
  271. # Determines when the IP address was last scanned.
  272. #
  273. # @return [Time, nil]
  274. # The time the IP address was last scanned at.
  275. #
  276. # @since 1.0.0
  277. #
  278. # @api public
  279. #
  280. def last_scanned_at
  281. last_scanned_port = self.open_ports.first(
  282. :order => [:last_scanned_at.desc]
  283. )
  284. return last_scanned_port.last_scanned_at if last_scanned_port
  285. end
  286. #
  287. # Converts the address to an IP address object.
  288. #
  289. # @return [IPAddr]
  290. # The IPAddr object representing either the IPv4 or IPv6 address.
  291. #
  292. # @since 1.0.0
  293. #
  294. # @api public
  295. #
  296. def to_ip
  297. self.address
  298. end
  299. #
  300. # Converts the address to an Integer.
  301. #
  302. # @return [Integer]
  303. # The network representation of the IP address.
  304. #
  305. # @since 1.0.0
  306. #
  307. # @api public
  308. #
  309. def to_i
  310. self.address.to_i
  311. end
  312. end
  313. end