Class: Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb

Overview

The Railgun class to dynamically expose the Windows API.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ Railgun

Returns a new instance of Railgun.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 50

def initialize( client )

	@client = client
	@dll    = ::Hash.new
	
	@win_consts = WinConstManager.new()
	
	@constants_loaded = false

	# Load the multi-caller
	@multicaller = MultiCaller.new( @client, self, @win_consts )

	# Load utility class
	@util = Util.new( self, @client.platform )
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(dll_symbol, *args) ⇒ Object

we fake having members like user32 and kernel32. reason is that

...user32.MessageBoxW()

is prettier than

...dlls["user32"].functions["MessageBoxW"]()


175
176
177
178
179
180
181
182
183
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 175

def method_missing(dll_symbol, *args)
	dll_name = dll_symbol.to_s

	self.get_dll( dll_name )
	
	raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(@dll.keys, "")}" unless @dll.has_key? dll_name
	
	return @dll[dll_name]
end

Instance Attribute Details

#clientObject

Returns the value of attribute client.



200
201
202
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 200

def client
  @client
end

#dllObject

Returns the value of attribute dll.



200
201
202
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 200

def dll
  @dll
end

#multicallerObject

Returns the value of attribute multicaller.



200
201
202
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 200

def multicaller
  @multicaller
end

#utilObject

Returns the value of attribute util.



200
201
202
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 200

def util
  @util
end

#win_constsObject

Returns the value of attribute win_consts.



200
201
202
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 200

def win_consts
  @win_consts
end

Instance Method Details

#add_dll(dll_name, windows_name = nil) ⇒ Object

adds a function to an existing DLL-definition you can override the dll name if you want to include a path or the DLL name contains non-ruby-approved characters



112
113
114
115
116
117
118
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 112

def add_dll(dll_name, windows_name=nil)
	raise "DLL #{dll_name} already exists. Existing DLLs: #{PP.pp(@dll.keys, "")}" unless not @dll.has_key? dll_name
	if( windows_name == nil )
		windows_name = dll_name
	end
	@dll[dll_name] = DLL.new(windows_name, @client, @win_consts)
end

#add_function(dll_name, function_name, return_type, params, windows_name = nil) ⇒ Object

adds a function to an existing DLL-definition



104
105
106
107
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 104

def add_function(dll_name, function_name, return_type, params, windows_name=nil)
	raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(@dll.keys, "")}" unless @dll.has_key? dll_name
	@dll[dll_name].add_function(function_name, return_type, params, windows_name)
end

#const(str) ⇒ Object

Give the programmer access to constants



186
187
188
189
190
191
192
193
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 186

def const(str)
	# the constants are also lazy loaded the first time we call const() or any API function...
	if( not @constants_loaded )
		ApiConstants.add_constants( @win_consts )
		@constants_loaded = true
	end
	return @win_consts.parse(str)
end

#get_dll(dll_name) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 120

def get_dll( dll_name )
	# sf: we now lazy load the module definitions as needed to avoid the performance hit
	#     to stdapi if we do it upon initilization (the user may never use railgun or else
	#     require only a portion of the modules exposed by railgun so no need to pre load them)
	if( not @dll.has_key?( dll_name ) )
	
		# the constants are also lazy loaded the first time we call const() or any API function...
		if( not @constants_loaded )
			ApiConstants.add_constants( @win_consts )
			@constants_loaded = true
		end

		case dll_name
			when 'kernel32'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32'
				Def::Def_kernel32.add_imports(self)
			when 'ntdll'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll'
				Def::Def_ntdll.add_imports(self)
			when 'user32'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32'
				Def::Def_user32.add_imports(self)
			when 'ws2_32'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32'
				Def::Def_ws2_32.add_imports(self)
			when 'iphlpapi'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi'
				Def::Def_iphlpapi.add_imports(self)
			when 'netapi32'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32'
				Def::Def_netapi32.add_imports(self)
			when 'advapi32'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32'
				Def::Def_advapi32.add_imports(self)
			when 'shell32'
				require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32'
				Def::Def_shell32.add_imports(self)
		end
		
		if( @dll.has_key?( dll_name ) )
			return @dll[dll_name]
		end
		
	else
		return @dll[dll_name]
	end
	
	return nil
end

#memread(address, length) ⇒ Object

read data from a memory address on the host (useful for working with LPVOID parameters)



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 67

def memread( address, length )

	raise "Invalid parameters." if( not address or not length )
	
	request = Packet.create_request( 'stdapi_railgun_memread' )
	
	request.add_tlv( TLV_TYPE_RAILGUN_MEM_ADDRESS, address )
	request.add_tlv( TLV_TYPE_RAILGUN_MEM_LENGTH, length )

	response = client.send_request( request )
	if( response.result == 0 )
		return response.get_tlv_value( TLV_TYPE_RAILGUN_MEM_DATA )
	end
	
	return nil
end

#memwrite(address, data, length) ⇒ Object

write data to a memory address on the host (useful for working with LPVOID parameters)



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 85

def memwrite( address, data, length )

	raise "Invalid parameters." if( not address or not data or not length )
	
	request = Packet.create_request( 'stdapi_railgun_memwrite' )
	
	request.add_tlv( TLV_TYPE_RAILGUN_MEM_ADDRESS, address )
	request.add_tlv( TLV_TYPE_RAILGUN_MEM_DATA, data )
	request.add_tlv( TLV_TYPE_RAILGUN_MEM_LENGTH, length )

	response = client.send_request( request )
	if( response.result == 0 )
		return true
	end
	
	return false
end

#multi(functions) ⇒ Object

The multi-call shorthand ( [“kernel32”, “ExitProcess”, [0]] )



196
197
198
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb', line 196

def multi(functions)
	@multicaller.call(functions)
end