PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/rex/socket/comm/local.rb

https://bitbucket.org/jrossi/metasploit
Ruby | 412 lines | 295 code | 70 blank | 47 comment | 67 complexity | f55853b729e3afd41f7b896d0494249c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. require 'singleton'
  2. require 'rex/socket'
  3. require 'rex/socket/tcp'
  4. require 'rex/socket/ssl_tcp'
  5. require 'rex/socket/ssl_tcp_server'
  6. require 'rex/socket/udp'
  7. require 'rex/socket/ip'
  8. require 'timeout'
  9. ###
  10. #
  11. # Local communication class factory.
  12. #
  13. ###
  14. class Rex::Socket::Comm::Local
  15. include Singleton
  16. include Rex::Socket::Comm
  17. #
  18. # Creates an instance of a socket using the supplied parameters.
  19. #
  20. def self.create(param)
  21. # Work around jRuby socket implementation issues
  22. if(RUBY_PLATFORM == 'java')
  23. return self.create_jruby(param)
  24. end
  25. case param.proto
  26. when 'tcp'
  27. return create_by_type(param, ::Socket::SOCK_STREAM, ::Socket::IPPROTO_TCP)
  28. when 'udp'
  29. return create_by_type(param, ::Socket::SOCK_DGRAM, ::Socket::IPPROTO_UDP)
  30. when 'ip'
  31. return create_ip(param)
  32. else
  33. raise Rex::UnsupportedProtocol.new(param.proto), caller
  34. end
  35. end
  36. #
  37. # Creates an instance of a socket using the supplied parameters.
  38. # Use various hacks to make this work with jRuby
  39. #
  40. def self.create_jruby(param)
  41. sock = nil
  42. # Notify handlers of the before socket create event.
  43. self.instance.notify_before_socket_create(self, param)
  44. case param.proto
  45. when 'tcp'
  46. if (param.server?)
  47. sock = TCPServer.new(param.localport, param.localhost)
  48. klass = Rex::Socket::TcpServer
  49. if (param.ssl)
  50. klass = Rex::Socket::SslTcpServer
  51. end
  52. sock.extend(klass)
  53. else
  54. sock = TCPSocket.new(param.peerhost, param.peerport)
  55. klass = Rex::Socket::Tcp
  56. if (param.ssl)
  57. klass = Rex::Socket::SslTcp
  58. end
  59. sock.extend(klass)
  60. end
  61. when 'udp'
  62. if (param.server?)
  63. sock = UDPServer.new(param.localport, param.localhost)
  64. klass = Rex::Socket::UdpServer
  65. sock.extend(klass)
  66. else
  67. sock = UDPSocket.new(param.peerhost, param.peerport)
  68. klass = Rex::Socket::Udp
  69. sock.extend(klass)
  70. end
  71. else
  72. raise Rex::UnsupportedProtocol.new(param.proto), caller
  73. end
  74. sock.initsock(param)
  75. self.instance.notify_socket_created(self, sock, param)
  76. return sock
  77. end
  78. #
  79. # Creates a raw IP socket using the supplied Parameter instance.
  80. # Special-cased because of how different it is from UDP/TCP
  81. #
  82. def self.create_ip(param)
  83. self.instance.notify_before_socket_create(self, param)
  84. sock = ::Socket.open(::Socket::PF_INET, ::Socket::SOCK_RAW, ::Socket::IPPROTO_RAW)
  85. sock.setsockopt(::Socket::IPPROTO_IP, ::Socket::IP_HDRINCL, 1)
  86. # Configure broadcast support
  87. sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_BROADCAST, true)
  88. if (param.bare? == false)
  89. sock.extend(::Rex::Socket::Ip)
  90. sock.initsock(param)
  91. end
  92. self.instance.notify_socket_created(self, sock, param)
  93. sock
  94. end
  95. #
  96. # Creates a socket using the supplied Parameter instance.
  97. #
  98. def self.create_by_type(param, type, proto = 0)
  99. # Whether to use IPv6 addressing
  100. usev6 = false
  101. # Detect IPv6 addresses and enable IPv6 accordingly
  102. if ( Rex::Socket.support_ipv6?())
  103. # Allow the caller to force IPv6
  104. if (param.v6)
  105. usev6 = true
  106. end
  107. # Force IPv6 mode for non-connected UDP sockets
  108. if (type == ::Socket::SOCK_DGRAM and not param.peerhost)
  109. # FreeBSD allows IPv6 socket creation, but throws an error on sendto()
  110. if (not Rex::Compat.is_freebsd())
  111. usev6 = true
  112. end
  113. end
  114. local = Rex::Socket.resolv_nbo(param.localhost) if param.localhost
  115. peer = Rex::Socket.resolv_nbo(param.peerhost) if param.peerhost
  116. if (local and local.length == 16)
  117. usev6 = true
  118. end
  119. if (peer and peer.length == 16)
  120. usev6 = true
  121. end
  122. if (usev6)
  123. if (local and local.length == 4)
  124. if (local == "\x00\x00\x00\x00")
  125. param.localhost = '::'
  126. elsif (local == "\x7f\x00\x00\x01")
  127. param.localhost = '::1'
  128. else
  129. param.localhost = '::ffff:' + Rex::Socket.getaddress(param.localhost)
  130. end
  131. end
  132. if (peer and peer.length == 4)
  133. if (peer == "\x00\x00\x00\x00")
  134. param.peerhost = '::'
  135. elsif (peer == "\x7f\x00\x00\x01")
  136. param.peerhost = '::1'
  137. else
  138. param.peerhost = '::ffff:' + Rex::Socket.getaddress(param.peerhost)
  139. end
  140. end
  141. param.v6 = true
  142. end
  143. else
  144. # No IPv6 support
  145. param.v6 = false
  146. end
  147. # Notify handlers of the before socket create event.
  148. self.instance.notify_before_socket_create(self, param)
  149. # Create the socket
  150. sock = nil
  151. if (param.v6)
  152. sock = ::Socket.new(::Socket::AF_INET6, type, proto)
  153. else
  154. sock = ::Socket.new(::Socket::AF_INET, type, proto)
  155. end
  156. # Bind to a given local address and/or port if they are supplied
  157. if (param.localhost || param.localport)
  158. begin
  159. sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, true)
  160. sock.bind(Rex::Socket.to_sockaddr(param.localhost, param.localport))
  161. rescue ::Errno::EADDRNOTAVAIL,::Errno::EADDRINUSE
  162. sock.close
  163. raise Rex::AddressInUse.new(param.localhost, param.localport), caller
  164. end
  165. end
  166. # Configure broadcast support for all datagram sockets
  167. if (type == ::Socket::SOCK_DGRAM)
  168. sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_BROADCAST, true)
  169. end
  170. # If a server TCP instance is being created...
  171. if (param.server?)
  172. sock.listen(128)
  173. if (param.bare? == false)
  174. klass = Rex::Socket::TcpServer
  175. if (param.ssl)
  176. klass = Rex::Socket::SslTcpServer
  177. end
  178. sock.extend(klass)
  179. sock.initsock(param)
  180. end
  181. # Otherwise, if we're creating a client...
  182. else
  183. chain = []
  184. # If we were supplied with host information
  185. if (param.peerhost)
  186. begin
  187. ip = param.peerhost
  188. port = param.peerport
  189. if param.proxies
  190. chain = param.proxies.dup
  191. chain.push(['host',param.peerhost,param.peerport])
  192. ip = chain[0][1]
  193. port = chain[0][2].to_i
  194. end
  195. begin
  196. Timeout.timeout(param.timeout) do
  197. sock.connect(Rex::Socket.to_sockaddr(ip, port))
  198. end
  199. rescue ::Timeout::Error
  200. raise ::Errno::ETIMEDOUT
  201. end
  202. rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL
  203. sock.close
  204. raise Rex::HostUnreachable.new(param.peerhost, param.peerport), caller
  205. rescue ::Errno::EADDRNOTAVAIL,::Errno::EADDRINUSE
  206. sock.close
  207. raise Rex::AddressInUse.new(param.peerhost, param.peerport), caller
  208. rescue Errno::ETIMEDOUT
  209. sock.close
  210. raise Rex::ConnectionTimeout.new(param.peerhost, param.peerport), caller
  211. rescue ::Errno::ECONNRESET,::Errno::ECONNREFUSED,::Errno::ENOTCONN,::Errno::ECONNABORTED
  212. sock.close
  213. raise Rex::ConnectionRefused.new(param.peerhost, param.peerport), caller
  214. end
  215. end
  216. if (param.bare? == false)
  217. case param.proto
  218. when 'tcp'
  219. klass = Rex::Socket::Tcp
  220. sock.extend(klass)
  221. sock.initsock(param)
  222. when 'udp'
  223. sock.extend(Rex::Socket::Udp)
  224. sock.initsock(param)
  225. end
  226. end
  227. if chain.size > 1
  228. chain.each_with_index {
  229. |proxy, i|
  230. next_hop = chain[i + 1]
  231. if next_hop
  232. proxy(sock, proxy[0], next_hop[1], next_hop[2])
  233. end
  234. }
  235. end
  236. # Now extend the socket with SSL and perform the handshake
  237. if(param.bare? == false and param.ssl)
  238. klass = Rex::Socket::SslTcp
  239. sock.extend(klass)
  240. sock.initsock(param)
  241. end
  242. end
  243. # Notify handlers that a socket has been created.
  244. self.instance.notify_socket_created(self, sock, param)
  245. sock
  246. end
  247. def self.proxy(sock, type, host, port)
  248. #$stdout.print("PROXY\n")
  249. case type.downcase
  250. when 'http'
  251. setup = "CONNECT #{host}:#{port} HTTP/1.0\r\n\r\n"
  252. size = sock.put(setup)
  253. if (size != setup.length)
  254. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to send the entire request to the proxy"), caller
  255. end
  256. begin
  257. ret = sock.get_once(39,30)
  258. rescue IOError
  259. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to receive a response from the proxy"), caller
  260. end
  261. if ret.nil?
  262. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to receive a response from the proxy"), caller
  263. end
  264. resp = Rex::Proto::Http::Response.new
  265. resp.update_cmd_parts(ret.split(/\r?\n/)[0])
  266. if resp.code != 200
  267. raise Rex::ConnectionProxyError.new(host, port, type, "The proxy returned a non-OK response"), caller
  268. end
  269. when 'socks4'
  270. setup = [4,1,port.to_i].pack('CCn') + Socket.gethostbyname(host)[3] + Rex::Text.rand_text_alpha(rand(8)+1) + "\x00"
  271. size = sock.put(setup)
  272. if (size != setup.length)
  273. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to send the entire request to the proxy"), caller
  274. end
  275. begin
  276. ret = sock.get_once(8, 30)
  277. rescue IOError
  278. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to receive a response from the proxy"), caller
  279. end
  280. if (ret.nil? or ret.length < 8)
  281. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to receive a complete response from the proxy"), caller
  282. end
  283. if ret[1,1] != "\x5a"
  284. raise Rex::ConnectionProxyError.new(host, port, type, "Proxy responded with error code #{ret[0,1].unpack("C")[0]}"), caller
  285. end
  286. when 'socks5'
  287. auth_methods = [5,1,0].pack('CCC')
  288. size = sock.put(auth_methods)
  289. if (size != auth_methods.length)
  290. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to send the entire request to the proxy"), caller
  291. end
  292. ret = sock.get_once(2,30)
  293. if (ret[1,1] == "\xff")
  294. raise Rex::ConnectionProxyError.new(host, port, type, "The proxy requires authentication"), caller
  295. end
  296. if (Rex::Socket.is_ipv4?(host))
  297. addr = Rex::Socket.gethostbyname(host)[3]
  298. setup = [5,1,0,1].pack('C4') + addr + [port.to_i].pack('n')
  299. elsif (Rex::Socket.support_ipv6? and Rex::Socket.is_ipv6?(host))
  300. # IPv6 stuff all untested
  301. addr = Rex::Socket.gethostbyname(host)[3]
  302. setup = [5,1,0,4].pack('C4') + addr + [port.to_i].pack('n')
  303. else
  304. # Then it must be a domain name.
  305. # Unfortunately, it looks like the host has always been
  306. # resolved by the time it gets here, so this code never runs.
  307. setup = [5,1,0,3].pack('C4') + [host.length].pack('C') + host + [port.to_i].pack('n')
  308. end
  309. size = sock.put(setup)
  310. if (size != setup.length)
  311. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to send the entire request to the proxy"), caller
  312. end
  313. begin
  314. response = sock.get_once(10, 30)
  315. rescue IOError
  316. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to receive a response from the proxy"), caller
  317. end
  318. if (response.nil? or response.length < 10)
  319. raise Rex::ConnectionProxyError.new(host, port, type, "Failed to receive a complete response from the proxy"), caller
  320. end
  321. if response[1,1] != "\x00"
  322. raise Rex::ConnectionProxyError.new(host, port, type, "Proxy responded with error code #{response[1,1].unpack("C")[0]}"), caller
  323. end
  324. else
  325. raise RuntimeError, "The proxy type specified is not valid", caller
  326. end
  327. end
  328. ##
  329. #
  330. # Registration
  331. #
  332. ##
  333. def self.register_event_handler(handler) # :nodoc:
  334. self.instance.register_event_handler(handler)
  335. end
  336. def self.deregister_event_handler(handler) # :nodoc:
  337. self.instance.deregister_event_handler(handler)
  338. end
  339. def self.each_event_handler(handler) # :nodoc:
  340. self.instance.each_event_handler(handler)
  341. end
  342. end