Skip to content

Commit 90117c3

Browse files
committed
Landing rapid7#1874 - Post API cleanup
2 parents e99401e + f3ff5b5 commit 90117c3

File tree

5 files changed

+315
-268
lines changed

5 files changed

+315
-268
lines changed

lib/msf/core/exploit.rb

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# -*- coding: binary -*-
22
require 'msf/core'
33
require 'msf/core/module'
4-
require 'msf/core/post'
54

65
module Msf
76

@@ -30,6 +29,8 @@ def on_exploit_success(exploit, session)
3029
###
3130
class Exploit < Msf::Module
3231

32+
require 'msf/core/post'
33+
require 'msf/core/exploit/local'
3334

3435
##
3536
# Exceptions
@@ -219,25 +220,6 @@ module Stance
219220
Passive = "passive"
220221
end
221222

222-
###
223-
#
224-
# The local exploit class is a specialization of the exploit module class that
225-
# is geared toward exploits that are performed locally. Locally, in this
226-
# case, is defined as an exploit that is realized by means other than network
227-
# communication.
228-
#
229-
###
230-
class Local < Exploit
231-
include PostMixin
232-
233-
#
234-
# Returns the fact that this exploit is a local exploit.
235-
#
236-
def exploit_type
237-
Exploit::Type::Local
238-
end
239-
end
240-
241223
###
242224
#
243225
# The remote exploit class is a specialization of the exploit module class
@@ -315,6 +297,7 @@ def abort_sockets
315297
# algorithm. It's just important that it returns an array of all of the
316298
# mixin modules.
317299
#
300+
# @return [Array]
318301
def self.mixins
319302
mixins = []
320303
wl = [ Msf::Exploit ]

lib/msf/core/exploit/local.rb

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
1+
# -*- coding: binary -*-
12

2-
require 'msf/core/exploit/local/unix'
3-
require 'msf/core/exploit/local/linux_kernel'
3+
require 'msf/core/post_mixin'
44

55
module Msf
6-
module Exploit::Local
6+
class Exploit
7+
8+
###
9+
#
10+
# A specialization of the {Exploit exploit module class} that is geared
11+
# toward exploits that are performed locally. Locally, in this case,
12+
# is defined as an exploit that is realized by means other than
13+
# network communication.
14+
#
15+
###
16+
class Local < Exploit
17+
include PostMixin
18+
19+
#
20+
# Returns the fact that this exploit is a local exploit.
21+
#
22+
def exploit_type
23+
Exploit::Type::Local
24+
end
25+
end
726

827
end
928
end

lib/msf/core/post.rb

Lines changed: 2 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -1,208 +1,8 @@
11
# -*- coding: binary -*-
2-
require 'msf/core'
3-
require 'msf/core/module'
42

5-
module Msf
6-
7-
#
8-
# A mixin used for providing Modules with post-exploitation options and helper methods
9-
#
10-
module PostMixin
11-
12-
include Msf::Auxiliary::Report
13-
14-
include Msf::Module::HasActions
15-
16-
def initialize(info={})
17-
super
18-
19-
register_options( [
20-
OptInt.new('SESSION', [ true, "The session to run this module on." ])
21-
] , Msf::Post)
22-
23-
# Default stance is active
24-
self.passive = (info['Passive'] and info['Passive'] == true) || false
25-
end
3+
require 'msf/core/post_mixin'
264

