Class: TurboRex::Windows::ALPC::Server

Inherits:
Object
  • Object
show all
Includes:
TurboRex::Windows::ALPC
Defined in:
lib/turborex/windows/alpc.rb

Defined Under Namespace

Classes: ClientStub

Constant Summary

Constants included from TurboRex::Windows::ALPC

ALPC_MESSAGE_CONTEXT_ATTRIBUTE, ALPC_MESSAGE_DIRECT_ATTRIBUTE, ALPC_MESSAGE_HANDLE_ATTRIBUTE, ALPC_MESSAGE_SECURITY_ATTRIBUTE, ALPC_MESSAGE_TOKEN_ATTRIBUTE, ALPC_MESSAGE_VIEW_ATTRIBUTE, ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE, ALPC_MSGFLG_LPC_MODE, ALPC_MSGFLG_RELEASE_MESSAGE, ALPC_MSGFLG_REPLY_MESSAGE, ALPC_MSGFLG_SYNC_REQUEST, ALPC_MSGFLG_WAIT_ALERTABLE, ALPC_MSGFLG_WAIT_USER_MODE, ALPC_MSGFLG_WOW64_CALL, ALPC_PORFLG_ALLOW_LPC_REQUESTS, PORMSG_PAD

Constants included from Constants

Constants::ACCESS_ALLOWED_ACE_TYPE, Constants::ACCESS_ALLOWED_CALLBACK_ACE_TYPE, Constants::ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE, Constants::ACCESS_ALLOWED_COMPOUND_ACE_TYPE, Constants::ACCESS_ALLOWED_OBJECT_ACE_TYPE, Constants::ACCESS_DENIED_ACE_TYPE, Constants::ACCESS_DENIED_CALLBACK_ACE_TYPE, Constants::ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE, Constants::ACCESS_DENIED_OBJECT_ACE_TYPE, Constants::ACCESS_MAX_MS_ACE_TYPE, Constants::ACCESS_MAX_MS_OBJECT_ACE_TYPE, Constants::ACCESS_MAX_MS_V2_ACE_TYPE, Constants::ACCESS_MAX_MS_V3_ACE_TYPE, Constants::ACCESS_MAX_MS_V4_ACE_TYPE, Constants::ACCESS_MAX_MS_V5_ACE_TYPE, Constants::ACCESS_MIN_MS_ACE_TYPE, Constants::ACCESS_MIN_MS_OBJECT_ACE_TYPE, Constants::CONTAINER_INHERIT_ACE, Constants::CRITICAL_ACE_FLAG, Constants::FAILED_ACCESS_ACE_FLAG, Constants::INHERITED_ACE, Constants::INHERIT_ONLY_ACE, Constants::MAX_BUCKETS_NUM, Constants::NO_PROPAGATE_INHERIT_ACE, Constants::OBJECT_INHERIT_ACE, Constants::SE_DACL_AUTO_INHERITED, Constants::SE_DACL_AUTO_INHERIT_REQ, Constants::SE_DACL_DEFAULTED, Constants::SE_DACL_PRESENT, Constants::SE_DACL_PROTECTED, Constants::SE_GROUP_DEFAULTED, Constants::SE_OWNER_DEFAULTED, Constants::SE_RM_CONTROL_VALID, Constants::SE_SACL_AUTO_INHERITED, Constants::SE_SACL_AUTO_INHERIT_REQ, Constants::SE_SACL_DEFAULTED, Constants::SE_SACL_PRESENT, Constants::SE_SACL_PROTECTED, Constants::SE_SELF_RELATIVE, Constants::SUCCESSFUL_ACCESS_ACE_FLAG, Constants::SYSTEM_ACCESS_FILTER_ACE_TYPE, Constants::SYSTEM_ALARM_ACE_TYPE, Constants::SYSTEM_ALARM_CALLBACK_ACE_TYPE, Constants::SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE, Constants::SYSTEM_ALARM_OBJECT_ACE_TYPE, Constants::SYSTEM_AUDIT_ACE_TYPE, Constants::SYSTEM_AUDIT_CALLBACK_ACE_TYPE, Constants::SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE, Constants::SYSTEM_AUDIT_OBJECT_ACE_TYPE, Constants::SYSTEM_MANDATORY_LABEL_ACE_TYPE, Constants::SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE, Constants::SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE, Constants::SYSTEM_SCOPED_POLICY_ID_ACE_TYPE, Constants::SecurityAnonymous, Constants::SecurityDelegation, Constants::SecurityIdentification, Constants::SecurityImpersonation, Constants::TRUST_PROTECTED_FILTER_ACE_FLAG, Constants::VALID_INHERIT_FLAGS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from TurboRex::Windows::ALPC

const_missing

Constructor Details

#initialize(port_name, opts = {}) ⇒ Server

Returns a new instance of Server.



731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
# 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

Instance Attribute Details

#obj_attrObject (readonly)

Returns the value of attribute obj_attr.



687
688
689
# File 'lib/turborex/windows/alpc.rb', line 687

def obj_attr
  @obj_attr
end

#port_nameObject (readonly)

Returns the value of attribute port_name.



686
687
688
# File 'lib/turborex/windows/alpc.rb', line 686

def port_name
  @port_name
end

Instance Method Details

#accept(conn_message, &block) ⇒ Object



795
796
797
798
799
800
801
802
803
804
805
806
807
# 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 = {}, &block) ⇒ Object



769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
# 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