Support platform specific railgun constants
parent
daf8833174
commit
9c60c3ee46
|
@ -23,6 +23,8 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'thread'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
|
@ -31,9 +33,53 @@ module Stdapi
|
|||
module Railgun
|
||||
|
||||
#
|
||||
# Manages our library of windows constants
|
||||
# A container holding useful API Constants.
|
||||
#
|
||||
class WinConstManager
|
||||
class ApiConstants
|
||||
|
||||
# This will be lazily loaded in self.manager
|
||||
@manager = nil
|
||||
|
||||
# Mutex to ensure we don't add constants more than once via thread races.
|
||||
@manager_semaphore = Mutex.new
|
||||
|
||||
class << self
|
||||
attr_accessor :manager_semaphore
|
||||
end
|
||||
|
||||
def self.inherited(child_class)
|
||||
child_class.manager_semaphore = Mutex.new
|
||||
end
|
||||
|
||||
#
|
||||
# Provides a frozen constant manager for the constants defined in
|
||||
# self.add_constants
|
||||
#
|
||||
def self.manager
|
||||
|
||||
# The first check for nil is to potentially skip the need to synchronize
|
||||
if @manager.nil?
|
||||
# Looks like we MAY need to load manager
|
||||
@manager_semaphore.synchronize do
|
||||
# We check once more. Now our options are synchronized
|
||||
if @manager.nil?
|
||||
@manager = ConstManager.new
|
||||
|
||||
self.add_constants(@manager)
|
||||
|
||||
@manager.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return @manager
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Manages our library of constants
|
||||
#
|
||||
class ConstManager
|
||||
attr_reader :consts
|
||||
|
||||
def initialize(initial_consts = {})
|
||||
|
@ -72,14 +118,14 @@ class WinConstManager
|
|||
end
|
||||
|
||||
#
|
||||
# Returns an array of constant names that have a value matching "winconst"
|
||||
# Returns an array of constant names that have a value matching "const"
|
||||
# and (optionally) a name that matches "filter_regex"
|
||||
#
|
||||
def select_const_names(winconst, filter_regex=nil)
|
||||
def select_const_names(const, filter_regex=nil)
|
||||
matches = []
|
||||
|
||||
consts.each_pair do |name, value|
|
||||
matches << name if value == winconst
|
||||
matches << name if value == const
|
||||
end
|
||||
|
||||
# Filter matches by name if a filter has been provided
|
|
@ -1,6 +1,5 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager'
|
||||
require 'thread'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/const_manager'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
|
@ -8,41 +7,12 @@ module Meterpreter
|
|||
module Extensions
|
||||
module Stdapi
|
||||
module Railgun
|
||||
module Def
|
||||
|
||||
#
|
||||
# A container holding useful Windows API Constants.
|
||||
#
|
||||
class ApiConstants
|
||||
|
||||
# This will be lazily loaded in self.manager
|
||||
@@manager = nil
|
||||
|
||||
# Mutex to ensure we don't add constants more than once via thread races.
|
||||
@@manager_semaphore = Mutex.new
|
||||
|
||||
#
|
||||
# Provides a frozen constant manager for the constants defined in
|
||||
# self.add_constants
|
||||
#
|
||||
def self.manager
|
||||
|
||||
# The first check for nil is to potentially skip the need to synchronize
|
||||
if @@manager.nil?
|
||||
# Looks like we MAY need to load manager
|
||||
@@manager_semaphore.synchronize do
|
||||
# We check once more. Now our options are synchronized
|
||||
if @@manager.nil?
|
||||
@@manager = WinConstManager.new
|
||||
|
||||
self.add_constants(@@manager)
|
||||
|
||||
@@manager.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return @@manager
|
||||
end
|
||||
class DefApiConstants_windows < ApiConstants
|
||||
|
||||
#
|
||||
# Slurp in a giant list of known constants.
|
||||
|
@ -2356,31 +2326,31 @@ class ApiConstants
|
|||
win_const_mgr.add_const('RTM_VIEW_MASK_UCAST',0x00000001)
|
||||
win_const_mgr.add_const('CERT_ALT_NAME_VALUE_ERR_INDEX_MASK',0x0000FFFF)
|
||||
win_const_mgr.add_const('ERROR_NO_SUCH_GROUP',0x00000527)
|
||||
|
||||
|
||||
# Generic Access Rights
|
||||
win_const_mgr.add_const('GENERIC_ALL',0x10000000)
|
||||
win_const_mgr.add_const('GENERIC_EXECUTE',0x20000000)
|
||||
win_const_mgr.add_const('GENERIC_WRITE',0x40000000)
|
||||
win_const_mgr.add_const('GENERIC_READ',0x80000000)
|
||||
|
||||
|
||||
|
||||
|
||||
# Standard Access Rights
|
||||
win_const_mgr.add_const('DELETE',0x00010000)
|
||||
win_const_mgr.add_const('READ_CONTROL',0x00020000)
|
||||
win_const_mgr.add_const('WRITE_DAC',0x00040000)
|
||||
win_const_mgr.add_const('WRITE_OWNER',0x00080000)
|
||||
win_const_mgr.add_const('ACCESS_SYSTEM_SECURITY',0x01000000)
|
||||
|
||||
|
||||
# Services
|
||||
win_const_mgr.add_const('SERVICE_NO_CHANGE',0xFFFFFFFF)
|
||||
|
||||
|
||||
# Service Start Types
|
||||
win_const_mgr.add_const('START_TYPE_BOOT',0x00000000)
|
||||
win_const_mgr.add_const('START_TYPE_SYSTEM',0x00000001)
|
||||
win_const_mgr.add_const('START_TYPE_AUTO',0x00000002)
|
||||
win_const_mgr.add_const('START_TYPE_MANUAL',0x00000003)
|
||||
win_const_mgr.add_const('START_TYPE_DISABLED',0x00000004)
|
||||
|
||||
|
||||
# Service States
|
||||
win_const_mgr.add_const('SERVICE_STOPPED',0x00000001)
|
||||
win_const_mgr.add_const('SERVICE_START_PENDING',0x00000002)
|
||||
|
@ -2389,7 +2359,7 @@ class ApiConstants
|
|||
win_const_mgr.add_const('SERVICE_CONTINUE_PENDING',0x00000005)
|
||||
win_const_mgr.add_const('SERVICE_PAUSE_PENDING',0x00000006)
|
||||
win_const_mgr.add_const('SERVICE_PAUSED',0x00000007)
|
||||
|
||||
|
||||
# Service Types
|
||||
win_const_mgr.add_const('SERVICE_KERNEL_DRIVER',0x00000001)
|
||||
win_const_mgr.add_const('SERVICE_FILE_SYSTEM_DRIVER',0x00000002)
|
||||
|
@ -2397,7 +2367,7 @@ class ApiConstants
|
|||
win_const_mgr.add_const('SERVICE_RECOGNIZER_DRIVER',0x00000008)
|
||||
win_const_mgr.add_const('SERVICE_WIN32_OWN_PROCESS',0x00000010)
|
||||
win_const_mgr.add_const('SERVICE_WIN32_SHARE_PROCESS',0x00000020)
|
||||
|
||||
|
||||
# Service Manager Permissions
|
||||
win_const_mgr.add_const('SC_MANAGER_CONNECT',0x00000001)
|
||||
win_const_mgr.add_const('SC_MANAGER_CREATE_SERVICE',0x00000002)
|
||||
|
@ -2407,7 +2377,7 @@ class ApiConstants
|
|||
win_const_mgr.add_const('SC_MANAGER_MODIFY_BOOT_CONFIG',0x00000020)
|
||||
win_const_mgr.add_const('SC_MANAGER_USER_DEFINED_CONTROL',0x00000100)
|
||||
win_const_mgr.add_const('SC_MANAGER_ALL_ACCESS',0x000F003F)
|
||||
|
||||
|
||||
# Service Permissions
|
||||
win_const_mgr.add_const('SERVICE_QUERY_CONFIG',0x00000001)
|
||||
win_const_mgr.add_const('SERVICE_CHANGE_CONFIG',0x00000002)
|
||||
|
@ -2419,7 +2389,7 @@ class ApiConstants
|
|||
win_const_mgr.add_const('SERVICE_INTERROGATE',0x00000080)
|
||||
win_const_mgr.add_const('SERVICE_USER_DEFINED_CONTROL',0x00000100)
|
||||
win_const_mgr.add_const('SERVICE_ALL_ACCESS',0x000F01FF)
|
||||
|
||||
|
||||
win_const_mgr.add_const('LINEINITIALIZEEXOPTION_USECOMPLETIONPORT',0x00000003)
|
||||
win_const_mgr.add_const('AVIIF_TWOCC',0x00000002)
|
||||
win_const_mgr.add_const('TBTS_LEFT',0x00000001)
|
||||
|
@ -38170,4 +38140,4 @@ class ApiConstants
|
|||
|
||||
end
|
||||
|
||||
end; end; end; end; end; end
|
||||
end; end; end; end; end; end; end
|
|
@ -24,8 +24,8 @@ class Def_advapi32
|
|||
[:UserName, :LPTSTR]
|
||||
]
|
||||
|
||||
def self.create_dll(dll_path = 'advapi32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'advapi32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('QueryServiceStatus', 'DWORD', [
|
||||
['LPVOID', 'hService', 'in'],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_crypt32
|
||||
|
||||
def self.create_dll(dll_path = 'crypt32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'crypt32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('CryptUnprotectData', 'BOOL', [
|
||||
['PBLOB','pDataIn', 'in'],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_iphlpapi
|
||||
|
||||
def self.create_dll(dll_path = 'iphlpapi')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'iphlpapi')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('CancelIPChangeNotify', 'BOOL',[
|
||||
["PBLOB","notifyOverlapped","in"],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_kernel32
|
||||
|
||||
def self.create_dll(dll_path = 'kernel32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'kernel32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function( 'GetConsoleWindow', 'LPVOID',[])
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_netapi32
|
||||
|
||||
def self.create_dll(dll_path = 'netapi32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'netapi32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('NetApiBufferFree','DWORD',[
|
||||
["LPVOID","Buffer","in"]
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_ntdll
|
||||
|
||||
def self.create_dll(dll_path = 'ntdll')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'ntdll')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('NtAllocateVirtualMemory', 'DWORD',[
|
||||
["DWORD","ProcessHandle","in"],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_psapi
|
||||
|
||||
def self.create_dll(dll_path = 'psapi')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'psapi')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('EnumDeviceDrivers', 'BOOL',[
|
||||
%w(PBLOB lpImageBase out),
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_shell32
|
||||
|
||||
def self.create_dll(dll_path = 'shell32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'shell32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('IsUserAnAdmin', 'BOOL', [
|
||||
])
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_user32
|
||||
|
||||
def self.create_dll(dll_path = 'user32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'user32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('ActivateKeyboardLayout', 'DWORD',[
|
||||
["DWORD","hkl","in"],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_version
|
||||
|
||||
def self.create_dll(dll_path = 'version')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'version')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('GetFileVersionInfoA', 'BOOL',[
|
||||
["PCHAR","lptstrFilename","in"],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_wlanapi
|
||||
|
||||
def self.create_dll(dll_path = 'wlanapi')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'wlanapi')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
|
||||
dll.add_function( 'WlanOpenHandle', 'DWORD',[
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_wldap32
|
||||
|
||||
def self.create_dll(dll_path = 'wldap32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'wldap32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('ldap_sslinitA', 'DWORD',[
|
||||
['PCHAR', 'HostName', 'in'],
|
||||
|
|
|
@ -9,8 +9,8 @@ module Def
|
|||
|
||||
class Def_ws2_32
|
||||
|
||||
def self.create_dll(dll_path = 'ws2_32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
def self.create_dll(constant_manager, dll_path = 'ws2_32')
|
||||
dll = DLL.new(dll_path, constant_manager)
|
||||
|
||||
dll.add_function('getaddrinfo', 'DWORD',[
|
||||
["PCHAR","pNodeName","in"],
|
||||
|
|
|
@ -46,11 +46,11 @@ class DLL
|
|||
attr_accessor :functions
|
||||
attr_reader :dll_path
|
||||
|
||||
def initialize(dll_path, win_consts)
|
||||
def initialize(dll_path, consts_mgr)
|
||||
@dll_path = dll_path
|
||||
|
||||
# needed by DLLHelper
|
||||
@win_consts = win_consts
|
||||
@consts_mgr = consts_mgr
|
||||
|
||||
self.functions = {}
|
||||
end
|
||||
|
|
|
@ -38,7 +38,7 @@ module DLLHelper
|
|||
|
||||
# converts ruby string to zero-terminated ASCII string
|
||||
def str_to_ascii_z(str)
|
||||
return str+"\x00"
|
||||
return str + "\x00"
|
||||
end
|
||||
|
||||
# converts 0-terminated ASCII string to ruby string
|
||||
|
@ -72,14 +72,14 @@ module DLLHelper
|
|||
# "SOME_CONSTANT | OTHER_CONSTANT" => 17
|
||||
# "tuna" => !!!!!!!!!!Exception
|
||||
#
|
||||
# Parameter "win_consts" is a WinConstantManager
|
||||
def param_to_number(v, win_consts = @win_consts)
|
||||
# Parameter "consts_mgr" is a ConstantManager
|
||||
def param_to_number(v, consts_mgr = @consts_mgr)
|
||||
if v.class == NilClass then
|
||||
return 0
|
||||
elsif v.kind_of? Integer then
|
||||
return v # ok, it's already a number
|
||||
elsif v.kind_of? String then
|
||||
dw = win_consts.parse(v) # might raise an exception
|
||||
dw = consts_mgr.parse(v) # might raise an exception
|
||||
if dw != nil
|
||||
return dw
|
||||
else
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
require 'pp'
|
||||
require 'enumerator'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_helper'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/buffer_item'
|
||||
|
@ -42,12 +41,12 @@ class MultiCaller
|
|||
|
||||
include DLLHelper
|
||||
|
||||
def initialize( client, parent, win_consts )
|
||||
def initialize(client, parent, consts_mgr)
|
||||
@parent = parent
|
||||
@client = client
|
||||
|
||||
# needed by DLL helper
|
||||
@win_consts = win_consts
|
||||
@consts_mgr = consts_mgr
|
||||
|
||||
if @client.native_arch == ARCH_X64
|
||||
@native = 'Q<'
|
||||
|
|
|
@ -31,13 +31,16 @@
|
|||
# chao - June 2011 - major overhaul of dll lazy loading, caching, and bit of everything
|
||||
#
|
||||
|
||||
#
|
||||
# zeroSteiner - April 2017 - added support for non-windows platforms
|
||||
#
|
||||
|
||||
require 'pp'
|
||||
require 'enumerator'
|
||||
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/util'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/const_manager'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/multicall'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper'
|
||||
|
@ -59,7 +62,7 @@ class Railgun
|
|||
# Railgun::DLL's that have builtin definitions.
|
||||
#
|
||||
# If you want to add additional DLL definitions to be preloaded create a
|
||||
# definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/'.
|
||||
# definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/$platform/'.
|
||||
# Naming is important and should follow convention. For example, if your
|
||||
# dll's name was "my_dll"
|
||||
# file name: def_my_dll.rb
|
||||
|
@ -129,12 +132,24 @@ class Railgun
|
|||
end
|
||||
|
||||
#
|
||||
# Return this Railgun's WinConstManager instance, initially populated with
|
||||
# Return this Railgun's platform specific ApiConstants class.
|
||||
#
|
||||
def api_constants
|
||||
if @api_constants.nil?
|
||||
require "rex/post/meterpreter/extensions/stdapi/railgun/def/#{client.platform}/api_constants"
|
||||
@api_constants = Def.const_get('DefApiConstants_' << client.platform)
|
||||
end
|
||||
|
||||
return @api_constants
|
||||
end
|
||||
|
||||
#
|
||||
# Return this Railgun's ConstManager instance, initially populated with
|
||||
# constants defined in ApiConstants.
|
||||
#
|
||||
def constant_manager
|
||||
# Loads lazily
|
||||
return ApiConstants.manager
|
||||
return api_constants.manager
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -162,22 +177,18 @@ class Railgun
|
|||
# Write data to a memory address on the host (useful for working with
|
||||
# LPVOID parameters)
|
||||
#
|
||||
def memwrite(address, data, length)
|
||||
def memwrite(address, data, length=nil)
|
||||
|
||||
length = data.length if length.nil?
|
||||
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
|
||||
return response.result == 0
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -252,7 +263,7 @@ class Railgun
|
|||
end
|
||||
|
||||
require "rex/post/meterpreter/extensions/stdapi/railgun/def/#{client.platform}/def_#{dll_name}"
|
||||
dll = Def.const_get('Def_' << dll_name).create_dll.freeze
|
||||
dll = Def.const_get('Def_' << dll_name).create_dll(constant_manager).freeze
|
||||
|
||||
@@cached_dlls[dll_name] = dll
|
||||
dlls[dll_name] = dll
|
||||
|
@ -284,7 +295,7 @@ class Railgun
|
|||
end
|
||||
|
||||
#
|
||||
# Return a Windows constant matching +str+.
|
||||
# Return a constant matching +str+.
|
||||
#
|
||||
def const(str)
|
||||
return constant_manager.parse(str)
|
||||
|
@ -295,7 +306,7 @@ class Railgun
|
|||
#
|
||||
def multi(functions)
|
||||
if @multicaller.nil?
|
||||
@multicaller = MultiCaller.new(client, self, ApiConstants.manager)
|
||||
@multicaller = MultiCaller.new(client, self, constant_manager)
|
||||
end
|
||||
|
||||
return @multicaller.call(functions)
|
||||
|
|
Loading…
Reference in New Issue