PageRenderTime 44ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/rex/socket.rb

https://bitbucket.org/jrossi/metasploit
Ruby | 684 lines | 355 code | 112 blank | 217 comment | 43 complexity | f3e63ed2dcbd5d7950c144c5cf82a54c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. require 'socket'
  2. require 'thread'
  3. require 'resolv'
  4. require 'rex/exceptions'
  5. module Rex
  6. ###
  7. #
  8. # Base class for all sockets.
  9. #
  10. ###
  11. module Socket
  12. module Comm
  13. end
  14. require 'rex/socket/parameters'
  15. require 'rex/socket/tcp'
  16. require 'rex/socket/tcp_server'
  17. require 'rex/socket/comm'
  18. require 'rex/socket/comm/local'
  19. require 'rex/socket/switch_board'
  20. require 'rex/socket/subnet_walker'
  21. require 'rex/socket/range_walker'
  22. ##
  23. #
  24. # Factory methods
  25. #
  26. ##
  27. #
  28. # Create a socket instance using the supplied parameter hash.
  29. #
  30. def self.create(opts = {})
  31. return create_param(Rex::Socket::Parameters.from_hash(opts))
  32. end
  33. #
  34. # Create a socket using the supplied Rex::Socket::Parameter instance.
  35. #
  36. def self.create_param(param)
  37. return param.comm.create(param)
  38. end
  39. #
  40. # Create a TCP socket using the supplied parameter hash.
  41. #
  42. def self.create_tcp(opts = {})
  43. return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'tcp')))
  44. end
  45. #
  46. # Create a TCP server socket using the supplied parameter hash.
  47. #
  48. def self.create_tcp_server(opts = {})
  49. return create_tcp(opts.merge('Server' => true))
  50. end
  51. #
  52. # Create a UDP socket using the supplied parameter hash.
  53. #
  54. def self.create_udp(opts = {})
  55. return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'udp')))
  56. end
  57. #
  58. # Create a IP socket using the supplied parameter hash.
  59. #
  60. def self.create_ip(opts = {})
  61. return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'ip')))
  62. end
  63. ##
  64. #
  65. # Serialization
  66. #
  67. ##
  68. # Cache our IPv6 support flag
  69. @@support_ipv6 = nil
  70. #
  71. # Determine whether we support IPv6
  72. #
  73. def self.support_ipv6?
  74. return @@support_ipv6 if not @@support_ipv6.nil?
  75. @@support_ipv6 = false
  76. if (::Socket.const_defined?('AF_INET6'))
  77. begin
  78. s = ::Socket.new(::Socket::AF_INET6, ::Socket::SOCK_DGRAM, ::Socket::IPPROTO_UDP)
  79. s.close
  80. @@support_ipv6 = true
  81. rescue
  82. end
  83. end
  84. return @@support_ipv6
  85. end
  86. #
  87. # Determine whether this is an IPv4 address
  88. #
  89. def self.is_ipv4?(addr)
  90. res = Rex::Socket.getaddress(addr)
  91. res.match(/:/) ? false : true
  92. end
  93. #
  94. # Determine whether this is an IPv6 address
  95. #
  96. def self.is_ipv6?(addr)
  97. res = Rex::Socket.getaddress(addr)
  98. res.match(/:/) ? true : false
  99. end
  100. #
  101. # Checks to see if the supplied address is a dotted quad.
  102. #
  103. def self.dotted_ip?(addr)
  104. # Assume anything with a colon is IPv6
  105. return true if (support_ipv6? and addr =~ /:/)
  106. # Otherwise assume this is IPv4
  107. (addr =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))$/) ? true : false
  108. end
  109. #
  110. # Return true if +addr+ is within the ranges specified in RFC1918, or
  111. # RFC5735/RFC3927
  112. #
  113. def self.is_internal?(addr)
  114. if self.dotted_ip?(addr)
  115. addr =~ /^(?:10\.|192\.168|172.(?:1[6-9]|2[0-9]|3[01])\.|169\.254)/
  116. else
  117. false
  118. end
  119. end
  120. #
  121. # Wrapper for Resolv.getaddress that takes special care to see if the
  122. # supplied address is already a dotted quad, for instance. This is
  123. # necessary to prevent calls to gethostbyaddr (which occurs on windows).
  124. # These calls can be quite slow. This also fixes an issue with the
  125. # Resolv.getaddress() call being non-functional on Ruby 1.9.1 (Win32).
  126. #
  127. def self.getaddress(addr, accept_ipv6 = true)
  128. begin
  129. if dotted_ip?(addr)
  130. return addr
  131. end
  132. res = ::Socket.gethostbyname(addr)
  133. return nil if not res
  134. # Shift the first three elements out
  135. rname = res.shift
  136. ralias = res.shift
  137. rtype = res.shift
  138. # Reject IPv6 addresses if we don't accept them
  139. if not accept_ipv6
  140. res.reject!{|nbo| nbo.length != 4}
  141. end
  142. # Make sure we have at least one name
  143. return nil if res.length == 0
  144. # Return the first address of the result
  145. self.addr_ntoa( res[0] )
  146. rescue ::ArgumentError # Win32 bug
  147. nil
  148. end
  149. end
  150. #
  151. # Wrapper for Socket.gethostbyname which takes into account whether or not
  152. # an IP address is supplied. If it is, then reverse DNS resolution does
  153. # not occur. This is done in order to prevent delays, such as would occur
  154. # on Windows.
  155. #
  156. def self.gethostbyname(host)
  157. if (dotted_ip?(host))
  158. if (is_ipv4?(host))
  159. return [ host, host, 2, host.split('.').map{ |c| c.to_i }.pack("C4") ]
  160. end
  161. end
  162. ::Socket.gethostbyname(host)
  163. end
  164. #
  165. # Create a sockaddr structure using the supplied IP address, port, and
  166. # address family
  167. #
  168. def self.to_sockaddr(ip, port)
  169. if (ip == '::ffff:0.0.0.0')
  170. ip = support_ipv6?() ? '::' : '0.0.0.0'
  171. end
  172. return ::Socket.pack_sockaddr_in(port, ip)
  173. end
  174. #
  175. # Returns the address family, host, and port of the supplied sockaddr as
  176. # [ af, host, port ]
  177. #
  178. def self.from_sockaddr(saddr)
  179. port, host = ::Socket::unpack_sockaddr_in(saddr)
  180. af = ::Socket::AF_INET
  181. if (support_ipv6?() and is_ipv6?(host))
  182. af = ::Socket::AF_INET6
  183. end
  184. return [ af, host, port ]
  185. end
  186. #
  187. # Resolves a host to raw network-byte order.
  188. #
  189. def self.resolv_nbo(host)
  190. self.gethostbyname(Rex::Socket.getaddress(host))[3]
  191. end
  192. #
  193. # Resolves a host to a network-byte order ruby integer.
  194. #
  195. def self.resolv_nbo_i(host)
  196. addr_ntoi(resolv_nbo(host))
  197. end
  198. #
  199. # Converts an ASCII IP address to a CIDR mask. Returns
  200. # nil if it's not convertable.
  201. #
  202. def self.addr_atoc(mask)
  203. mask_i = resolv_nbo_i(mask)
  204. cidr = nil
  205. 0.upto(32) do |i|
  206. if ((1 << i)-1) << (32-i) == mask_i
  207. cidr = i
  208. break
  209. end
  210. end
  211. return cidr
  212. end
  213. #
  214. # Resolves a CIDR bitmask into a dotted-quad. Returns
  215. # nil if it's not convertable.
  216. #
  217. def self.addr_ctoa(cidr)
  218. return nil unless (0..32) === cidr.to_i
  219. addr_itoa(((1 << cidr)-1) << 32-cidr)
  220. end
  221. #
  222. # Resolves a host to a dotted address.
  223. #
  224. def self.resolv_to_dotted(host)
  225. addr_ntoa(addr_aton(host))
  226. end
  227. #
  228. # Converts a ascii address into an integer
  229. #
  230. def self.addr_atoi(addr)
  231. resolv_nbo_i(addr)
  232. end
  233. #
  234. # Converts an integer address into ascii
  235. #
  236. def self.addr_itoa(addr, v6=false)
  237. nboa = addr_iton(addr, v6)
  238. # IPv4
  239. if (addr < 0x100000000 and not v6)
  240. nboa.unpack('C4').join('.')
  241. # IPv6
  242. else
  243. nboa.unpack('n8').map{ |c| "%.4x" % c }.join(":")
  244. end
  245. end
  246. #
  247. # Converts a ascii address to network byte order
  248. #
  249. def self.addr_aton(addr)
  250. resolv_nbo(addr)
  251. end
  252. #
  253. # Converts a network byte order address to ascii
  254. #
  255. def self.addr_ntoa(addr)
  256. # IPv4
  257. if (addr.length == 4)
  258. return addr.unpack('C4').join('.')
  259. end
  260. # IPv6
  261. if (addr.length == 16)
  262. return addr.unpack('n8').map{ |c| "%.4x" % c }.join(":")
  263. end
  264. raise RuntimeError, "Invalid address format"
  265. end
  266. #
  267. # Converts a network byte order address to an integer
  268. #
  269. def self.addr_ntoi(addr)
  270. bits = addr.unpack("N*")
  271. if (bits.length == 1)
  272. return bits[0]
  273. end
  274. if (bits.length == 4)
  275. val = 0
  276. bits.each_index { |i| val += ( bits[i] << (96 - (i * 32)) ) }
  277. return val
  278. end
  279. raise RuntimeError, "Invalid address format"
  280. end
  281. #
  282. # Converts an integer into a network byte order address
  283. #
  284. def self.addr_iton(addr, v6=false)
  285. if(addr < 0x100000000 and not v6)
  286. return [addr].pack('N')
  287. else
  288. w = []
  289. w[0] = (addr >> 96) & 0xffffffff
  290. w[1] = (addr >> 64) & 0xffffffff
  291. w[2] = (addr >> 32) & 0xffffffff
  292. w[3] = addr & 0xffffffff
  293. return w.pack('N4')
  294. end
  295. end
  296. #
  297. # Converts a CIDR subnet into an array (base, bcast)
  298. #
  299. def self.cidr_crack(cidr, v6=false)
  300. tmp = cidr.split('/')
  301. tst,scope = tmp[0].split("%",2)
  302. scope = "%" + scope if scope
  303. scope ||= ""
  304. addr = addr_atoi(tst)
  305. bits = 32
  306. mask = 0
  307. use6 = false
  308. if (addr > 0xffffffff or v6 or cidr =~ /:/)
  309. use6 = true
  310. bits = 128
  311. end
  312. mask = (2 ** bits) - (2 ** (bits - tmp[1].to_i))
  313. base = addr & mask
  314. stop = base + (2 ** (bits - tmp[1].to_i)) - 1
  315. return [self.addr_itoa(base, use6) + scope, self.addr_itoa(stop, use6) + scope]
  316. end
  317. #
  318. # Converts a netmask (255.255.255.240) into a bitmask (28). This is the
  319. # lame kid way of doing it.
  320. #
  321. def self.net2bitmask(netmask)
  322. nmask = resolv_nbo(netmask)
  323. imask = addr_ntoi(nmask)
  324. bits = 32
  325. if (imask > 0xffffffff)
  326. bits = 128
  327. end
  328. 0.upto(bits-1) do |bit|
  329. p = 2 ** bit
  330. return (bits - bit) if ((imask & p) == p)
  331. end
  332. 0
  333. end
  334. #
  335. # Converts a bitmask (28) into a netmask (255.255.255.240)
  336. # TODO: IPv6 (use is ambiguous right now)
  337. #
  338. def self.bit2netmask(bitmask)
  339. [ (~((2 ** (32 - bitmask)) - 1)) & 0xffffffff ].pack('N').unpack('CCCC').join('.')
  340. end
  341. def self.portspec_crack(pspec)
  342. portspec_to_portlist(pspec)
  343. end
  344. #
  345. # Converts a port specification like "80,21-23,443" into a sorted,
  346. # unique array of valid port numbers like [21,22,23,80,443]
  347. #
  348. def self.portspec_to_portlist(pspec)
  349. ports = []
  350. # Build ports array from port specification
  351. pspec.split(/,/).each do |item|
  352. start, stop = item.split(/-/).map { |p| p.to_i }
  353. start ||= 0
  354. stop ||= item.match(/-/) ? 65535 : start
  355. start, stop = stop, start if stop < start
  356. start.upto(stop) { |p| ports << p }
  357. end
  358. # Sort, and remove dups and invalid ports
  359. ports.sort.uniq.delete_if { |p| p < 1 or p > 65535 }
  360. end
  361. #
  362. # Converts a port list like [1,2,3,4,5,100] into a
  363. # range specification like "1-5,100"
  364. #
  365. def self.portlist_to_portspec(parr)
  366. ranges = []
  367. range = []
  368. lastp = nil
  369. parr.uniq.sort{|a,b| a<=>b}.map{|a| a.to_i}.each do |n|
  370. next if (n < 1 or n > 65535)
  371. if not lastp
  372. range = [n]
  373. lastp = n
  374. next
  375. end
  376. if lastp == n - 1
  377. range << n
  378. else
  379. ranges << range
  380. range = [n]
  381. end
  382. lastp = n
  383. end
  384. ranges << range
  385. ranges.delete(nil)
  386. ranges.uniq.map{|x| x.length == 1 ? "#{x[0]}" : "#{x[0]}-#{x[-1]}"}.join(",")
  387. end
  388. ##
  389. #
  390. # Utility class methods
  391. #
  392. ##
  393. #
  394. # This method does NOT send any traffic to the destination, instead, it uses a
  395. # "bound" UDP socket to determine what source address we would use to
  396. # communicate with the specified destination. The destination defaults to
  397. # Google's DNS server to make the standard behavior determine which IP
  398. # we would use to communicate with the internet.
  399. #
  400. def self.source_address(dest='8.8.8.8', comm = ::Rex::Socket::Comm::Local)
  401. begin
  402. s = self.create_udp(
  403. 'PeerHost' => dest,
  404. 'PeerPort' => 31337,
  405. 'Comm' => comm
  406. )
  407. r = s.getsockname[1]
  408. s.close
  409. # Trim off the trailing interface ID for link-local IPv6
  410. return r.split('%').first
  411. rescue ::Exception
  412. return '127.0.0.1'
  413. end
  414. end
  415. #
  416. # Identifies the link-local address of a given interface (if IPv6 is enabled)
  417. #
  418. def self.ipv6_link_address(intf)
  419. r = source_address("FF02::1%#{intf}")
  420. return if not (r and r =~ /^fe80/i)
  421. r
  422. end
  423. #
  424. # Identifies the mac address of a given interface (if IPv6 is enabled)
  425. #
  426. def self.ipv6_mac(intf)
  427. r = ipv6_link_address(intf)
  428. return if not r
  429. raw = addr_aton(r)[-8, 8]
  430. (raw[0,3] + raw[5,3]).unpack("C*").map{|c| "%.2x" % c}.join(":")
  431. end
  432. #
  433. # Create a TCP socket pair.
  434. #
  435. # sf: This create a socket pair using native ruby sockets and will work
  436. # on Windows where ::Socket.pair is not implemented.
  437. # Note: OpenSSL requires native ruby sockets for its io.
  438. #
  439. # Note: Even though sub-threads are smashing the parent threads local, there
  440. # is no concurrent use of the same locals and this is safe.
  441. def self.tcp_socket_pair
  442. lsock = nil
  443. rsock = nil
  444. laddr = '127.0.0.1'
  445. lport = 0
  446. threads = []
  447. mutex = ::Mutex.new
  448. threads << Rex::ThreadFactory.spawn('TcpSocketPair', false) {
  449. server = nil
  450. mutex.synchronize {
  451. threads << Rex::ThreadFactory.spawn('TcpSocketPairClient', false) {
  452. mutex.synchronize {
  453. rsock = ::TCPSocket.new( laddr, lport )
  454. }
  455. }
  456. server = ::TCPServer.new(laddr, 0)
  457. if (server.getsockname =~ /127\.0\.0\.1:/)
  458. # JRuby ridiculousness
  459. caddr, lport = server.getsockname.split(":")
  460. caddr = caddr[1,caddr.length]
  461. lport = lport.to_i
  462. else
  463. # Sane implementations where Socket#getsockname returns a
  464. # sockaddr
  465. lport, caddr = ::Socket.unpack_sockaddr_in( server.getsockname )
  466. end
  467. }
  468. lsock, saddr = server.accept
  469. server.close
  470. }
  471. threads.each { |t| t.join }
  472. return [lsock, rsock]
  473. end
  474. #
  475. # Create a UDP socket pair using native ruby UDP sockets.
  476. #
  477. def self.udp_socket_pair
  478. laddr = '127.0.0.1'
  479. lsock = ::UDPSocket.new
  480. lsock.bind( laddr, 0 )
  481. rsock = ::UDPSocket.new
  482. rsock.bind( laddr, 0 )
  483. rsock.connect( *lsock.addr.values_at(3,1) )
  484. lsock.connect( *rsock.addr.values_at(3,1) )
  485. return [lsock, rsock]
  486. end
  487. ##
  488. #
  489. # Class initialization
  490. #
  491. ##
  492. #
  493. # Initialize general socket parameters.
  494. #
  495. def initsock(params = nil)
  496. if (params)
  497. self.peerhost = params.peerhost
  498. self.peerport = params.peerport
  499. self.localhost = params.localhost
  500. self.localport = params.localport
  501. self.context = params.context || {}
  502. self.ipv = params.v6 ? 6 : 4
  503. end
  504. end
  505. #
  506. # By default, all sockets are themselves selectable file descriptors.
  507. #
  508. def fd
  509. self
  510. end
  511. #
  512. # Returns local connection information.
  513. #
  514. def getsockname
  515. Socket.from_sockaddr(super)
  516. end
  517. #
  518. # Wrapper around getsockname
  519. #
  520. def getlocalname
  521. getsockname
  522. end
  523. #
  524. # Return peer connection information.
  525. #
  526. def getpeername
  527. return Socket.from_sockaddr(super)
  528. end
  529. #
  530. # Returns a string that indicates the type of the socket, such as 'tcp'.
  531. #
  532. def type?
  533. raise NotImplementedError, "Socket type is not supported."
  534. end
  535. #
  536. # The peer host of the connected socket.
  537. #
  538. attr_reader :peerhost
  539. #
  540. # The peer port of the connected socket.
  541. #
  542. attr_reader :peerport
  543. #
  544. # The local host of the connected socket.
  545. #
  546. attr_reader :localhost
  547. #
  548. # The local port of the connected socket.
  549. #
  550. attr_reader :localport
  551. #
  552. # The IP version of the socket
  553. #
  554. attr_reader :ipv
  555. #
  556. # Contextual information that describes the source and other
  557. # instance-specific attributes. This comes from the param.context
  558. # attribute.
  559. #
  560. attr_reader :context
  561. protected
  562. attr_writer :peerhost, :peerport, :localhost, :localport # :nodoc:
  563. attr_writer :context # :nodoc:
  564. attr_writer :ipv # :nodoc:
  565. end
  566. end
  567. #
  568. # Globalized socket constants
  569. #
  570. SHUT_RDWR = ::Socket::SHUT_RDWR
  571. SHUT_RD = ::Socket::SHUT_RD
  572. SHUT_WR = ::Socket::SHUT_WR