ronin-post_ex 0.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.document +6 -0
  3. data/.github/workflows/ruby.yml +31 -0
  4. data/.gitignore +13 -0
  5. data/.rspec +1 -0
  6. data/.ruby-version +1 -0
  7. data/.yardopts +1 -0
  8. data/API_SPEC.md +235 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +23 -0
  11. data/Gemfile +36 -0
  12. data/README.md +245 -0
  13. data/Rakefile +34 -0
  14. data/examples/bind_shell.rb +19 -0
  15. data/gemspec.yml +25 -0
  16. data/lib/ronin/post_ex/cli/shell_shell.rb +66 -0
  17. data/lib/ronin/post_ex/cli/system_shell.rb +811 -0
  18. data/lib/ronin/post_ex/remote_dir.rb +190 -0
  19. data/lib/ronin/post_ex/remote_file/stat.rb +174 -0
  20. data/lib/ronin/post_ex/remote_file.rb +417 -0
  21. data/lib/ronin/post_ex/remote_process.rb +170 -0
  22. data/lib/ronin/post_ex/resource.rb +144 -0
  23. data/lib/ronin/post_ex/sessions/bind_shell.rb +60 -0
  24. data/lib/ronin/post_ex/sessions/remote_shell_session.rb +48 -0
  25. data/lib/ronin/post_ex/sessions/reverse_shell.rb +67 -0
  26. data/lib/ronin/post_ex/sessions/rpc_session.rb +779 -0
  27. data/lib/ronin/post_ex/sessions/session.rb +73 -0
  28. data/lib/ronin/post_ex/sessions/shell_session.rb +618 -0
  29. data/lib/ronin/post_ex/system/fs.rb +650 -0
  30. data/lib/ronin/post_ex/system/process.rb +422 -0
  31. data/lib/ronin/post_ex/system/shell.rb +1037 -0
  32. data/lib/ronin/post_ex/system.rb +191 -0
  33. data/lib/ronin/post_ex/version.rb +26 -0
  34. data/lib/ronin/post_ex.rb +22 -0
  35. data/ronin-post_ex.gemspec +61 -0
  36. data/spec/sessions/bind_shell_spec.rb +31 -0
  37. data/spec/sessions/remote_shell_session_spec.rb +28 -0
  38. data/spec/sessions/reverse_shell_spec.rb +49 -0
  39. data/spec/sessions/rpc_session_spec.rb +500 -0
  40. data/spec/sessions/session_spec.rb +61 -0
  41. data/spec/sessions/shell_session_spec.rb +482 -0
  42. data/spec/spec_helper.rb +9 -0
  43. data/spec/system_spec.rb +66 -0
  44. metadata +155 -0
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-post_ex - a Ruby API for Post-Exploitation.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-post_ex is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-post_ex is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-post_ex. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ module Ronin
22
+ module PostEx
23
+ #
24
+ # A base-class for all post-exploitation resources.
25
+ #
26
+ class Resource
27
+
28
+ # The object providing control of the resource.
29
+ #
30
+ # @return [Sessions::Session]
31
+ attr_reader :session
32
+
33
+ #
34
+ # Creates a new Resource.
35
+ #
36
+ # @param [Object] session
37
+ # The object controlling the Resource.
38
+ #
39
+ def initialize(session)
40
+ @session = session
41
+ end
42
+
43
+ #
44
+ # Determines whether the {#session} object supports the resource's
45
+ # method(s).
46
+ #
47
+ # @param [Array<Symbol>] method_names
48
+ # The name of the Resource method.
49
+ #
50
+ # @return [Boolean]
51
+ # Specifies whether the {#session} object supports the method.
52
+ #
53
+ # @example
54
+ # fs.supports?(:read, :write)
55
+ # # => true
56
+ #
57
+ # @api public
58
+ #
59
+ def supports?(*method_names)
60
+ method_names.all? do |method_name|
61
+ method_name = method_name.to_sym
62
+ session_methods = self.class.resource_methods[method_name]
63
+
64
+ session_methods && session_methods.all? { |session_method|
65
+ @session.respond_to?(session_method)
66
+ }
67
+ end
68
+ end
69
+
70
+ #
71
+ # Determines which Resource methods are supported by the controlling
72
+ # object.
73
+ #
74
+ # @return [Array<Symbol>]
75
+ # The names of the supported Resource methods.
76
+ #
77
+ def supports
78
+ self.class.resource_methods.keys.select do |method_name|
79
+ supports?(method_name)
80
+ end
81
+ end
82
+
83
+ #
84
+ # Allows resources to spawn interactive consoles.
85
+ #
86
+ # @abstract
87
+ #
88
+ def interact
89
+ raise(NotImplementedError,"#{self.class} does not provide a console")
90
+ end
91
+
92
+ private
93
+
94
+ #
95
+ # The defined Resource methods.
96
+ #
97
+ # @return [Hash{Symbol => Array<Symbol>}]
98
+ # The names of the Resource methods and their required API methods.
99
+ #
100
+ # @api semipublic
101
+ #
102
+ def self.resource_methods
103
+ @resource_methods ||= {}
104
+ end
105
+
106
+ #
107
+ # Specifies that a Resource method requires certain methods define by the
108
+ # {#session} object.
109
+ #
110
+ # @param [Symbol] method_name
111
+ # The name of the Resource method.
112
+ #
113
+ # @param [Array<Symbol>] control_methods
114
+ # The methods that must be defined by the {#session} object.
115
+ #
116
+ # @api semipublic
117
+ #
118
+ def self.resource_method(method_name,control_methods=[])
119
+ resource_methods[method_name.to_sym] = control_methods.map(&:to_sym)
120
+ end
121
+
122
+ #
123
+ # Requires that the controlling object define the given method.
124
+ #
125
+ # @param [Symbol] name
126
+ # The name of the method that is required.
127
+ #
128
+ # @return [true]
129
+ # The method is defined.
130
+ #
131
+ # @raise [NotImplementedError]
132
+ # The method is not defined by the controlling object.
133
+ #
134
+ def requires_method!(name)
135
+ unless @session.respond_to?(name)
136
+ raise(NotImplementedError,"#{@session.inspect} does not define #{name}")
137
+ end
138
+
139
+ return true
140
+ end
141
+
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-post_ex - a Ruby API for Post-Exploitation.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-post_ex is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-post_ex is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-post_ex. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/post_ex/sessions/remote_shell_session'
22
+
23
+ require 'socket'
24
+
25
+ module Ronin
26
+ module PostEx
27
+ module Sessions
28
+ #
29
+ # Session class for interacting with bind shells.
30
+ #
31
+ # ## Examples
32
+ #
33
+ # session = Ronin::PostEx::Sessions::BindShell.connect(host,port)
34
+ # system = session.system
35
+ #
36
+ # system.shell.ls('/')
37
+ # # => "..."
38
+ #
39
+ class BindShell < RemoteShellSession
40
+
41
+ #
42
+ # Connects to a remote bind shell.
43
+ #
44
+ # @param [String] host
45
+ # The host to connect to.
46
+ #
47
+ # @param [Integer] port
48
+ # The port to connect to.
49
+ #
50
+ # @return [BindShell]
51
+ # The new bind shell session.
52
+ #
53
+ def self.connect(host,port)
54
+ new(TCPSocket.new(host,port))
55
+ end
56
+
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-post_ex - a Ruby API for Post-Exploitation.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-post_ex is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-post_ex is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-post_ex. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/post_ex/sessions/shell_session'
22
+
23
+ module Ronin
24
+ module PostEx
25
+ module Sessions
26
+ #
27
+ # Session base class for all other remote shell sessions.
28
+ #
29
+ class RemoteShellSession < ShellSession
30
+
31
+ #
32
+ # Initializes the remote shell session.
33
+ #
34
+ # @param [TCPSocket, UDPSocket] socket
35
+ # The underlying socket for the remote shell session.
36
+ #
37
+ def initialize(socket)
38
+ super(socket)
39
+
40
+ addrinfo = socket.remote_address
41
+
42
+ @name = "#{addrinfo.ip_address}:#{addrinfo.ip_port}"
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-post_ex - a Ruby API for Post-Exploitation.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-post_ex is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-post_ex is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-post_ex. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/post_ex/sessions/remote_shell_session'
22
+
23
+ require 'socket'
24
+
25
+ module Ronin
26
+ module PostEx
27
+ module Sessions
28
+ #
29
+ # Session class for interacting with reverse shells.
30
+ #
31
+ # ## Examples
32
+ #
33
+ # session = Ronin::PostEx::Sessions::ReverseShell.listen(host,port)
34
+ # system = session.system
35
+ #
36
+ # system.shell.ls('/')
37
+ # # => "..."
38
+ #
39
+ class ReverseShell < RemoteShellSession
40
+
41
+ #
42
+ # Listens for and accepts a reverse shell connection.
43
+ #
44
+ # @param [String, nil] host
45
+ # The host to connect to.
46
+ #
47
+ # @param [Integer] port
48
+ # The port to connect to.
49
+ #
50
+ # @return [ReverseShell]
51
+ # The new reverse shell session.
52
+ #
53
+ def self.listen(host=nil,port)
54
+ server_socket = TCPServer.new(port,host)
55
+ server_socket.listen(1)
56
+
57
+ begin
58
+ new(server_socket.accept)
59
+ ensure
60
+ server_socket.close
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end