class TurboRex::Windows::ALPC::Server

Constants

DupObjectTypes
Flags
Length
MaxMessageLength
MaxPoolUsage
MaxSectionSize
MaxTotalSectionSize
MaxViewSize
MemoryBandwidth
ObjectName

Attributes

obj_attr[R]
port_name[R]

Public Class Methods

new(port_name, opts = {}) click to toggle source
# File lib/turborex/windows/alpc.rb, line 731
def initialize(port_name, opts = {})
  if TurboRex::Windows::Utils.is_wow64?
    default_cpu = Metasm::Ia32
  else
    default_cpu = Metasm::X86_64
  end

  cpu = opts[:cpu] || default_cpu
  APIProxy.init(cpu)

  @communication_port_handles = []
  @clients = []

  unless port_name.start_with? '\\'
    port_name = '\\' + port_name
  end
  @port_name = port_name

  if wport_name = TurboRex::Windows::Utils.multibyte_to_widechar(port_name)
    dest_str = APIProxy.alloc_c_struct('UNICODE_STRING')
    APIProxy.rtlinitunicodestring(dest_str, wport_name)

    handle = APIProxy.alloc_c_type('HANDLE')
    alpc_port_attr, obj_attr = make_attr(obj_name: dest_str)
    ntstatus = APIProxy.ntalpccreateport(handle, obj_attr, alpc_port_attr)

    unless TinySDK.nt_success? ntstatus
      formatted = TurboRex::Windows::TinySDK.format_hex_ntstatus ntstatus, hex_str: true
      raise "Unable to create alpc port: #{formatted}"
    end

    @conn_port_handle = handle[0]
    @transport = Transport.new
  else
    raise "Unable to convert characters to utf-16le encoding."
  end
end

Public Instance Methods

accept(conn_message) { |client_stub| ... } click to toggle source
# File lib/turborex/windows/alpc.rb, line 795
def accept(conn_message, &block)
  handle, ntstatus = @transport.accept(port_message: conn_message)
  if TinySDK.nt_success?(ntstatus)
    @communication_port_handles << handle
    client_stub = ClientStub.new(handle, @conn_port_handle, @transport, conn_message)
    @clients << client_stub
    yield(client_stub) if block_given?
    client_stub
  else
    puts "[-] Unable to accept connection. (0x#{ntstatus.to_s(16).upcase})"
    raise TurboRex::Exception::ALPC::UnableToAcceptConnection
  end
end
run(opts = {}) { |client| ... } click to toggle source
# File lib/turborex/windows/alpc.rb, line 769
def run(opts = {}, &block)
  loop do
    conn_message = @transport.listen(@conn_port_handle)
    puts "[*] Receiving connection request"

    if opts[:conn_req_cb]
      unless (permit_conn = opts[:conn_req_cb].call(:connection_req, conn_message, self))
        ######################################################################################################################
        ## Requires following params(UniqueProcess, UniqueThread, MessageId), otherwise raise STATUS_REPLY_MESSAGE_MISMATCH ##
        ## uniq_process = conn_message.client_id.unique_process                                                             ##
        ## uniq_thread = conn_message.client_id.unique_thread                                                               ##
        ## message_id = conn_message.message_id                                                                             ##
        ##                                                                                                                  ##
        ## Or we can pass a instance of PortMessage with the 'port_message' key                                            ##
        ######################################################################################################################
        @transport.refuse_connect(port_message: conn_message) and next
      end
    end

    client = accept(conn_message)
    if block_given?
      yield(client)
    end
  end
end

Private Instance Methods

make_attr(opts = {}) click to toggle source

def impersonate_client(client)

client.impersonate

end

# File lib/turborex/windows/alpc.rb, line 815
def make_attr(opts = {})
  unless @alpc_port_attr
    alpc_port_attr = APIProxy.alloc_c_struct('ALPC_PORT_ATTRIBUTES')
    alpc_port_attr.Flags = ALPC::ALPC_PORFLG_ALLOW_LPC_REQUESTS
    alpc_port_attr.MaxMessageLength = 0x1000
    alpc_port_attr.MemoryBandwidth = 0
    alpc_port_attr.MaxPoolUsage = 0xFFFFFFFF
    alpc_port_attr.MaxSectionSize = 0xFFFFFFFF
    alpc_port_attr.MaxViewSize = 0xFFFFFFFF
    alpc_port_attr.MaxTotalSectionSize = 0xFFFFFFFF
    alpc_port_attr.DupObjectTypes = 0xFFFFFFFF
  end

  unless @obj_attr
    obj_attr = APIProxy.alloc_c_struct('OBJECT_ATTRIBUTES')
    obj_attr.Length = obj_attr.sizeof
    obj_attr.ObjectName = opts[:obj_name]
    @obj_attr = obj_attr
  end

  [alpc_port_attr, obj_attr]
end
np() click to toggle source
# File lib/turborex/windows/alpc.rb, line 838
def np
  APIProxy.np
end