27-
#
28-
# Grabs a session object from the framework or raises OptionValidateError
29-
# if one doesn't exist. Initializes user input and output on the session.
30-
#
31-
def setup
32-
if not session
33-
raise Msf::OptionValidateError.new(["SESSION"])
34-
end
35-
36-
super
37-
38-
check_for_session_readiness() if session.type == "meterpreter"
39-
40-
@session.init_ui(self.user_input, self.user_output)
41-
@sysinfo = nil
42-
end
43-
44-
# Meterpreter sometimes needs a little bit of extra time to
45-
# actually be responsive for post modules. Default tries
46-
# and retries for 5 seconds.
47-
def check_for_session_readiness(tries=6)
48-
session_ready_count = 0
49-
session_ready = false
50-
until session.sys or session_ready_count > tries
51-
session_ready_count += 1
52-
back_off_period = (session_ready_count**2)/10.0
53-
select(nil,nil,nil,back_off_period)
54-
end
55-
session_ready = !!session.sys
56-
raise "Could not get a hold of the session." unless session_ready
57-
return session_ready
58-
end
59-
60-
#
61-
# Default cleanup handler does nothing
62-
#
63-
def cleanup
64-
end
65-
66-
#
67-
# Return the associated session or nil if there isn't one
68-
#
69-
def session
70-
# Try the cached one
71-
return @session if @session and not session_changed?
72-
73-
if datastore["SESSION"]
74-
@session = framework.sessions[datastore["SESSION"].to_i]
75-
else
76-
@session = nil
77-
end
78-
79-
@session
80-
end
81-
82-
alias :client :session
83-
84-
#
85-
# Cached sysinfo, returns nil for non-meterpreter sessions
86-
#
87-
def sysinfo
88-
begin
89-
@sysinfo ||= session.sys.config.sysinfo
90-
rescue NoMethodError
91-
@sysinfo = nil
92-
end
93-
@sysinfo
94-
end
95-
96-
#
97-
# Can be overridden by individual modules to add new commands
98-
#
99-
def post_commands
100-
{}
101-
end
102-
103-
def passive?
104-
self.passive
105-
end
106-
107-
#
108-
# Return a (possibly empty) list of all compatible sessions
109-
#
110-
def compatible_sessions
111-
sessions = []
112-
framework.sessions.each do |sid, s|
113-
sessions << sid if session_compatible?(s)
114-
end
115-
sessions
116-
end
117-
118-
119-
#
120-
# Return false if the given session is not compatible with this module
121-
#
122-
# Checks the session's type against this module's
123-
# +module_info["SessionTypes"]+ as well as examining platform
124-
# compatibility. +sess_or_sid+ can be a Session object, Fixnum, or String.
125-
# In the latter cases it sould be a key in in +framework.sessions+.
126-
#
127-
# NOTE: because it errs on the side of compatibility, a true return value
128-
# from this method does not guarantee the module will work with the
129-
# session.
130-
#
131-
def session_compatible?(sess_or_sid)
132-
# Normalize the argument to an actual Session
133-
case sess_or_sid
134-
when ::Fixnum, ::String
135-
s = framework.sessions[sess_or_sid.to_i]
136-
when ::Msf::Session
137-
s = sess_or_sid
138-
end
139-
140-
# Can't do anything without a session
141-
return false if s.nil?
142-
143-
# Can't be compatible if it's the wrong type
144-
if self.module_info["SessionTypes"]
145-
return false unless self.module_info["SessionTypes"].include?(s.type)
146-
end
147-
148-
# XXX: Special-case java and php for now. This sucks and Session
149-
# should have a method to auto-detect the underlying platform of
150-
# platform-independent sessions such as these.
151-
plat = s.platform
152-
if plat =~ /php|java/ and sysinfo and sysinfo["OS"]
153-
plat = sysinfo["OS"]
154-
end
155-
156-
# Types are okay, now check the platform. This is kind of a ghetto
157-
# workaround for session platforms being ad-hoc and Platform being
158-
# inflexible.
159-
if self.platform and self.platform.kind_of?(Msf::Module::PlatformList)
160-
[
161-
# Add as necessary
162-
"win", "linux", "osx"
163-
].each do |name|
164-
if plat =~ /#{name}/
165-
p = Msf::Module::PlatformList.transform(name)
166-
return false unless self.platform.supports? p
167-
end
168-
end
169-
elsif self.platform and self.platform.kind_of?(Msf::Module::Platform)
170-
p_klass = Msf::Module::Platform
171-
case plat.downcase
172-
when /win/
173-
return false unless self.platform.kind_of?(p_klass::Windows)
174-
when /osx/
175-
return false unless self.platform.kind_of?(p_klass::OSX)
176-
when /linux/
177-
return false unless self.platform.kind_of?(p_klass::Linux)
178-
end
179-
end
180-
181-
# If we got here, we haven't found anything that definitely
182-
# disqualifies this session. Assume that means we can use it.
183-
return true
184-
end
185-
186-
#
187-
# True when this module is passive, false when active
188-
#
189-
attr_reader :passive
190-
191-
protected
192-
193-
attr_writer :passive
194-
195-
def session_changed?
196-
@ds_session ||= datastore["SESSION"]
197-
198-
if (@ds_session != datastore["SESSION"])
199-
@ds_session = nil
200-
return true
201-
else
202-
return false
203-
end
204-
end
205-
end
5+
module Msf
2066

2077
#
2088
# A Post-exploitation module

0 commit comments

Comments
 (0)